@codexhost/cli-linux-arm64 0.13.2 → 0.14.0

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.
Files changed (33) hide show
  1. package/README.md +1 -1
  2. package/app/codexhost-distribution.json +1 -1
  3. package/app/console-server.mjs +94 -8
  4. package/app/console-web.js +537 -146
  5. package/app/desktop-controller.mjs +108 -12
  6. package/app/host-runtime.mjs +847 -235
  7. package/app/plugins/antigravity/plugin.mjs +143 -20
  8. package/app/plugins/claude-code/plugin.mjs +601 -71
  9. package/app/plugins/codebuddy/plugin.mjs +227 -30
  10. package/app/plugins/codex-usage/plugin.mjs +212 -77
  11. package/app/plugins/copilot/assets/icon.png +0 -0
  12. package/app/plugins/copilot/manifest.json +26 -0
  13. package/app/plugins/copilot/plugin.mjs +34546 -0
  14. package/app/plugins/cursor-cli/plugin.mjs +20805 -44862
  15. package/app/plugins/deepseek-harness/manifest.json +2 -2
  16. package/app/plugins/deepseek-harness/plugin.mjs +202 -21
  17. package/app/plugins/enabled.json +1 -0
  18. package/app/plugins/grok/plugin.mjs +278 -29
  19. package/app/plugins/hermes/plugin.mjs +143 -12
  20. package/app/plugins/kimi-code/plugin.mjs +140 -16
  21. package/app/plugins/kiro-cli/plugin.mjs +121 -10
  22. package/app/plugins/omp/plugin.mjs +2200 -2002
  23. package/app/plugins/opencode/plugin.mjs +137 -16
  24. package/app/plugins/pi/plugin.mjs +2563 -2282
  25. package/app/plugins/qoder/plugin.mjs +133 -14
  26. package/app/plugins/qoder-cn/plugin.mjs +133 -14
  27. package/app/plugins/workbuddy/plugin.mjs +603 -56
  28. package/app/plugins/zcode/plugin.mjs +133 -14
  29. package/app/renderer-extension.js +1171 -529
  30. package/bin/codexhost +0 -0
  31. package/libexec/codexhost-shim +0 -0
  32. package/libexec/codexhost-updater +0 -0
  33. package/package.json +1 -1
@@ -14673,6 +14673,48 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14673
14673
  initializeOnly: external_exports.boolean().optional()
14674
14674
  });
14675
14675
 
14676
+ // ../shared-contracts/dist/harness-presentation.js
14677
+ var localeSchema = external_exports.string().max(64).regex(/^[a-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/u);
14678
+ var displayText = (maximum) => external_exports.string().min(1).max(maximum).refine((text) => text.trim().length > 0);
14679
+ var harnessLocalizationsSchema = external_exports.record(localeSchema, external_exports.object({
14680
+ label: displayText(256).optional(),
14681
+ description: displayText(1024).optional()
14682
+ }).strict()).refine((entries) => Object.keys(entries).length <= 16, "Too many locales");
14683
+ var harnessLocalizedTextSchema = external_exports.record(localeSchema, displayText(4096)).refine((entries) => typeof entries.en === "string", "English fallback is required").refine((entries) => Object.keys(entries).length <= 16, "Too many locales");
14684
+ function translation(entries, locale) {
14685
+ if (!entries)
14686
+ return void 0;
14687
+ const language = locale.split("-")[0] ?? locale;
14688
+ for (const candidate of [locale, language]) {
14689
+ if (Object.hasOwn(entries, candidate))
14690
+ return entries[candidate];
14691
+ }
14692
+ return void 0;
14693
+ }
14694
+ function localizeHarnessPresentation(value, locale) {
14695
+ const localized = translation(value.localizations, locale);
14696
+ const language = translation(value.localizations, locale.split("-")[0] ?? locale);
14697
+ return {
14698
+ label: localized?.label ?? language?.label ?? value.label,
14699
+ description: localized?.description ?? language?.description ?? value.description
14700
+ };
14701
+ }
14702
+ function localizeHarnessText(value, locale) {
14703
+ return translation(value, locale) ?? value.en ?? "";
14704
+ }
14705
+
14706
+ // ../shared-contracts/dist/account-credits-presentation.js
14707
+ function accountCreditsWindowLabel(window2, locale, periodLabel) {
14708
+ if (window2.periodType && window2.periodType !== "unknown" && (window2.scope || !window2.label)) {
14709
+ const period = periodLabel(window2.periodType);
14710
+ return window2.scope ? `${localizeHarnessPresentation(window2.scope, locale).label} \xB7 ${period}` : period;
14711
+ }
14712
+ return localizeHarnessPresentation({
14713
+ label: window2.label ?? window2.product ?? periodLabel("unknown"),
14714
+ ...window2.localizations ? { localizations: window2.localizations } : {}
14715
+ }, locale).label;
14716
+ }
14717
+
14676
14718
  // ../shared-contracts/dist/model-price-overrides.js
14677
14719
  var MODEL_PRICE_OVERRIDES_GET_METHOD = "codexhost/usage/model-prices/get";
14678
14720
  var MODEL_PRICE_OVERRIDES_SET_METHOD = "codexhost/usage/model-prices/set";
@@ -14726,10 +14768,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14726
14768
  var project = external_exports.string().min(1).max(4096);
14727
14769
  var usageStatisticsParamsSchema = external_exports.strictObject({
14728
14770
  range: external_exports.enum(USAGE_STATISTICS_RANGES),
14771
+ /** Display timezone for ranges, dates and hourly buckets; omitted means the Host's local zone. */
14772
+ timeZone: external_exports.string().min(1).max(128).refine((value) => {
14773
+ try {
14774
+ new Intl.DateTimeFormat("en", { timeZone: value });
14775
+ return true;
14776
+ } catch {
14777
+ return false;
14778
+ }
14779
+ }, "Unsupported usage statistics timezone").optional(),
14729
14780
  harness: harness.optional(),
14730
14781
  model: model.nullable().optional(),
14731
14782
  project: project.nullable().optional(),
14732
- /** One local date inside the range. */
14783
+ /** One date in the query timezone inside the range. */
14733
14784
  date: localDate.optional()
14734
14785
  });
14735
14786
  var usageStatisticsTotalsSchema = external_exports.strictObject({
@@ -14765,7 +14816,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14765
14816
  });
14766
14817
  var usageStatisticsResultSchema = external_exports.strictObject({
14767
14818
  range: external_exports.enum(USAGE_STATISTICS_RANGES),
14768
- /** First local date of the range; null for all time. */
14819
+ /** First date in the query timezone (Host local when omitted); null for all time. */
14769
14820
  from: localDate.nullable(),
14770
14821
  to: localDate,
14771
14822
  /** The filters these figures apply, echoed so a late answer to older filters is recognised. */
@@ -14805,7 +14856,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14805
14856
  totals: usageStatisticsTotalsSchema,
14806
14857
  /** Each date and Harness of the range: every filter except the day. */
14807
14858
  daily: external_exports.array(external_exports.strictObject({ date: localDate, harness, ...totals })).max(2e5),
14808
- /** Local weekday (0 = Sunday) and hour, all filters applied. */
14859
+ /** Weekday (0 = Sunday) and hour in the query timezone, all filters applied. */
14809
14860
  hourly: external_exports.array(external_exports.strictObject({
14810
14861
  weekday: external_exports.number().int().min(0).max(6),
14811
14862
  hour: external_exports.number().int().min(0).max(23),
@@ -14866,6 +14917,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14866
14917
  "codexhost/harness/display-settings/set",
14867
14918
  "codexhost/harness/inspect",
14868
14919
  "codexhost/harness/installation",
14920
+ "codexhost/harness/installation/start",
14921
+ "codexhost/harness/installation/status",
14869
14922
  "codexhost/harness/launch-settings/get",
14870
14923
  "codexhost/harness/launch-settings/set",
14871
14924
  "codexhost/harness/web-ui/open",
@@ -14943,7 +14996,18 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14943
14996
  var nonNegativeSafeIntegerSchema = external_exports.number().int().safe().nonnegative();
14944
14997
  var finiteNonNegativeNumberSchema = external_exports.number().finite().nonnegative();
14945
14998
  var cacheHitRatePercentSchema = external_exports.number().finite().min(0).max(100);
14999
+ var indicatorTextSchema = (maximum) => harnessLocalizedTextSchema.refine((entries) => Object.values(entries).every((text) => text.length <= maximum));
15000
+ var composerIndicatorsSchema = external_exports.array(external_exports.object({
15001
+ kind: external_exports.literal("countdown"),
15002
+ id: external_exports.string().min(1).max(64),
15003
+ expiresAtUnix: nonNegativeSafeIntegerSchema,
15004
+ label: indicatorTextSchema(256).optional(),
15005
+ tooltip: indicatorTextSchema(1024).optional()
15006
+ }).strict()).max(2).refine((entries) => new Set(entries.map(({ id }) => id)).size === entries.length, {
15007
+ message: "Composer indicator IDs must be unique"
15008
+ });
14946
15009
  var threadUsageSnapshotSchema = external_exports.object({
15010
+ composerIndicators: composerIndicatorsSchema.optional(),
14947
15011
  inputTokens: nonNegativeSafeIntegerSchema.optional(),
14948
15012
  cachedInputTokens: nonNegativeSafeIntegerSchema.optional(),
14949
15013
  cacheWriteInputTokens: nonNegativeSafeIntegerSchema.optional(),
@@ -15016,8 +15080,24 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15016
15080
  }
15017
15081
  });
15018
15082
  var usagePercentSchema = external_exports.number().finite().min(0).max(100);
15083
+ var accountCreditsPeriodSchema = external_exports.enum([
15084
+ "weekly",
15085
+ "monthly",
15086
+ "five_hour",
15087
+ "seven_day",
15088
+ "unknown"
15089
+ ]);
15090
+ var accountCreditsScopeSchema = external_exports.object({
15091
+ id: external_exports.string().min(1).max(256),
15092
+ label: external_exports.string().min(1).max(256),
15093
+ localizations: harnessLocalizationsSchema.optional()
15094
+ }).strict();
15019
15095
  var accountCreditsProductUsageSchema = external_exports.object({
15020
15096
  product: external_exports.string().min(1),
15097
+ /** Native period and scope, never inferred from the display name. */
15098
+ periodType: accountCreditsPeriodSchema.optional(),
15099
+ scope: accountCreditsScopeSchema.optional(),
15100
+ localizations: harnessLocalizationsSchema.optional(),
15021
15101
  used: external_exports.number().finite().nonnegative().optional(),
15022
15102
  // Zero is a real empty cap, not an absent field.
15023
15103
  limit: external_exports.number().finite().nonnegative().optional(),
@@ -15037,9 +15117,11 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15037
15117
  unit: external_exports.string().min(1).max(32).optional(),
15038
15118
  /** Native label when the primary limit is scoped to a model or product group. */
15039
15119
  label: external_exports.string().min(1).optional(),
15120
+ scope: accountCreditsScopeSchema.optional(),
15121
+ localizations: harnessLocalizationsSchema.optional(),
15040
15122
  usedPercent: usagePercentSchema,
15041
15123
  resetsAt: external_exports.string().min(1).optional(),
15042
- periodType: external_exports.enum(["weekly", "monthly", "five_hour", "seven_day", "unknown"]),
15124
+ periodType: accountCreditsPeriodSchema,
15043
15125
  productUsage: external_exports.array(accountCreditsProductUsageSchema).min(1).optional(),
15044
15126
  resetCredits: accountResetCreditsSchema.optional()
15045
15127
  }).strict();
@@ -15050,7 +15132,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15050
15132
  var threadUsageInspectionSchema = external_exports.object({
15051
15133
  threadId: hostThreadIdSchema,
15052
15134
  usage: threadUsageSnapshotSchema.nullable(),
15053
- accountCredits: accountCreditsSnapshotSchema.optional()
15135
+ accountCredits: accountCreditsSnapshotSchema.optional(),
15136
+ /** Whether this source can provide cached account quota independently of usage. */
15137
+ accountCreditsSupported: external_exports.boolean().optional()
15054
15138
  }).strict();
15055
15139
 
15056
15140
  // ../shared-contracts/dist/harness-accounts.js
@@ -15177,7 +15261,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15177
15261
  id: harnessPermissionModeIdSchema,
15178
15262
  label: nonBlankTextSchema.max(HARNESS_PERMISSION_MODE_LABEL_MAX_LENGTH),
15179
15263
  description: nonBlankTextSchema.max(HARNESS_PERMISSION_MODE_DESCRIPTION_MAX_LENGTH).optional(),
15180
- dangerous: external_exports.boolean().optional()
15264
+ dangerous: external_exports.boolean().optional(),
15265
+ localizations: harnessLocalizationsSchema.optional()
15181
15266
  }).strict();
15182
15267
  var harnessPermissionModeCatalogSchema = external_exports.object({
15183
15268
  modes: external_exports.array(harnessPermissionModeSchema).min(1).max(HARNESS_PERMISSION_MODE_CATALOG_MAX_LENGTH),
@@ -15330,7 +15415,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15330
15415
  }).strict().optional(),
15331
15416
  autonomousTurns: external_exports.object({
15332
15417
  observe: external_exports.boolean()
15333
- }).strict().optional()
15418
+ }).strict().optional(),
15419
+ /** True only when `turn.steer` delivers input into the active Turn through a native primitive. */
15420
+ steer: external_exports.boolean().optional()
15334
15421
  }).strict();
15335
15422
  var harnessConfigurationStateSchema = external_exports.object({
15336
15423
  effectiveModel: harnessModelRefSchema.optional(),
@@ -15378,7 +15465,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15378
15465
  var harnessInspectParamsSchema = external_exports.object({
15379
15466
  harnessId: harnessIdSchema,
15380
15467
  cwd: nonBlankTextSchema2.max(16384).optional(),
15381
- refresh: external_exports.boolean().optional()
15468
+ refresh: external_exports.boolean().optional(),
15469
+ /** `availability` asks only whether the Harness can run; see `InspectHarnessInput.purpose`. */
15470
+ purpose: external_exports.literal("availability").optional()
15382
15471
  }).strict();
15383
15472
  var harnessWebUiOpenParamsSchema = external_exports.object({
15384
15473
  harnessId: harnessIdSchema
@@ -15461,6 +15550,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15461
15550
  seen.add(thread.threadId);
15462
15551
  }
15463
15552
  });
15553
+ var threadSteeringInspectParamsSchema = external_exports.object({
15554
+ threadId: hostThreadIdSchema,
15555
+ /** The text about to be steered; a Harness command always stops and restarts. */
15556
+ text: external_exports.string().optional()
15557
+ }).strict();
15558
+ var threadSteerDeliverySchema = external_exports.enum(["activeTurn", "newTurn"]);
15559
+ var threadSteeringInspectResultSchema = external_exports.object({
15560
+ delivery: external_exports.enum(["official", "activeTurn", "newTurn"])
15561
+ }).strict();
15464
15562
 
15465
15563
  // ../shared-contracts/dist/harness-plugins.js
15466
15564
  var HARNESS_PLUGIN_MANIFEST_MAX_BYTES = 32 * 1024;
@@ -15555,7 +15653,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15555
15653
  }).strict();
15556
15654
 
15557
15655
  // ../shared-contracts/dist/harness-installation.js
15558
- var HARNESS_INSTALLATION_METHOD = "codexhost/harness/installation";
15656
+ var HARNESS_INSTALLATION_START_METHOD = "codexhost/harness/installation/start";
15657
+ var HARNESS_INSTALLATION_STATUS_METHOD = "codexhost/harness/installation/status";
15559
15658
  var harnessInstallationParamsSchema = external_exports.object({
15560
15659
  harnessId: harnessIdSchema,
15561
15660
  action: external_exports.enum(["check", "update", "install"])
@@ -15565,11 +15664,31 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15565
15664
  latestVersion: external_exports.string().min(1).max(128),
15566
15665
  updateAvailable: external_exports.boolean(),
15567
15666
  canUpdate: external_exports.boolean(),
15667
+ /** Defaults to CLI; some Harnesses ship only inside a desktop application. */
15668
+ versionKind: external_exports.enum(["cli", "application"]).optional(),
15669
+ /** Official download opened by the user; does not imply an automatic installation. */
15670
+ manualUpdateUrl: external_exports.url().max(2048).refine((value) => /^https:\/\/[^/?#@]+(?:[/?#]|$)/iu.test(value), "Manual updates require a credential-free HTTPS URL").optional(),
15568
15671
  // Adapter-owned diagnostic text; UI uses messageCode rather than displaying it verbatim.
15569
15672
  message: external_exports.string().max(2048).optional(),
15570
15673
  messageCode: external_exports.string().min(1).max(128).optional(),
15674
+ /** Safe plugin-owned explanation, distinct from raw diagnostic message. */
15675
+ notice: harnessLocalizedTextSchema.optional(),
15571
15676
  latestVersionKind: external_exports.enum(["unknown", "tracking-branch"]).optional()
15572
15677
  }).strict();
15678
+ var harnessInstallationTaskParamsSchema = external_exports.object({ taskId: external_exports.string().uuid() }).strict();
15679
+ var harnessInstallationTaskSchema = external_exports.discriminatedUnion("status", [
15680
+ external_exports.object({ taskId: external_exports.string().uuid(), status: external_exports.literal("running") }).strict(),
15681
+ external_exports.object({
15682
+ taskId: external_exports.string().uuid(),
15683
+ status: external_exports.literal("succeeded"),
15684
+ result: harnessInstallationStateSchema
15685
+ }).strict(),
15686
+ external_exports.object({
15687
+ taskId: external_exports.string().uuid(),
15688
+ status: external_exports.literal("failed"),
15689
+ error: external_exports.object({ code: external_exports.number().int(), message: external_exports.string().min(1).max(2048) }).strict()
15690
+ }).strict()
15691
+ ]);
15573
15692
 
15574
15693
  // ../shared-contracts/dist/codex-accounts.js
15575
15694
  var accountIdSchema = external_exports.string().min(1).max(256).regex(/^[A-Za-z0-9._~-]+$/u);
@@ -15696,6 +15815,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15696
15815
  invocation: commandInvocationSchema,
15697
15816
  label: commandLabelSchema,
15698
15817
  description: commandDescriptionSchema.optional(),
15818
+ localizations: harnessLocalizationsSchema.optional(),
15699
15819
  argumentMode: external_exports.enum(["none", "text"]),
15700
15820
  /**
15701
15821
  * Native distinction reported by the Harness. Omitted when the Harness does
@@ -16527,10 +16647,10 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
16527
16647
  let previousWasTranslation = false;
16528
16648
  paragraphLines.forEach((line, lineIndex) => {
16529
16649
  if (lineIndex > 0 && !primaryIsCjk && CJK_PATTERN.test(line)) {
16530
- const translation = document2.createElement("span");
16531
- translation.className = "release-note-translation";
16532
- appendInline(document2, translation, line);
16533
- paragraph.append(translation);
16650
+ const translation2 = document2.createElement("span");
16651
+ translation2.className = "release-note-translation";
16652
+ appendInline(document2, translation2, line);
16653
+ paragraph.append(translation2);
16534
16654
  previousWasTranslation = true;
16535
16655
  return;
16536
16656
  }
@@ -18232,6 +18352,8 @@ th[aria-sort] .console-usage-sort__mark {
18232
18352
  harness: "Harness",
18233
18353
  model: "Model",
18234
18354
  project: "Project",
18355
+ host: "Machine",
18356
+ localHost: "This machine",
18235
18357
  filterModel: "Filter by model",
18236
18358
  filterProject: "Filter by project",
18237
18359
  unknownModel: "Unknown model",
@@ -18415,6 +18537,8 @@ th[aria-sort] .console-usage-sort__mark {
18415
18537
  harness: "Harness",
18416
18538
  model: "\u6A21\u578B",
18417
18539
  project: "\u9879\u76EE",
18540
+ host: "\u673A\u5668",
18541
+ localHost: "\u672C\u673A",
18418
18542
  filterModel: "\u6309\u6A21\u578B\u7B5B\u9009",
18419
18543
  filterProject: "\u6309\u9879\u76EE\u7B5B\u9009",
18420
18544
  unknownModel: "\u672A\u77E5\u6A21\u578B",
@@ -19179,6 +19303,26 @@ th[aria-sort] .console-usage-sort__mark {
19179
19303
  };
19180
19304
  }
19181
19305
 
19306
+ // src/renderer-installation-client.ts
19307
+ async function runRendererInstallation(send, input) {
19308
+ const params = harnessInstallationParamsSchema.parse(input);
19309
+ const options = { priority: "background", timeoutMs: 15e3 };
19310
+ let task = harnessInstallationTaskSchema.parse(
19311
+ await send(HARNESS_INSTALLATION_START_METHOD, params, options)
19312
+ );
19313
+ const taskId = task.taskId;
19314
+ while (task.status === "running") {
19315
+ await new Promise((resolve) => globalThis.setTimeout(resolve, 500));
19316
+ task = harnessInstallationTaskSchema.parse(
19317
+ await send(HARNESS_INSTALLATION_STATUS_METHOD, { taskId }, options)
19318
+ );
19319
+ if (task.taskId !== taskId) throw new Error("Harness installation task identity changed");
19320
+ }
19321
+ if (task.status === "failed")
19322
+ throw Object.assign(new Error(task.error.message), { code: task.error.code });
19323
+ return task.result;
19324
+ }
19325
+
19182
19326
  // src/renderer-request-sender.ts
19183
19327
  var RendererMethodUnavailableError = class extends Error {
19184
19328
  constructor(method, cause) {
@@ -19327,7 +19471,15 @@ th[aria-sort] .console-usage-sort__mark {
19327
19471
  };
19328
19472
  const inspectHarness = async (input, options) => {
19329
19473
  const params = harnessInspectParamsSchema.parse(input);
19330
- const result = await manager.sendRequest(HARNESS_INSPECT_METHOD, params, options);
19474
+ let result;
19475
+ try {
19476
+ result = await manager.sendRequest(HARNESS_INSPECT_METHOD, params, options);
19477
+ } catch (error51) {
19478
+ if (!params.purpose || !isInvalidParams(error51)) throw error51;
19479
+ const full = { ...params };
19480
+ delete full.purpose;
19481
+ result = await manager.sendRequest(HARNESS_INSPECT_METHOD, full, options);
19482
+ }
19331
19483
  return harnessInspectionSchema.parse(result);
19332
19484
  };
19333
19485
  const inspectHarnessCommands = async (input) => {
@@ -19367,13 +19519,7 @@ th[aria-sort] .console-usage-sort__mark {
19367
19519
  };
19368
19520
  return Object.freeze({
19369
19521
  async installation(input) {
19370
- return harnessInstallationStateSchema.parse(
19371
- await manager.sendRequest(
19372
- HARNESS_INSTALLATION_METHOD,
19373
- harnessInstallationParamsSchema.parse(input),
19374
- { priority: "interactive" }
19375
- )
19376
- );
19522
+ return runRendererInstallation(manager.sendRequest, input);
19377
19523
  },
19378
19524
  async getHarnessDisplaySettings() {
19379
19525
  return harnessDisplaySettingsSchema.parse(
@@ -19589,6 +19735,9 @@ th[aria-sort] .console-usage-sort__mark {
19589
19735
  }
19590
19736
  });
19591
19737
  }
19738
+ function isInvalidParams(error51) {
19739
+ return typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === -32602;
19740
+ }
19592
19741
 
19593
19742
  // src/settings/accounts.css
19594
19743
  var accounts_default = `.settings-harness-account__logo {
@@ -20555,37 +20704,19 @@ th[aria-sort] .console-usage-sort__mark {
20555
20704
 
20556
20705
  // src/settings/harness-version-messages.ts
20557
20706
  var harnessVersionEnglish = Object.freeze({
20707
+ locale: "en",
20558
20708
  unknown: "Unknown",
20559
20709
  trackingBranch: "Tracking branch (new commits)",
20560
20710
  notes: Object.freeze({
20561
- "original-installer": "Use the original installer, package manager, or launcher to update this installation.",
20562
- "claude-policy-restricted": "Claude updates are restricted by the installation's settings or policy.",
20563
- "codebuddy-npm-required": "Use CodeBuddy's native updater or original package manager. Latest-version checks here require an identified npm installation.",
20564
- "deepseek-original-installer": "Update with the original installer. Python, desktop, and project-local installations are not upgraded through global npm.",
20565
- "kiro-native-updater": "Use Kiro CLI's original installer or native updater to check for and install updates.",
20566
- "zcode-desktop-updater": "The CLI ships inside ZCode Desktop. Update ZCode Desktop itself to update it.",
20567
- "qoder-check-unavailable": "This Qoder China release does not expose a non-installing update check. Use its original installer.",
20568
- "hermes-update-plan-unavailable": "This Hermes release does not expose a safe update plan. Use the original installer.",
20569
- "hermes-externally-managed": "This Hermes installation is managed externally. Update it through its desktop app, container, or original package manager.",
20570
- "hermes-update-channel": "Uses Hermes's configured update channel. Gateway restarts are deferred; existing processes keep their running code.",
20571
- "hermes-manual-update": "Use the native updater manually. Safe non-interactive updates require a clean source checkout, commit identity, and Gateway restart deferral."
20711
+ "original-installer": "Use the original installer, package manager, or launcher to update this installation."
20572
20712
  })
20573
20713
  });
20574
20714
  var harnessVersionChinese = Object.freeze({
20715
+ locale: "zh-CN",
20575
20716
  unknown: "\u672A\u77E5",
20576
20717
  trackingBranch: "\u8DDF\u8E2A\u5206\u652F\uFF08\u6709\u65B0\u63D0\u4EA4\uFF09",
20577
20718
  notes: Object.freeze({
20578
- "original-installer": "\u8BF7\u4F7F\u7528\u539F\u5B89\u88C5\u7A0B\u5E8F\u3001\u5305\u7BA1\u7406\u5668\u6216\u542F\u52A8\u5668\u66F4\u65B0\u6B64\u5B89\u88C5\u3002",
20579
- "claude-policy-restricted": "\u6B64 Claude \u5B89\u88C5\u7684\u8BBE\u7F6E\u6216\u7B56\u7565\u9650\u5236\u4E86\u66F4\u65B0\u3002",
20580
- "codebuddy-npm-required": "\u8BF7\u4F7F\u7528 CodeBuddy \u539F\u751F\u66F4\u65B0\u5668\u6216\u539F\u5305\u7BA1\u7406\u5668\u66F4\u65B0\u3002\u6B64\u5904\u4EC5\u80FD\u67E5\u8BE2\u5DF2\u8BC6\u522B\u7684 npm \u5B89\u88C5\u7684\u6700\u65B0\u7248\u672C\u3002",
20581
- "deepseek-original-installer": "\u8BF7\u4F7F\u7528\u539F\u5B89\u88C5\u65B9\u5F0F\u66F4\u65B0\u3002Python\u3001\u684C\u9762\u5E94\u7528\u53CA\u9879\u76EE\u5185\u5B89\u88C5\u4E0D\u4F1A\u901A\u8FC7\u5168\u5C40 npm \u66F4\u65B0\u3002",
20582
- "kiro-native-updater": "\u8BF7\u4F7F\u7528 Kiro CLI \u539F\u5B89\u88C5\u7A0B\u5E8F\u6216\u539F\u751F\u66F4\u65B0\u5668\u68C0\u67E5\u5E76\u5B89\u88C5\u66F4\u65B0\u3002",
20583
- "zcode-desktop-updater": "CLI \u968F ZCode Desktop \u4E00\u8D77\u53D1\u5E03\uFF0C\u8BF7\u76F4\u63A5\u66F4\u65B0 ZCode Desktop\u3002",
20584
- "qoder-check-unavailable": "\u6B64 Qoder \u4E2D\u56FD\u7248\u5C1A\u4E0D\u652F\u6301\u53EA\u68C0\u67E5\u3001\u4E0D\u5B89\u88C5\u7684\u66F4\u65B0\u67E5\u8BE2\uFF0C\u8BF7\u4F7F\u7528\u539F\u5B89\u88C5\u65B9\u5F0F\u66F4\u65B0\u3002",
20585
- "hermes-update-plan-unavailable": "\u6B64 Hermes \u7248\u672C\u4E0D\u63D0\u4F9B\u5B89\u5168\u7684\u66F4\u65B0\u8BA1\u5212\uFF0C\u8BF7\u4F7F\u7528\u539F\u5B89\u88C5\u65B9\u5F0F\u66F4\u65B0\u3002",
20586
- "hermes-externally-managed": "\u6B64 Hermes \u5B89\u88C5\u7531\u5916\u90E8\u5DE5\u5177\u7BA1\u7406\uFF0C\u8BF7\u901A\u8FC7\u5176\u684C\u9762\u5E94\u7528\u3001\u5BB9\u5668\u6216\u539F\u5305\u7BA1\u7406\u5668\u66F4\u65B0\u3002",
20587
- "hermes-update-channel": "\u4F7F\u7528 Hermes \u914D\u7F6E\u7684\u66F4\u65B0\u6E20\u9053\uFF0C\u6682\u4E0D\u91CD\u542F Gateway\uFF1B\u73B0\u6709\u8FDB\u7A0B\u7EE7\u7EED\u8FD0\u884C\u539F\u6709\u4EE3\u7801\u3002",
20588
- "hermes-manual-update": "\u8BF7\u624B\u52A8\u4F7F\u7528\u539F\u751F\u66F4\u65B0\u5668\u3002\u5B89\u5168\u7684\u975E\u4EA4\u4E92\u66F4\u65B0\u8981\u6C42\u6E90\u7801\u76EE\u5F55\u65E0\u672A\u63D0\u4EA4\u4FEE\u6539\u3001\u53EF\u8BC6\u522B\u5F53\u524D\u63D0\u4EA4\uFF0C\u5E76\u652F\u6301\u63A8\u8FDF Gateway \u91CD\u542F\u3002"
20719
+ "original-installer": "\u8BF7\u4F7F\u7528\u539F\u5B89\u88C5\u7A0B\u5E8F\u3001\u5305\u7BA1\u7406\u5668\u6216\u542F\u52A8\u5668\u66F4\u65B0\u6B64\u5B89\u88C5\u3002"
20589
20720
  })
20590
20721
  });
20591
20722
  function harnessVersionLabel(state, messages) {
@@ -20597,6 +20728,7 @@ th[aria-sort] .console-usage-sort__mark {
20597
20728
  return state.latestVersion;
20598
20729
  }
20599
20730
  function harnessVersionNote(state, messages) {
20731
+ if (state?.notice) return localizeHarnessText(state.notice, messages.locale);
20600
20732
  const code = state?.messageCode;
20601
20733
  return code && Object.hasOwn(messages.notes, code) ? messages.notes[code] : void 0;
20602
20734
  }
@@ -20775,16 +20907,23 @@ th[aria-sort] .console-usage-sort__mark {
20775
20907
  launchPathSaveError: "Could not save. Enter an existing absolute installation folder on this Host and check configuration permissions.",
20776
20908
  connectionOfficialWebsite: "Visit official website",
20777
20909
  connectionOpenHarnessWeb: "Open DeepSeek Harness Web",
20778
- connectionDeepSeekTestedVersions: "Supported DSH versions: 0.1.7-rc.1, 0.1.7-rc.2, 0.2.0-rc.1 and 0.2.0-rc.2. Versions newer than 0.2.0-rc.2 can be tried, but compatibility may be limited; versions older than 0.1.7-rc.1 must be upgraded first.",
20910
+ connectionDeepSeekTestedVersions: "Supported DSH versions: 0.1.7-rc.1, 0.1.7-rc.2, 0.2.0-rc.1, 0.2.0-rc.2, 0.2.1-rc.1 and 0.2.1-rc.2. Versions newer than 0.2.1-rc.2 can be tried, but compatibility may be limited; versions older than 0.1.7-rc.1 must be upgraded first.",
20779
20911
  connectionInstall: "Install",
20780
20912
  connectionInstallDescription: "This Harness was not detected.",
20781
20913
  connectionInstallRunning: "Installing on the selected Host. You can leave this page; login or setup may still be required afterward.",
20782
20914
  harnessVersion: harnessVersionEnglish,
20783
20915
  harnessVersionTitle: "Harness CLI version",
20916
+ harnessVersionApplicationTitle: "Application version",
20784
20917
  harnessVersionCurrent: "Current version",
20785
20918
  harnessVersionLatest: "Latest version",
20786
20919
  harnessVersionChecking: "Checking versions\u2026",
20920
+ harnessVersionAvailable: "Update available",
20787
20921
  harnessVersionUpdate: "Update",
20922
+ harnessVersionDownloadUpdate: "Download update",
20923
+ harnessUpdateAll: "Update all",
20924
+ harnessUpdateAllProgress: "Updating",
20925
+ harnessUpdateAllDescription: "Update all eligible Harnesses on the selected Host.",
20926
+ harnessUpdateAllResult: "Updated {succeeded}; failed {failed}.",
20788
20927
  harnessVersionUpdating: "Updating\u2026",
20789
20928
  harnessVersionUpToDate: "Up to date",
20790
20929
  harnessVersionUpdated: "Update verified. New sessions will use the new version.",
@@ -21048,16 +21187,23 @@ th[aria-sort] .console-usage-sort__mark {
21048
21187
  launchPathSaveError: "\u4FDD\u5B58\u5931\u8D25\u3002\u8BF7\u586B\u5199\u6B64 Host \u4E0A\u5B9E\u9645\u5B58\u5728\u7684\u5B89\u88C5\u76EE\u5F55\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u5E76\u786E\u8BA4\u914D\u7F6E\u76EE\u5F55\u53EF\u5199\u3002",
21049
21188
  connectionOfficialWebsite: "\u8BBF\u95EE\u5B98\u7F51",
21050
21189
  connectionOpenHarnessWeb: "\u6253\u5F00 DeepSeek Harness Web",
21051
- connectionDeepSeekTestedVersions: "\u652F\u6301 DSH \u7248\u672C\uFF1A0.1.7-rc.1\u30010.1.7-rc.2\u30010.2.0-rc.1 \u548C 0.2.0-rc.2\u3002\u9AD8\u4E8E 0.2.0-rc.2 \u7684\u7248\u672C\u53EF\u4EE5\u5C1D\u8BD5\u8FDE\u63A5\uFF0C\u4F46\u9002\u914D\u5EA6\u53EF\u80FD\u6709\u9650\uFF1B\u4F4E\u4E8E 0.1.7-rc.1 \u7684\u7248\u672C\u9700\u8981\u5148\u5347\u7EA7\u3002",
21190
+ connectionDeepSeekTestedVersions: "\u652F\u6301 DSH \u7248\u672C\uFF1A0.1.7-rc.1\u30010.1.7-rc.2\u30010.2.0-rc.1\u30010.2.0-rc.2\u30010.2.1-rc.1 \u548C 0.2.1-rc.2\u3002\u9AD8\u4E8E 0.2.1-rc.2 \u7684\u7248\u672C\u53EF\u4EE5\u5C1D\u8BD5\u8FDE\u63A5\uFF0C\u4F46\u9002\u914D\u5EA6\u53EF\u80FD\u6709\u9650\uFF1B\u4F4E\u4E8E 0.1.7-rc.1 \u7684\u7248\u672C\u9700\u8981\u5148\u5347\u7EA7\u3002",
21052
21191
  connectionInstall: "\u5B89\u88C5",
21053
21192
  connectionInstallDescription: "\u5C1A\u672A\u68C0\u6D4B\u5230\u8BE5 Harness\u3002",
21054
21193
  connectionInstallRunning: "\u6B63\u5728\u6240\u9009 Host \u4E0A\u5B89\u88C5\uFF0C\u79BB\u5F00\u9875\u9762\u4E0D\u4F1A\u4E2D\u65AD\u3002\u5B89\u88C5\u540E\u53EF\u80FD\u4ECD\u9700\u767B\u5F55\u6216\u914D\u7F6E\u3002",
21055
21194
  harnessVersion: harnessVersionChinese,
21056
21195
  harnessVersionTitle: "Harness CLI \u7248\u672C",
21196
+ harnessVersionApplicationTitle: "\u5E94\u7528\u7248\u672C",
21057
21197
  harnessVersionCurrent: "\u5F53\u524D\u7248\u672C",
21058
21198
  harnessVersionLatest: "\u6700\u65B0\u7248\u672C",
21059
21199
  harnessVersionChecking: "\u6B63\u5728\u68C0\u67E5\u7248\u672C\u2026",
21200
+ harnessVersionAvailable: "\u6709\u66F4\u65B0",
21060
21201
  harnessVersionUpdate: "\u66F4\u65B0",
21202
+ harnessVersionDownloadUpdate: "\u4E0B\u8F7D\u66F4\u65B0",
21203
+ harnessUpdateAll: "\u5168\u90E8\u66F4\u65B0",
21204
+ harnessUpdateAllProgress: "\u66F4\u65B0\u4E2D",
21205
+ harnessUpdateAllDescription: "\u66F4\u65B0\u5F53\u524D Host \u4E0A\u652F\u6301\u81EA\u52A8\u66F4\u65B0\u4E14\u6709\u65B0\u7248\u672C\u7684 Harness\u3002",
21206
+ harnessUpdateAllResult: "\u5DF2\u66F4\u65B0 {succeeded} \u9879\uFF0C{failed} \u9879\u5931\u8D25\u3002",
21061
21207
  harnessVersionUpdating: "\u6B63\u5728\u66F4\u65B0\u2026",
21062
21208
  harnessVersionUpToDate: "\u5DF2\u662F\u6700\u65B0",
21063
21209
  harnessVersionUpdated: "\u5DF2\u786E\u8BA4\u66F4\u65B0\u6210\u529F\uFF0C\u65B0\u4F1A\u8BDD\u5C06\u4F7F\u7528\u65B0\u7248\u672C\u3002",
@@ -21176,10 +21322,37 @@ th[aria-sort] .console-usage-sort__mark {
21176
21322
  return names.size === 1 ? names.values().next().value ?? model2 : model2;
21177
21323
  }
21178
21324
 
21325
+ // src/console/usage/usage-hosts.ts
21326
+ var LOCAL_USAGE_HOST_ID = "local";
21327
+ function usageHostOptions(hosts, localLabel, selected) {
21328
+ const options = [{ key: LOCAL_USAGE_HOST_ID, label: localLabel }];
21329
+ const seen = /* @__PURE__ */ new Set([LOCAL_USAGE_HOST_ID]);
21330
+ const add = (hostId2, label) => {
21331
+ if (hostId2.length === 0 || seen.has(hostId2)) return;
21332
+ seen.add(hostId2);
21333
+ options.push({ key: hostId2, label: label !== void 0 && label.length > 0 ? label : hostId2 });
21334
+ };
21335
+ for (const host of hosts ?? []) add(host.hostId, host.label);
21336
+ if (!seen.has(selected)) add(selected, void 0);
21337
+ return options;
21338
+ }
21339
+ function createLatestKeyGuard() {
21340
+ let generation = 0;
21341
+ let key;
21342
+ return {
21343
+ begin(next) {
21344
+ generation += 1;
21345
+ key = next;
21346
+ const mine = generation;
21347
+ const selected = next;
21348
+ return () => generation === mine && Object.is(key, selected);
21349
+ }
21350
+ };
21351
+ }
21352
+
21179
21353
  // src/renderer-usage-control.ts
21180
21354
  var ENGLISH_USAGE_MESSAGES = Object.freeze({
21181
21355
  usage: "Usage",
21182
- account: "Account",
21183
21356
  context: "Context",
21184
21357
  recordedCredits: "Recorded usage",
21185
21358
  latestCacheHit: "Latest cache hit (CH)",
@@ -21205,7 +21378,6 @@ th[aria-sort] .console-usage-sort__mark {
21205
21378
  });
21206
21379
  var CHINESE_USAGE_MESSAGES = Object.freeze({
21207
21380
  usage: "\u7528\u91CF",
21208
- account: "\u8D26\u53F7",
21209
21381
  context: "\u4E0A\u4E0B\u6587",
21210
21382
  recordedCredits: "\u5DF2\u8BB0\u5F55\u6D88\u8017",
21211
21383
  latestCacheHit: "\u6700\u8FD1\u7F13\u5B58\u547D\u4E2D\uFF08CH\uFF09",
@@ -22536,6 +22708,7 @@ th[aria-sort] .console-usage-sort__mark {
22536
22708
  const range = text("range");
22537
22709
  const measure = text("measure");
22538
22710
  const granularity = text("granularity");
22711
+ const hostId2 = text("hostId");
22539
22712
  const harness2 = text("harness");
22540
22713
  const model2 = text("model");
22541
22714
  const project2 = text("project");
@@ -22544,6 +22717,7 @@ th[aria-sort] .console-usage-sort__mark {
22544
22717
  ...range && USAGE_STATISTICS_RANGES.includes(range) ? { range } : {},
22545
22718
  ...measure && MEASURES.includes(measure) ? { measure } : {},
22546
22719
  ...granularity === "day" || granularity === "week" || granularity === "month" ? { granularity } : {},
22720
+ ...hostId2 !== void 0 && hostId2.length > 0 ? { hostId: hostId2 } : {},
22547
22721
  ...harness2 !== void 0 ? { harness: harness2 } : {},
22548
22722
  ...model2 !== void 0 ? { model: model2 } : {},
22549
22723
  ...project2 !== void 0 ? { project: project2 } : {},
@@ -22582,7 +22756,7 @@ th[aria-sort] .console-usage-sort__mark {
22582
22756
  day.setDate(day.getDate() - (day.getDay() + 6) % 7);
22583
22757
  return isoDate(day);
22584
22758
  }
22585
- function createUsageStatisticsPage(consoleMessages2, request, pageLocale) {
22759
+ function createUsageStatisticsPage(consoleMessages2, request, pageLocale, usageHosts) {
22586
22760
  const messages = consoleMessages2.usageStatistics;
22587
22761
  return Object.freeze({
22588
22762
  id: "usage-statistics",
@@ -22591,10 +22765,12 @@ th[aria-sort] .console-usage-sort__mark {
22591
22765
  mount(context) {
22592
22766
  const document2 = context.content.ownerDocument;
22593
22767
  const locale = pageLocale ?? (document2.documentElement.lang || "en");
22768
+ const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
22594
22769
  const count3 = (value) => count2(value, locale);
22595
22770
  const tokenCount2 = (totals2, value) => tokenCount(totals2, value, locale);
22596
22771
  const saved = readView();
22597
22772
  const view = {
22773
+ hostId: saved.hostId ?? LOCAL_USAGE_HOST_ID,
22598
22774
  range: saved.range ?? "30d",
22599
22775
  measure: saved.measure ?? "cost",
22600
22776
  granularity: saved.granularity ?? null,
@@ -22625,7 +22801,7 @@ th[aria-sort] .console-usage-sort__mark {
22625
22801
  let projectLabel = /* @__PURE__ */ new Map();
22626
22802
  const projectName = (key) => key === UNKNOWN ? messages.unknownProject : projectLabel.get(key) ?? baseName(key);
22627
22803
  const measureLabel = (measure) => measure === "cost" ? messages.cost : messages.tokens;
22628
- const dateFormat = (options) => new Intl.DateTimeFormat(locale, options);
22804
+ const dateFormat = (options) => new Intl.DateTimeFormat(locale, { ...options, timeZone });
22629
22805
  const shortDate = dateFormat({ month: "short", day: "numeric" });
22630
22806
  const longDate = dateFormat({
22631
22807
  year: "numeric",
@@ -22644,10 +22820,51 @@ th[aria-sort] .console-usage-sort__mark {
22644
22820
  const prices = createModelPricesDialog(
22645
22821
  document2,
22646
22822
  consoleMessages2,
22647
- request,
22823
+ (method, params2) => request(method, params2, view.hostId),
22648
22824
  context.signal,
22649
22825
  load
22650
22826
  );
22827
+ let offeredHosts = usageHosts ? [] : void 0;
22828
+ const hostCombo = new ComboBox(document2, {
22829
+ label: messages.host,
22830
+ searchLabel: messages.search,
22831
+ emptyLabel: messages.noMatches,
22832
+ signal: context.signal,
22833
+ searchable: false,
22834
+ display: (option) => `${messages.host} \xB7 ${option.label}`,
22835
+ onChange: (key) => {
22836
+ if (key === view.hostId) return;
22837
+ view.hostId = key;
22838
+ view.harness = "";
22839
+ view.model = "";
22840
+ view.project = "";
22841
+ date5 = null;
22842
+ unpricedOnly = false;
22843
+ result = null;
22844
+ error51 = null;
22845
+ loadedAt = 0;
22846
+ names.clear();
22847
+ save();
22848
+ hostOptions();
22849
+ render();
22850
+ void refreshHarnessNames();
22851
+ load();
22852
+ }
22853
+ });
22854
+ const hostOptions = () => {
22855
+ const options = usageHostOptions(offeredHosts, messages.localHost, view.hostId);
22856
+ hostCombo.element.hidden = options.length < 2;
22857
+ hostCombo.update(options, view.hostId === LOCAL_USAGE_HOST_ID ? "" : view.hostId);
22858
+ };
22859
+ const offerHosts = () => {
22860
+ if (!usageHosts) return;
22861
+ void usageHosts().then((hosts) => {
22862
+ if (context.signal.aborted) return;
22863
+ offeredHosts = hosts;
22864
+ hostOptions();
22865
+ }).catch(() => void 0);
22866
+ };
22867
+ hostOptions();
22651
22868
  const updated = h(document2, "span", { className: "console-muted console-usage-updated" });
22652
22869
  const refresh = h(
22653
22870
  document2,
@@ -22660,7 +22877,10 @@ th[aria-sort] .console-usage-sort__mark {
22660
22877
  },
22661
22878
  createRendererSettingsIcon("refresh", 16)
22662
22879
  );
22663
- refresh.addEventListener("click", () => load());
22880
+ refresh.addEventListener("click", () => {
22881
+ offerHosts();
22882
+ load();
22883
+ });
22664
22884
  const auto = new ComboBox(document2, {
22665
22885
  label: messages.autoRefresh,
22666
22886
  searchLabel: messages.search,
@@ -22699,6 +22919,7 @@ th[aria-sort] .console-usage-sort__mark {
22699
22919
  document2,
22700
22920
  "div",
22701
22921
  { className: "console-usage-toolbar" },
22922
+ hostCombo.element,
22702
22923
  updated,
22703
22924
  refresh,
22704
22925
  auto.element,
@@ -23337,7 +23558,6 @@ ${detail}` : ""}`
23337
23558
  }
23338
23559
  function hourlyPanel(data) {
23339
23560
  const singleDay = data.filters.date !== null || data.range === "today";
23340
- const zone = Intl.DateTimeFormat().resolvedOptions().timeZone;
23341
23561
  return panel(
23342
23562
  singleDay ? messages.hourlyDay : messages.hourly,
23343
23563
  hourlyChart(document2, {
@@ -23352,7 +23572,7 @@ ${detail}` : ""}`
23352
23572
  weekStartsOnMonday: !locale.startsWith("en"),
23353
23573
  labels: { cost: messages.cost, tokens: messages.tokens }
23354
23574
  }),
23355
- h(document2, "span", { className: "console-muted console-usage-zone" }, zone)
23575
+ h(document2, "span", { className: "console-muted console-usage-zone" }, timeZone)
23356
23576
  );
23357
23577
  }
23358
23578
  function sessionsPanel(title, rows, tableKey) {
@@ -23499,6 +23719,7 @@ ${detail}` : ""}`
23499
23719
  const project2 = filterValue(view.project);
23500
23720
  return {
23501
23721
  range: view.range,
23722
+ timeZone,
23502
23723
  ...view.harness ? { harness: view.harness } : {},
23503
23724
  ...model2 !== void 0 ? { model: model2 } : {},
23504
23725
  ...project2 !== void 0 ? { project: project2 } : {},
@@ -23511,10 +23732,26 @@ ${detail}` : ""}`
23511
23732
  if (result && !result.reading.complete) poll = window.setTimeout(load, POLL_MS);
23512
23733
  else if (view.autoRefreshMs > 0) poll = window.setTimeout(load, view.autoRefreshMs);
23513
23734
  }
23735
+ const harnessNamesRead = createLatestKeyGuard();
23736
+ async function refreshHarnessNames() {
23737
+ const hostId2 = view.hostId;
23738
+ const isCurrent = harnessNamesRead.begin(hostId2);
23739
+ names.clear();
23740
+ try {
23741
+ const value = await request(HARNESS_PLUGIN_LIST_METHOD2, {}, hostId2);
23742
+ if (!isCurrent()) return;
23743
+ for (const plugin of harnessPluginListResultSchema.parse(value).plugins) {
23744
+ names.set(plugin.id, plugin.name);
23745
+ }
23746
+ } catch {
23747
+ if (!isCurrent()) return;
23748
+ }
23749
+ if (!context.signal.aborted) render();
23750
+ }
23514
23751
  function load() {
23515
23752
  window.clearTimeout(poll);
23516
23753
  const requested = params();
23517
- void context.runLatest(() => request(USAGE_STATISTICS_METHOD, requested), {
23754
+ void context.runLatest(() => request(USAGE_STATISTICS_METHOD, requested, view.hostId), {
23518
23755
  success(value) {
23519
23756
  const parsed = usageStatisticsResultSchema.safeParse(value);
23520
23757
  if (parsed.success) {
@@ -23539,12 +23776,8 @@ ${detail}` : ""}`
23539
23776
  }
23540
23777
  context.content.replaceChildren(header, prices.element, filters, notices, body);
23541
23778
  render();
23542
- void request(HARNESS_PLUGIN_LIST_METHOD2, {}).then((value) => {
23543
- for (const plugin of harnessPluginListResultSchema.parse(value).plugins) {
23544
- names.set(plugin.id, plugin.name);
23545
- }
23546
- if (!context.signal.aborted) render();
23547
- }).catch(() => void 0);
23779
+ offerHosts();
23780
+ void refreshHarnessNames();
23548
23781
  load();
23549
23782
  return () => {
23550
23783
  window.clearTimeout(poll);
@@ -25021,7 +25254,7 @@ ${detail}` : ""}`
25021
25254
  }
25022
25255
 
25023
25256
  // src/settings/harness-version-panel.ts
25024
- function createHarnessVersionPanel(document2, messages, signal, agent, client) {
25257
+ function createHarnessVersionPanel(document2, messages, signal, agent, client, onChange = () => void 0) {
25025
25258
  const panel = document2.createElement("section");
25026
25259
  panel.className = "settings-harness-version";
25027
25260
  panel.dataset.harnessVersion = agent;
@@ -25047,37 +25280,67 @@ ${detail}` : ""}`
25047
25280
  panel.append(heading, versions, status, actions, note);
25048
25281
  let state;
25049
25282
  let busy = false;
25283
+ let updating = false;
25050
25284
  let unsupported = false;
25285
+ let updatePromise = null;
25051
25286
  const render = () => {
25287
+ heading.textContent = state?.versionKind === "application" ? messages.harnessVersionApplicationTitle : messages.harnessVersionTitle;
25052
25288
  current.textContent = `${messages.harnessVersionCurrent}: ${state?.currentVersion ?? "\u2014"}`;
25053
25289
  latest.textContent = `${messages.harnessVersionLatest}: ${harnessVersionLabel(state, messages.harnessVersion)}`;
25054
25290
  update.disabled = busy || signal.aborted || !state?.canUpdate || !state.updateAvailable;
25291
+ const manualUrl = !state?.canUpdate && state?.updateAvailable ? state.manualUpdateUrl : void 0;
25292
+ actions.replaceChildren(update);
25293
+ update.hidden = !busy && !signal.aborted && Boolean(manualUrl);
25294
+ if (update.hidden && manualUrl) {
25295
+ const download2 = document2.createElement("a");
25296
+ download2.className = "settings-command-button settings-command-button--secondary";
25297
+ download2.dataset.harnessVersionAction = "download-update";
25298
+ download2.textContent = messages.harnessVersionDownloadUpdate;
25299
+ download2.href = manualUrl;
25300
+ download2.target = "_blank";
25301
+ download2.rel = "noopener noreferrer";
25302
+ actions.append(download2);
25303
+ }
25055
25304
  update.textContent = state?.canUpdate && state.latestVersion !== "Unknown" && !state.updateAvailable ? messages.harnessVersionUpToDate : messages.harnessVersionUpdate;
25056
25305
  const detail = harnessVersionNote(state, messages.harnessVersion);
25057
- note.textContent = detail ? `${detail} ${messages.harnessVersionNote}` : messages.harnessVersionNote;
25306
+ note.textContent = detail ? !state?.canUpdate ? detail : `${detail} ${messages.harnessVersionNote}` : messages.harnessVersionNote;
25058
25307
  };
25059
25308
  const run = async (action) => {
25060
- if (busy || unsupported || signal.aborted) return;
25061
- if (action === "update" && (!state?.canUpdate || !state.updateAvailable)) return;
25309
+ if (busy || unsupported || signal.aborted) return false;
25310
+ if (action === "update" && (!state?.canUpdate || !state.updateAvailable)) return false;
25062
25311
  busy = true;
25312
+ updating = action === "update";
25313
+ onChange();
25063
25314
  status.textContent = action === "check" ? messages.harnessVersionChecking : messages.harnessVersionUpdating;
25064
25315
  render();
25065
25316
  try {
25066
25317
  const result = await client.run(action);
25067
- if (signal.aborted) return;
25318
+ if (signal.aborted) return false;
25068
25319
  state = result;
25069
25320
  status.textContent = !result.canUpdate ? messages.harnessVersionManual : action === "update" ? result.updateAvailable ? messages.harnessVersionFailed : messages.harnessVersionUpdated : "";
25321
+ return result.canUpdate && !result.updateAvailable;
25070
25322
  } catch (error51) {
25071
- if (signal.aborted) return;
25323
+ if (signal.aborted) return false;
25072
25324
  unsupported = typeof error51 === "object" && error51 !== null && "code" in error51 && (error51.code === -32601 || error51.code === -32078);
25073
25325
  status.textContent = unsupported ? messages.harnessVersionUnsupported : messages.harnessVersionFailed;
25074
25326
  if (state) state = { ...state, canUpdate: false };
25327
+ return false;
25075
25328
  } finally {
25076
25329
  busy = false;
25077
- if (!signal.aborted) render();
25330
+ updating = false;
25331
+ if (!signal.aborted) {
25332
+ render();
25333
+ onChange();
25334
+ }
25078
25335
  }
25079
25336
  };
25080
- update.addEventListener("click", () => void run("update"));
25337
+ const updateVersion = () => {
25338
+ updatePromise ??= run("update").finally(() => {
25339
+ updatePromise = null;
25340
+ });
25341
+ return updatePromise;
25342
+ };
25343
+ update.addEventListener("click", () => void updateVersion());
25081
25344
  const owner = document2.defaultView;
25082
25345
  let checkFrame = null;
25083
25346
  let checkTimer = null;
@@ -25104,7 +25367,95 @@ ${detail}` : ""}`
25104
25367
  } else {
25105
25368
  void run("check");
25106
25369
  }
25107
- return panel;
25370
+ return {
25371
+ element: panel,
25372
+ get state() {
25373
+ return state;
25374
+ },
25375
+ get updating() {
25376
+ return updating;
25377
+ },
25378
+ update: updateVersion
25379
+ };
25380
+ }
25381
+
25382
+ // src/settings/connection-versions.ts
25383
+ function createConnectionVersions(document2, messages, signal, diagnostics, onChange) {
25384
+ const panels = /* @__PURE__ */ new Map();
25385
+ const installation = diagnostics?.installation?.bind(diagnostics);
25386
+ return {
25387
+ get(hostId2, agent) {
25388
+ if (!installation || signal.aborted) return void 0;
25389
+ const key = JSON.stringify([hostId2, agent]);
25390
+ let panel = panels.get(key);
25391
+ if (!panel) {
25392
+ panel = createHarnessVersionPanel(
25393
+ document2,
25394
+ messages,
25395
+ signal,
25396
+ agent,
25397
+ {
25398
+ run: (action) => installation(hostId2, agent, action)
25399
+ },
25400
+ onChange
25401
+ );
25402
+ panels.set(key, panel);
25403
+ }
25404
+ return panel;
25405
+ }
25406
+ };
25407
+ }
25408
+
25409
+ // src/settings/connection-updates.ts
25410
+ function createConnectionUpdates(document2, messages, signal, onChange) {
25411
+ const batches = /* @__PURE__ */ new Map();
25412
+ const eligible = (panels) => panels.filter((panel) => panel.state?.updateAvailable && panel.state.canUpdate);
25413
+ const start = async (hostId2, panels) => {
25414
+ if (signal.aborted || batches.get(hostId2)?.running) return;
25415
+ const targets = eligible(panels);
25416
+ if (!targets.length) return;
25417
+ const batch = { running: true, total: targets.length, succeeded: 0, failed: 0 };
25418
+ batches.set(hostId2, batch);
25419
+ onChange();
25420
+ await Promise.all(
25421
+ targets.map(async (panel) => {
25422
+ try {
25423
+ if (await panel.update()) batch.succeeded++;
25424
+ else batch.failed++;
25425
+ } catch {
25426
+ batch.failed++;
25427
+ }
25428
+ if (!signal.aborted) onChange();
25429
+ })
25430
+ );
25431
+ batch.running = false;
25432
+ if (!signal.aborted) onChange();
25433
+ };
25434
+ return {
25435
+ createControls(hostId2, panels) {
25436
+ const batch = batches.get(hostId2);
25437
+ const count3 = eligible(panels).length;
25438
+ const button2 = document2.createElement("button");
25439
+ button2.type = "button";
25440
+ button2.className = "settings-command-button settings-command-button--secondary settings-connection-update-all";
25441
+ button2.dataset.connectionAction = "update-all";
25442
+ button2.disabled = signal.aborted || Boolean(batch?.running) || !count3;
25443
+ button2.title = messages.harnessUpdateAllDescription;
25444
+ const label = batch?.running ? `${messages.harnessUpdateAllProgress} ${batch.succeeded + batch.failed}/${batch.total}` : count3 ? `${messages.harnessUpdateAll} (${count3})` : messages.harnessUpdateAll;
25445
+ button2.append(createRendererSettingsIcon("download", 15), label);
25446
+ button2.addEventListener("click", () => {
25447
+ if (!button2.disabled) void start(hostId2, panels);
25448
+ });
25449
+ const result = document2.createElement("p");
25450
+ result.className = "settings-connection-update-result";
25451
+ result.setAttribute("role", "status");
25452
+ result.hidden = !batch || batch.running;
25453
+ if (batch && !batch.running) {
25454
+ result.textContent = messages.harnessUpdateAllResult.replace("{succeeded}", String(batch.succeeded)).replace("{failed}", String(batch.failed));
25455
+ }
25456
+ return { button: button2, result };
25457
+ }
25458
+ };
25108
25459
  }
25109
25460
 
25110
25461
  // src/settings/connections-page.ts
@@ -25272,6 +25623,7 @@ ${error51.stderrTail}`] : []
25272
25623
  status.dataset.connectionTone = connectionStatusTone(item.availability, item.error !== null);
25273
25624
  status.setAttribute("role", "cell");
25274
25625
  status.textContent = item.error?.code === "authenticationRequired" ? messages.connectionLoginRequired : item.error?.code === "configurationRequired" ? messages.connectionConfigurationRequired : connectionStatusLabel(item.availability, messages, item.error !== null);
25626
+ const version2 = item.version;
25275
25627
  const action = document2.createElement("div");
25276
25628
  action.className = "settings-connection-row__action";
25277
25629
  action.setAttribute("role", "cell");
@@ -25301,6 +25653,31 @@ ${error51.stderrTail}`] : []
25301
25653
  });
25302
25654
  action.append(viewError);
25303
25655
  }
25656
+ if (version2?.state?.updateAvailable && !version2.updating) {
25657
+ const available = document2.createElement("span");
25658
+ available.className = "settings-connection-version-available";
25659
+ available.textContent = messages.harnessVersionAvailable;
25660
+ available.title = `${messages.harnessVersionCurrent}: ${version2.state.currentVersion ?? "\u2014"}
25661
+ ${messages.harnessVersionLatest}: ${harnessVersionLabel(version2.state, messages.harnessVersion)}`;
25662
+ action.append(available);
25663
+ }
25664
+ if (version2?.state?.updateAvailable && version2.state.canUpdate) {
25665
+ const update = document2.createElement("button");
25666
+ update.type = "button";
25667
+ update.className = "settings-connection-install-link";
25668
+ update.dataset.connectionAction = "update";
25669
+ update.disabled = version2.updating;
25670
+ update.title = messages.harnessVersionUpdate;
25671
+ update.setAttribute("aria-label", `${messages.harnessVersionUpdate}: ${item.name}`);
25672
+ update.append(createRendererSettingsIcon("download", 17));
25673
+ update.addEventListener("click", (event) => {
25674
+ event.stopPropagation();
25675
+ if (update.disabled) return;
25676
+ void version2.update();
25677
+ select();
25678
+ });
25679
+ action.append(update);
25680
+ }
25304
25681
  if (group) {
25305
25682
  const toggle = document2.createElement("button");
25306
25683
  toggle.type = "button";
@@ -25589,8 +25966,6 @@ ${error51.stderrTail}`] : []
25589
25966
  let selectedHostId = null;
25590
25967
  let selectedItemKey = null;
25591
25968
  let launchControls = null;
25592
- const versionPanels = /* @__PURE__ */ new Map();
25593
- const updatingVersions = /* @__PURE__ */ new Set();
25594
25969
  const hostNames = /* @__PURE__ */ new Map();
25595
25970
  let latestSnapshot = null;
25596
25971
  let disposeHostScroller = () => void 0;
@@ -25619,7 +25994,15 @@ ${error51.stderrTail}`] : []
25619
25994
  renderFrame = null;
25620
25995
  };
25621
25996
  const diagnostics = getDiagnostics();
25997
+ const versions = createConnectionVersions(
25998
+ document2,
25999
+ messages,
26000
+ context.signal,
26001
+ diagnostics,
26002
+ scheduleRender
26003
+ );
25622
26004
  const installs = diagnostics ? harnessInstallStore(diagnostics) : null;
26005
+ const updates = createConnectionUpdates(document2, messages, context.signal, scheduleRender);
25623
26006
  const runRefresh = () => {
25624
26007
  if (pending || !diagnostics) return;
25625
26008
  pending = true;
@@ -25755,10 +26138,13 @@ ${error51.stderrTail}`] : []
25755
26138
  const agent = item.agentSnapshot?.agent;
25756
26139
  if (!agent) return item;
25757
26140
  const state = installs?.get(selectedHost.hostId, agent);
26141
+ const availability = state?.status ?? item.availability;
26142
+ const version2 = item.agentSnapshot?.availability !== "notInstalled" && availability !== "installing" && availability !== "checking" ? versions.get(selectedHost.hostId, agent) : void 0;
25758
26143
  return {
25759
26144
  ...item,
25760
26145
  ...state ? { availability: state.status } : {},
25761
- ...updatingVersions.has(JSON.stringify([selectedHost.hostId, agent])) ? { availability: "updating" } : {},
26146
+ ...version2 ? { version: version2 } : {},
26147
+ ...version2?.updating ? { availability: "updating" } : {},
25762
26148
  ...state?.error ? { installError: state.error } : {},
25763
26149
  ...diagnostics?.installation && harnessHasInstallCommands(item.agentSnapshot?.plugin) ? {
25764
26150
  install: () => {
@@ -25795,30 +26181,7 @@ ${error51.stderrTail}`] : []
25795
26181
  runRefresh
25796
26182
  );
25797
26183
  launchControls = { hostId: selectedHost.hostId, itemKey: item.key, element };
25798
- const agent = item.agentSnapshot?.agent;
25799
- const installation = diagnostics?.installation?.bind(diagnostics);
25800
- if (agent && item.agentSnapshot?.availability !== "notInstalled" && item.availability !== "installing" && item.availability !== "checking" && installation) {
25801
- const key = JSON.stringify([selectedHost.hostId, agent]);
25802
- let panel = versionPanels.get(key);
25803
- if (!panel) {
25804
- const hostId2 = selectedHost.hostId;
25805
- panel = createHarnessVersionPanel(document2, messages, context.signal, agent, {
25806
- async run(action) {
25807
- if (action !== "update") return installation(hostId2, agent, action);
25808
- updatingVersions.add(key);
25809
- if (diagnostics) render(diagnostics.snapshot());
25810
- try {
25811
- return await installation(hostId2, agent, action);
25812
- } finally {
25813
- updatingVersions.delete(key);
25814
- if (!context.signal.aborted && diagnostics) render(diagnostics.snapshot());
25815
- }
25816
- }
25817
- });
25818
- versionPanels.set(key, panel);
25819
- }
25820
- inspector.append(panel);
25821
- }
26184
+ if (item.version) inspector.append(item.version.element);
25822
26185
  };
25823
26186
  const pinnedItem = items.find((item) => item.key === "renderer-adapter");
25824
26187
  if (pinnedItem) {
@@ -25974,7 +26337,14 @@ ${error51.stderrTail}`] : []
25974
26337
  }
25975
26338
  const selectedItem = items.find((item) => item.key === selectedItemKey) ?? items[0];
25976
26339
  if (selectedItem) selectItem(selectedItem);
25977
- list.append(hostStrip, tableHeader, rows);
26340
+ const updateControls = updates.createControls(
26341
+ selectedHost.hostId,
26342
+ items.flatMap((item) => item.version ? [item.version] : [])
26343
+ );
26344
+ const hostHeader = document2.createElement("div");
26345
+ hostHeader.className = "settings-connection-host-header";
26346
+ hostHeader.append(hostStrip, updateControls.button);
26347
+ list.append(hostHeader, updateControls.result, tableHeader, rows);
25978
26348
  layout.append(list, inspector);
25979
26349
  content.replaceChildren(layout);
25980
26350
  disposeHostScroller = configureHostScroller(
@@ -27660,17 +28030,6 @@ ${error51.stderrTail}`] : []
27660
28030
  if (periodType === "seven_day") return messages.accountCreditsPeriodSevenDay;
27661
28031
  return messages.accountCreditsPeriodUnknown;
27662
28032
  }
27663
- function creditsProductLabel(product, messages) {
27664
- if (product === "GrokBuild" || product === "Build") return messages.accountCreditsBuild;
27665
- if (product === "5-hour window") return messages.accountCreditsPeriodFiveHour;
27666
- if (product === "7-day window") return messages.accountCreditsPeriodSevenDay;
27667
- if (product.endsWith(" \xB7 monthly"))
27668
- return `${product.slice(0, -" \xB7 monthly".length)} \xB7 ${messages.accountCreditsPeriodMonthly}`;
27669
- if (product === "GrokChat") return "Chat";
27670
- if (product === "GrokImagine") return "Imagine";
27671
- if (product === "GrokVoice") return "Voice";
27672
- return product;
27673
- }
27674
28033
  function formatAccountCreditsReset(value, locale, now = /* @__PURE__ */ new Date()) {
27675
28034
  if (locale !== "zh-CN") return formatRendererCreditsReset(value, now);
27676
28035
  const date5 = new Date(value);
@@ -27697,36 +28056,22 @@ ${error51.stderrTail}`] : []
27697
28056
  if (periodType === "weekly" || periodType === "seven_day") return "seven_day";
27698
28057
  return null;
27699
28058
  }
27700
- function scopedUsageProduct(product) {
27701
- const suffixes = [
27702
- [" \xB7 5-hour window", "five_hour"],
27703
- [" \xB7 Weekly window", "seven_day"],
27704
- [" \xB7 7-day window", "seven_day"],
27705
- [" \xB7 5-hour", "five_hour"],
27706
- [" \xB7 7-day", "seven_day"]
27707
- ];
27708
- for (const [suffix, period] of suffixes) {
27709
- if (!product.endsWith(suffix)) continue;
27710
- const scope = product.slice(0, -suffix.length).trim();
27711
- if (scope) return { scope, period };
27712
- }
27713
- return null;
27714
- }
27715
28059
  function splitUsageWindows(credits, messages, filter) {
27716
28060
  const generic = { columns: {} };
27717
28061
  const scopedRows = /* @__PURE__ */ new Map();
27718
28062
  const additional = [];
27719
28063
  const addScoped = (scope, period, window2) => {
27720
- const rows2 = scopedRows.get(scope) ?? [];
28064
+ const scopeLabel = localizeHarnessPresentation(scope, messages.locale).label;
28065
+ const rows2 = scopedRows.get(scope.id) ?? [];
27721
28066
  let row = rows2.find((candidate) => !candidate.columns[period]);
27722
28067
  if (!row) {
27723
- row = { scope, columns: {} };
28068
+ row = { scope: scopeLabel, columns: {} };
27724
28069
  rows2.push(row);
27725
- scopedRows.set(scope, rows2);
28070
+ scopedRows.set(scope.id, rows2);
27726
28071
  }
27727
28072
  row.columns[period] = {
27728
28073
  ...window2,
27729
- label: `${scope} \xB7 ${creditsPeriodLabel(period, messages)}`,
28074
+ label: window2.label,
27730
28075
  scoped: true
27731
28076
  };
27732
28077
  };
@@ -27736,29 +28081,30 @@ ${error51.stderrTail}`] : []
27736
28081
  else additional.push(window2);
27737
28082
  };
27738
28083
  const primary = {
27739
- label: credits.label ? creditsProductLabel(credits.label, messages) : creditsPeriodLabel(credits.periodType, messages),
28084
+ label: accountCreditsWindowLabel(
28085
+ credits,
28086
+ messages.locale,
28087
+ (period) => creditsPeriodLabel(period, messages)
28088
+ ),
27740
28089
  usedPercent: credits.usedPercent,
27741
28090
  amount: credits,
27742
28091
  resetsAt: credits.resetsAt,
27743
- scoped: Boolean(credits.label && scopedUsageProduct(credits.label))
28092
+ scoped: Boolean(credits.scope)
27744
28093
  };
27745
- const primaryScope = credits.label ? scopedUsageProduct(credits.label) : null;
27746
- addWindow(
27747
- primary,
27748
- primaryScope?.period ?? (credits.label ? null : comparisonPeriod(credits.periodType)),
27749
- primaryScope?.scope
27750
- );
28094
+ addWindow(primary, comparisonPeriod(credits.periodType), credits.scope);
27751
28095
  for (const product of credits.productUsage ?? []) {
27752
- const scoped = scopedUsageProduct(product.product);
27753
28096
  const window2 = {
27754
- label: creditsProductLabel(product.product, messages),
28097
+ label: accountCreditsWindowLabel(
28098
+ product,
28099
+ messages.locale,
28100
+ (period) => creditsPeriodLabel(period, messages)
28101
+ ),
27755
28102
  usedPercent: product.usagePercent,
27756
28103
  amount: product,
27757
28104
  resetsAt: product.resetsAt,
27758
- scoped: Boolean(scoped)
28105
+ scoped: Boolean(product.scope)
27759
28106
  };
27760
- const genericPeriod = product.product === "5-hour window" ? "five_hour" : product.product === "7-day window" ? "seven_day" : null;
27761
- addWindow(window2, scoped?.period ?? genericPeriod, scoped?.scope);
28107
+ addWindow(window2, comparisonPeriod(product.periodType ?? "unknown"), product.scope);
27762
28108
  }
27763
28109
  const structured = [...scopedRows.values()].flat();
27764
28110
  let rows = Object.keys(generic.columns).length > 0 ? [generic, ...structured] : structured;
@@ -28150,8 +28496,7 @@ ${error51.stderrTail}`] : []
28150
28496
  { status: "ready", credits: account.credits, freshness: "live", observedAt: null },
28151
28497
  messages,
28152
28498
  display,
28153
- () => void 0,
28154
- account.harnessId === "grok" ? "weekly-only" : "all"
28499
+ () => void 0
28155
28500
  ) : renderAccountBalance(document2, messages, account.balance);
28156
28501
  personCell.title = messages.accountNativeManagementHint.replace("{harness}", account.harnessName);
28157
28502
  appendAccountExtras(personCell, [importAction]);
@@ -29125,7 +29470,7 @@ ${error51.stderrTail}`] : []
29125
29470
  }
29126
29471
  });
29127
29472
  }
29128
- function createDefaultRendererSettingsPages(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null, getAccountClient = () => null, getSessionImportClient = () => null, openImportedThread = () => Promise.reject(new Error("Imported Thread navigation is unavailable")), getLoadedSessionsClient = () => null, getRemoteConnections = () => null, requestUsageStatistics = () => Promise.reject(new Error("Local Host connection is unavailable"))) {
29473
+ function createDefaultRendererSettingsPages(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null, getAccountClient = () => null, getSessionImportClient = () => null, openImportedThread = () => Promise.reject(new Error("Imported Thread navigation is unavailable")), getLoadedSessionsClient = () => null, getRemoteConnections = () => null, requestUsageStatistics = () => Promise.reject(new Error("Local Host connection is unavailable")), usageStatisticsHosts) {
29129
29474
  return Object.freeze([
29130
29475
  createConnectionsSettingsPage(messages, getDiagnostics, void 0, getRemoteConnections),
29131
29476
  createRemoteConnectionsPage(messages, getRemoteConnections),
@@ -29139,7 +29484,8 @@ ${error51.stderrTail}`] : []
29139
29484
  createUsageStatisticsPage(
29140
29485
  consoleMessages(messages.locale),
29141
29486
  requestUsageStatistics,
29142
- messages.locale
29487
+ messages.locale,
29488
+ usageStatisticsHosts
29143
29489
  ),
29144
29490
  createAppearanceSettingsPage(messages, getLoadedSessionsClient),
29145
29491
  updatesPage(messages, getUpdateClient),
@@ -29916,6 +30262,20 @@ ${error51.stderrTail}`] : []
29916
30262
  gap: 18px;
29917
30263
  }
29918
30264
 
30265
+ .settings-connections-content {
30266
+ container: settings-connections / inline-size;
30267
+ }
30268
+
30269
+ @container settings-connections (max-width: 780px) {
30270
+ .settings-connections-layout {
30271
+ grid-template-columns: minmax(0, 1fr);
30272
+ }
30273
+
30274
+ .settings-connection-inspector {
30275
+ position: static;
30276
+ }
30277
+ }
30278
+
29919
30279
  .settings-connection-list,
29920
30280
  .settings-connection-inspector {
29921
30281
  overflow: hidden;
@@ -29924,14 +30284,36 @@ ${error51.stderrTail}`] : []
29924
30284
  border-radius: 10px;
29925
30285
  }
29926
30286
 
30287
+ .settings-connection-host-header {
30288
+ display: flex;
30289
+ align-items: center;
30290
+ min-width: 0;
30291
+ border-bottom: 1px solid var(--settings-divider);
30292
+ }
30293
+
30294
+ .settings-connection-update-all {
30295
+ flex: none;
30296
+ margin-right: 10px;
30297
+ white-space: nowrap;
30298
+ }
30299
+
30300
+ .settings-connection-update-result {
30301
+ margin: 0;
30302
+ padding: 7px 10px;
30303
+ color: var(--settings-muted);
30304
+ font-size: 11px;
30305
+ line-height: 18px;
30306
+ border-bottom: 1px solid var(--settings-divider);
30307
+ }
30308
+
29927
30309
  .settings-connection-host-strip {
29928
30310
  display: grid;
30311
+ flex: 1;
29929
30312
  grid-template-columns: 30px minmax(0, 1fr) 30px;
29930
30313
  align-items: center;
29931
30314
  min-width: 0;
29932
30315
  gap: 5px;
29933
30316
  padding: 9px 10px;
29934
- border-bottom: 1px solid var(--settings-divider);
29935
30317
  }
29936
30318
 
29937
30319
  .settings-connection-host-scroll {
@@ -30028,7 +30410,7 @@ ${error51.stderrTail}`] : []
30028
30410
  .settings-connection-table-header,
30029
30411
  .settings-connection-row {
30030
30412
  display: grid;
30031
- grid-template-columns: minmax(160px, 1fr) minmax(92px, auto) 108px;
30413
+ grid-template-columns: minmax(160px, 1fr) minmax(92px, auto) minmax(108px, max-content);
30032
30414
  align-items: center;
30033
30415
  min-width: 0;
30034
30416
  gap: 10px;
@@ -30121,6 +30503,14 @@ ${error51.stderrTail}`] : []
30121
30503
  line-height: 18px;
30122
30504
  }
30123
30505
 
30506
+ .settings-connection-version-available {
30507
+ flex: none;
30508
+ color: var(--settings-muted);
30509
+ font-size: 10px;
30510
+ line-height: 16px;
30511
+ white-space: nowrap;
30512
+ }
30513
+
30124
30514
  .settings-connection-row__status::before {
30125
30515
  width: 6px;
30126
30516
  height: 6px;
@@ -30157,6 +30547,7 @@ ${error51.stderrTail}`] : []
30157
30547
  justify-content: flex-end;
30158
30548
  min-width: 0;
30159
30549
  gap: 4px;
30550
+ white-space: nowrap;
30160
30551
  }
30161
30552
 
30162
30553
  .settings-connection-row__handle {