@karlorz/codexhost-cli-win32-x64 0.13.3-6 → 0.13.3-7

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.
@@ -14941,6 +14941,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14941
14941
  "codexhost/harness/installation",
14942
14942
  "codexhost/harness/launch-settings/get",
14943
14943
  "codexhost/harness/launch-settings/set",
14944
+ "codexhost/harness/grok-computer-use/get",
14945
+ "codexhost/harness/grok-computer-use/set",
14944
14946
  "codexhost/harness/web-ui/open",
14945
14947
  "codexhost/harness/accounts/sources",
14946
14948
  "codexhost/harness/accounts/list",
@@ -15472,7 +15474,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15472
15474
  var harnessInspectParamsSchema = external_exports.object({
15473
15475
  harnessId: harnessIdSchema,
15474
15476
  cwd: nonBlankTextSchema2.max(16384).optional(),
15475
- refresh: external_exports.boolean().optional()
15477
+ refresh: external_exports.boolean().optional(),
15478
+ /** `availability` asks only whether the Harness can run; see `InspectHarnessInput.purpose`. */
15479
+ purpose: external_exports.literal("availability").optional()
15476
15480
  }).strict();
15477
15481
  var harnessWebUiOpenParamsSchema = external_exports.object({
15478
15482
  harnessId: harnessIdSchema
@@ -15648,6 +15652,28 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15648
15652
  restartRequired: external_exports.boolean()
15649
15653
  }).strict();
15650
15654
 
15655
+ // ../shared-contracts/dist/grok-computer-use.js
15656
+ var GROK_COMPUTER_USE_GET_METHOD = "codexhost/harness/grok-computer-use/get";
15657
+ var GROK_COMPUTER_USE_SET_METHOD = "codexhost/harness/grok-computer-use/set";
15658
+ var grokComputerUseGetSchema = external_exports.object({}).strict();
15659
+ var grokComputerUseSetSchema = external_exports.object({
15660
+ enabled: external_exports.boolean().optional(),
15661
+ browser: external_exports.boolean().optional()
15662
+ }).strict().refine((value) => value.enabled !== void 0 || value.browser !== void 0, {
15663
+ message: "Expected enabled or browser"
15664
+ });
15665
+ var grokComputerUseSettingsSchema = external_exports.object({
15666
+ enabled: external_exports.boolean(),
15667
+ available: external_exports.boolean(),
15668
+ unavailableReason: external_exports.string().min(1).max(500).optional(),
15669
+ browser: external_exports.boolean().optional(),
15670
+ browserFilesPresent: external_exports.boolean().optional(),
15671
+ browserAvailable: external_exports.boolean().optional(),
15672
+ browserUnavailableReason: external_exports.string().min(1).max(500).optional(),
15673
+ applyFailed: external_exports.boolean().optional(),
15674
+ applyError: external_exports.string().min(1).max(500).optional()
15675
+ }).strict();
15676
+
15651
15677
  // ../shared-contracts/dist/harness-installation.js
15652
15678
  var HARNESS_INSTALLATION_METHOD = "codexhost/harness/installation";
15653
15679
  var harnessInstallationParamsSchema = external_exports.object({
@@ -17089,6 +17115,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
17089
17115
  if (!client.setHarnessLaunchSettings) throw new Error("Launch settings are unavailable");
17090
17116
  return client.setHarnessLaunchSettings({ harnessId: harnessIdSchema.parse(agent), path });
17091
17117
  },
17118
+ async getGrokComputerUse() {
17119
+ if (!client.getGrokComputerUse) throw new Error("Grok Computer Use settings are unavailable");
17120
+ return client.getGrokComputerUse();
17121
+ },
17122
+ async setGrokComputerUse(_hostId, update) {
17123
+ if (!client.setGrokComputerUse) throw new Error("Grok Computer Use settings are unavailable");
17124
+ return client.setGrokComputerUse(update);
17125
+ },
17092
17126
  subscribe(listener) {
17093
17127
  listeners.add(listener);
17094
17128
  return () => listeners.delete(listener);
@@ -18376,6 +18410,13 @@ th[aria-sort] .console-usage-sort__mark {
18376
18410
  save: "Save",
18377
18411
  useAutomatic: "Use automatic",
18378
18412
  saved: "Saved",
18413
+ grokComputerUse: "Grok Computer Use",
18414
+ grokComputerUseHelp: "Lets Grok control Mac apps through ChatGPT\u2019s Computer Use helper. ChatGPT Settings \u2192 Computer use still applies only to official Codex. New Grok threads pick up this switch.",
18415
+ grokComputerUseUnavailable: "ChatGPT Desktop Computer Use files were not found.",
18416
+ grokBrowser: "Grok in-app browser",
18417
+ grokBrowserHelp: "Lets Grok use ChatGPT\u2019s built-in browser (Browser Use) through cua_repl. Independent of Computer Use; official Codex Browser Use is unchanged. Grok fails closed when the in-app tab cannot be bound.",
18418
+ grokBrowserUnavailable: "ChatGPT Desktop in-app browser files were not found.",
18419
+ grokBrowserBlocked: "Saved as intent. ChatGPT Desktop does not authorize Grok to use the in-app browser.",
18379
18420
  installGuide: "Install guide",
18380
18421
  noHarness: "No Harness plugins are installed.",
18381
18422
  consoleOffline: "The console is not running",
@@ -18565,6 +18606,13 @@ th[aria-sort] .console-usage-sort__mark {
18565
18606
  save: "\u4FDD\u5B58",
18566
18607
  useAutomatic: "\u6062\u590D\u81EA\u52A8\u67E5\u627E",
18567
18608
  saved: "\u5DF2\u4FDD\u5B58",
18609
+ grokComputerUse: "Grok Computer Use",
18610
+ grokComputerUseHelp: "\u8BA9 Grok \u901A\u8FC7 ChatGPT \u7684 Computer Use \u52A9\u624B\u63A7\u5236 Mac \u5E94\u7528\u3002ChatGPT \u8BBE\u7F6E \u2192 Computer use \u4ECD\u53EA\u4F5C\u7528\u4E8E\u5B98\u65B9 Codex\u3002\u65B0\u7684 Grok \u7EBF\u7A0B\u4F1A\u8BFB\u53D6\u6B64\u5F00\u5173\u3002",
18611
+ grokComputerUseUnavailable: "\u672A\u627E\u5230 ChatGPT Desktop \u7684 Computer Use \u6587\u4EF6\u3002",
18612
+ grokBrowser: "Grok \u5185\u7F6E\u6D4F\u89C8\u5668",
18613
+ grokBrowserHelp: "\u8BA9 Grok \u901A\u8FC7 cua_repl \u4F7F\u7528 ChatGPT \u5185\u7F6E\u6D4F\u89C8\u5668\uFF08Browser Use\uFF09\u3002\u4E0E Computer Use \u76F8\u4E92\u72EC\u7ACB\uFF0C\u5B98\u65B9 Codex Browser Use \u4E0D\u53D7\u5F71\u54CD\u3002\u65E0\u6CD5\u7ED1\u5B9A\u5185\u7F6E\u6807\u7B7E\u9875\u65F6 Grok \u4F1A\u76F4\u63A5\u5931\u8D25\u3002",
18614
+ grokBrowserUnavailable: "\u672A\u627E\u5230 ChatGPT Desktop \u7684\u5185\u7F6E\u6D4F\u89C8\u5668\u6587\u4EF6\u3002",
18615
+ grokBrowserBlocked: "\u5DF2\u4FDD\u5B58\u4E3A\u610F\u5411\u3002ChatGPT Desktop \u5C1A\u672A\u6388\u6743 Grok \u4F7F\u7528\u5185\u7F6E\u6D4F\u89C8\u5668\u3002",
18568
18616
  installGuide: "\u5B89\u88C5\u8BF4\u660E",
18569
18617
  noHarness: "\u6CA1\u6709\u5DF2\u5B89\u88C5\u7684 Harness \u63D2\u4EF6\u3002",
18570
18618
  consoleOffline: "\u63A7\u5236\u53F0\u672A\u8FD0\u884C",
@@ -18696,6 +18744,7 @@ th[aria-sort] .console-usage-sort__mark {
18696
18744
  const document2 = context.content.ownerDocument;
18697
18745
  const list = h(document2, "div", { className: "console-harness-list" });
18698
18746
  const status = /* @__PURE__ */ new Map();
18747
+ const busy = /* @__PURE__ */ new Set();
18699
18748
  let harnesses = [];
18700
18749
  const render = () => {
18701
18750
  if (harnesses.length === 0) {
@@ -18772,6 +18821,75 @@ th[aria-sort] .console-usage-sort__mark {
18772
18821
  );
18773
18822
  }
18774
18823
  }
18824
+ if (harness2.computerUse) {
18825
+ const computerUse = harness2.computerUse;
18826
+ const pending = busy.has(harness2.id);
18827
+ const post = (update) => {
18828
+ busy.add(harness2.id);
18829
+ toggle.disabled = true;
18830
+ browserToggle.disabled = true;
18831
+ void consolePost(
18832
+ "/api/harnesses/grok-computer-use",
18833
+ update
18834
+ ).then(({ harness: saved }) => {
18835
+ harnesses = harnesses.map((entry) => entry.id === saved.id ? saved : entry);
18836
+ status.set(harness2.id, messages.saved);
18837
+ }).catch(
18838
+ (error51) => status.set(harness2.id, error51 instanceof Error ? error51.message : String(error51))
18839
+ ).finally(() => {
18840
+ busy.delete(harness2.id);
18841
+ render();
18842
+ });
18843
+ };
18844
+ const toggle = h(document2, "input", {
18845
+ type: "checkbox",
18846
+ "aria-label": messages.grokComputerUse
18847
+ });
18848
+ toggle.checked = computerUse.enabled;
18849
+ toggle.disabled = pending || !computerUse.available && !computerUse.enabled;
18850
+ toggle.addEventListener("change", () => post({ enabled: toggle.checked }));
18851
+ const browserToggle = h(document2, "input", {
18852
+ type: "checkbox",
18853
+ "aria-label": messages.grokBrowser
18854
+ });
18855
+ browserToggle.checked = computerUse.browser === true;
18856
+ browserToggle.disabled = pending || computerUse.browserFilesPresent !== true && computerUse.browser !== true;
18857
+ browserToggle.addEventListener(
18858
+ "change",
18859
+ () => post({ browser: browserToggle.checked })
18860
+ );
18861
+ row.append(
18862
+ h(
18863
+ document2,
18864
+ "div",
18865
+ { className: "console-harness__path" },
18866
+ h(document2, "label", {}, toggle, ` ${messages.grokComputerUse}`)
18867
+ ),
18868
+ h(
18869
+ document2,
18870
+ "div",
18871
+ { className: "console-muted" },
18872
+ harness2.computerUse.available ? messages.grokComputerUseHelp : computerUse.unavailableReason ?? messages.grokComputerUseUnavailable
18873
+ ),
18874
+ h(
18875
+ document2,
18876
+ "div",
18877
+ { className: "console-harness__path" },
18878
+ h(document2, "label", {}, browserToggle, ` ${messages.grokBrowser}`)
18879
+ ),
18880
+ h(
18881
+ document2,
18882
+ "div",
18883
+ { className: "console-muted" },
18884
+ computerUse.browserAvailable === true ? messages.grokBrowserHelp : computerUse.browserFilesPresent === true ? computerUse.browserUnavailableReason ?? messages.grokBrowserBlocked : computerUse.browserUnavailableReason ?? messages.grokBrowserUnavailable
18885
+ )
18886
+ );
18887
+ if (status.has(harness2.id)) {
18888
+ row.append(
18889
+ h(document2, "div", { className: "console-muted" }, status.get(harness2.id) ?? "")
18890
+ );
18891
+ }
18892
+ }
18775
18893
  if (guide) {
18776
18894
  identity.append(
18777
18895
  h(
@@ -18916,6 +19034,13 @@ th[aria-sort] .console-usage-sort__mark {
18916
19034
  });
18917
19035
  }
18918
19036
 
19037
+ // src/renderer-cpa-live-voice-preference.ts
19038
+ var voiceStateOwner = globalThis;
19039
+ var { sharedRoutes, gatewayReady } = voiceStateOwner.__codexhostVoicePreferenceStateV1 ??= {
19040
+ sharedRoutes: /* @__PURE__ */ new WeakMap(),
19041
+ gatewayReady: /* @__PURE__ */ new WeakMap()
19042
+ };
19043
+
18919
19044
  // src/voice-settings-sync.ts
18920
19045
  function desktopVoiceCallActive(owner) {
18921
19046
  const hook = Reflect.get(owner, "__codexhostNativeChatVoiceV1");
@@ -19046,6 +19171,15 @@ th[aria-sort] .console-usage-sort__mark {
19046
19171
  configured: "Configured",
19047
19172
  needsSetup: "Needs setup",
19048
19173
  unknown: "Not checked",
19174
+ gatewayStatus: "Gateway configuration",
19175
+ preferencesStatus: "Preferences applied",
19176
+ hookStatus: "Desktop gateway voice integration",
19177
+ preferencesOn: "Applied",
19178
+ preferencesOff: "Not applied yet",
19179
+ hookSupported: "Supported",
19180
+ hookUnsupported: "This Desktop build is not supported for gateway voice",
19181
+ hookPending: "Attaching\u2026",
19182
+ hookDisabled: "Off",
19049
19183
  configure: "Configure",
19050
19184
  setup: "Gateway setup",
19051
19185
  setupHint: "Gateway settings use your local Codex configuration and the selected provider\u2019s credential. End voice before editing configuration. Never paste credentials here.",
@@ -19096,6 +19230,15 @@ th[aria-sort] .console-usage-sort__mark {
19096
19230
  configured: "\u5DF2\u914D\u7F6E",
19097
19231
  needsSetup: "\u9700\u8981\u914D\u7F6E",
19098
19232
  unknown: "\u672A\u68C0\u67E5",
19233
+ gatewayStatus: "\u7F51\u5173\u914D\u7F6E",
19234
+ preferencesStatus: "\u504F\u597D\u662F\u5426\u5DF2\u5E94\u7528",
19235
+ hookStatus: "Desktop \u7F51\u5173\u8BED\u97F3\u96C6\u6210",
19236
+ preferencesOn: "\u5DF2\u5E94\u7528",
19237
+ preferencesOff: "\u5C1A\u672A\u5E94\u7528",
19238
+ hookSupported: "\u652F\u6301",
19239
+ hookUnsupported: "\u5F53\u524D Desktop \u7248\u672C\u4E0D\u652F\u6301\u7F51\u5173\u8BED\u97F3",
19240
+ hookPending: "\u6B63\u5728\u63A5\u5165\u2026",
19241
+ hookDisabled: "\u5DF2\u5173\u95ED",
19099
19242
  configure: "\u914D\u7F6E",
19100
19243
  setup: "\u7F51\u5173\u914D\u7F6E",
19101
19244
  setupHint: "\u7F51\u5173\u4F7F\u7528\u672C\u5730 Codex \u914D\u7F6E\u53CA\u6240\u9009 Provider \u7684\u51ED\u636E\u3002\u7F16\u8F91\u524D\u8BF7\u7ED3\u675F\u8BED\u97F3\u3002\u8BF7\u52FF\u5728\u6B64\u7C98\u8D34\u51ED\u636E\u3002",
@@ -19295,20 +19438,30 @@ th[aria-sort] .console-usage-sort__mark {
19295
19438
  });
19296
19439
  configure.id = gateway.item.querySelector("label")?.htmlFor ?? "";
19297
19440
  configure.setAttribute("aria-expanded", String(setup));
19441
+ const gatewayReadyLabel = state.gatewayReady === null ? m.unknown : state.gatewayReady ? m.configured : m.needsSetup;
19298
19442
  const gatewayActions = h(
19299
19443
  doc,
19300
19444
  "div",
19301
19445
  { className: "settings-voice__gateway-actions" },
19446
+ h(doc, "span", {}, gatewayReadyLabel),
19447
+ configure
19448
+ );
19449
+ gateway.item.append(gatewayActions);
19450
+ config2.card.append(gateway.item);
19451
+ const hook = options.desktop ? desktopVoiceHookStatus(doc.defaultView) : "unknown";
19452
+ const hookLabel = hook === "active" ? m.hookSupported : hook === "pending" ? m.hookPending : hook === "unsupported" ? m.hookUnsupported : hook === "disabled" ? m.hookDisabled : m.unknown;
19453
+ const health = h(doc, "div", { className: "settings-voice__health" });
19454
+ health.append(
19455
+ h(doc, "p", {}, `${m.gatewayStatus}: ${gatewayReadyLabel}`),
19302
19456
  h(
19303
19457
  doc,
19304
- "span",
19458
+ "p",
19305
19459
  {},
19306
- state.gatewayReady === null ? m.unknown : state.gatewayReady ? m.configured : m.needsSetup
19460
+ `${m.preferencesStatus}: ${state.routesActive === true ? m.preferencesOn : state.routesActive === false ? m.preferencesOff : m.unknown}`
19307
19461
  ),
19308
- configure
19462
+ h(doc, "p", {}, `${m.hookStatus}: ${hookLabel}`)
19309
19463
  );
19310
- gateway.item.append(gatewayActions);
19311
- config2.card.append(gateway.item);
19464
+ config2.card.append(health);
19312
19465
  if (setup) {
19313
19466
  const details = h(
19314
19467
  doc,
@@ -19438,6 +19591,15 @@ th[aria-sort] .console-usage-sort__mark {
19438
19591
  }
19439
19592
  });
19440
19593
  }
19594
+ function desktopVoiceHookStatus(win) {
19595
+ if (!win) return "unknown";
19596
+ const value = win.__codexhostClientOwnedVoiceV1;
19597
+ if (!value || typeof value !== "object") return "unknown";
19598
+ const status = value.status;
19599
+ if (status === "active" || status === "pending" || status === "unsupported" || status === "disabled")
19600
+ return status;
19601
+ return "unknown";
19602
+ }
19441
19603
 
19442
19604
  // src/console/pages/restart-control.ts
19443
19605
  function renderRestartControl(document2, messages, state) {
@@ -20068,7 +20230,15 @@ th[aria-sort] .console-usage-sort__mark {
20068
20230
  };
20069
20231
  const inspectHarness = async (input, options) => {
20070
20232
  const params = harnessInspectParamsSchema.parse(input);
20071
- const result = await manager.sendRequest(HARNESS_INSPECT_METHOD, params, options);
20233
+ let result;
20234
+ try {
20235
+ result = await manager.sendRequest(HARNESS_INSPECT_METHOD, params, options);
20236
+ } catch (error51) {
20237
+ if (!params.purpose || !isInvalidParams(error51)) throw error51;
20238
+ const full = { ...params };
20239
+ delete full.purpose;
20240
+ result = await manager.sendRequest(HARNESS_INSPECT_METHOD, full, options);
20241
+ }
20072
20242
  return harnessInspectionSchema.parse(result);
20073
20243
  };
20074
20244
  const inspectHarnessCommands = async (input) => {
@@ -20142,6 +20312,19 @@ th[aria-sort] .console-usage-sort__mark {
20142
20312
  )
20143
20313
  );
20144
20314
  },
20315
+ async getGrokComputerUse() {
20316
+ return grokComputerUseSettingsSchema.parse(
20317
+ await manager.sendRequest(GROK_COMPUTER_USE_GET_METHOD, {})
20318
+ );
20319
+ },
20320
+ async setGrokComputerUse(update) {
20321
+ return grokComputerUseSettingsSchema.parse(
20322
+ await manager.sendRequest(
20323
+ GROK_COMPUTER_USE_SET_METHOD,
20324
+ grokComputerUseSetSchema.parse(update)
20325
+ )
20326
+ );
20327
+ },
20145
20328
  async listLoadedSessions() {
20146
20329
  return loadedSessionsSchema.parse(await manager.sendRequest(LOADED_SESSIONS_METHOD, {}));
20147
20330
  },
@@ -20330,6 +20513,9 @@ th[aria-sort] .console-usage-sort__mark {
20330
20513
  }
20331
20514
  });
20332
20515
  }
20516
+ function isInvalidParams(error51) {
20517
+ return typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === -32602;
20518
+ }
20333
20519
 
20334
20520
  // src/settings/accounts.css
20335
20521
  var accounts_default = `.settings-harness-account__logo {
@@ -21505,6 +21691,26 @@ th[aria-sort] .console-usage-sort__mark {
21505
21691
  launchPathLoading: "Loading launch settings\u2026",
21506
21692
  launchPathLoadError: "Could not load launch settings. Reopen this detail panel to retry.",
21507
21693
  launchPathSaveError: "Could not save. Enter an existing absolute installation folder on this Host and check configuration permissions.",
21694
+ grokComputerUseLabel: "Grok Computer Use",
21695
+ grokComputerUseTitle: "Computer Use",
21696
+ grokComputerUseDescription: "Let Grok control Mac apps via ChatGPT Computer Use (cua_repl).",
21697
+ grokComputerUseHelp: "ChatGPT Settings \u2192 Computer use still applies to official Codex threads. Always-allowed apps stay in that list. New Grok threads pick up this switch.",
21698
+ grokComputerUseOn: "On \xB7 available",
21699
+ grokComputerUseOff: "Off",
21700
+ grokComputerUseSaving: "Saving\u2026",
21701
+ grokComputerUseLoading: "Loading Grok Computer Use\u2026",
21702
+ grokComputerUseLoadError: "Could not load Grok Computer Use. Reopen this panel to retry.",
21703
+ grokComputerUseSaveError: "Could not save. Install ChatGPT.app with Computer Use, then try again.",
21704
+ grokComputerUseUnavailable: "ChatGPT Desktop Computer Use files were not found on this Mac.",
21705
+ grokBrowserLabel: "Grok in-app browser",
21706
+ grokBrowserTitle: "In-app browser",
21707
+ grokBrowserDescription: "Let Grok use ChatGPT's built-in browser (Browser Use) through cua_repl. Independent of Computer Use.",
21708
+ grokBrowserHelp: "Official Codex Browser Use is unchanged. Grok fails closed when ChatGPT does not authorize the connection or no in-app browser tab can be bound. The Chrome extension is a separate path.",
21709
+ grokBrowserOn: "On \xB7 browser surface enabled",
21710
+ grokBrowserOff: "Off",
21711
+ grokBrowserUnavailable: "ChatGPT Desktop in-app browser files were not found on this Mac.",
21712
+ grokBrowserBlocked: "Saved as intent. ChatGPT Desktop does not authorize Grok to use the in-app browser.",
21713
+ grokComputerUseApplyFailed: "Could not apply the saved setting to Grok config.",
21508
21714
  connectionOfficialWebsite: "Visit official website",
21509
21715
  connectionOpenHarnessWeb: "Open DeepSeek Harness Web",
21510
21716
  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.",
@@ -21516,6 +21722,7 @@ th[aria-sort] .console-usage-sort__mark {
21516
21722
  harnessVersionCurrent: "Current version",
21517
21723
  harnessVersionLatest: "Latest version",
21518
21724
  harnessVersionChecking: "Checking versions\u2026",
21725
+ harnessVersionAvailable: "Update available",
21519
21726
  harnessVersionUpdate: "Update",
21520
21727
  harnessVersionUpdating: "Updating\u2026",
21521
21728
  harnessVersionUpToDate: "Up to date",
@@ -21787,6 +21994,26 @@ th[aria-sort] .console-usage-sort__mark {
21787
21994
  launchPathLoading: "\u6B63\u5728\u8BFB\u53D6\u542F\u52A8\u8BBE\u7F6E\u2026",
21788
21995
  launchPathLoadError: "\u65E0\u6CD5\u8BFB\u53D6\u542F\u52A8\u8BBE\u7F6E\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u6B64\u8BE6\u60C5\u9762\u677F\u91CD\u8BD5\u3002",
21789
21996
  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",
21997
+ grokComputerUseLabel: "Grok Computer Use",
21998
+ grokComputerUseTitle: "Computer Use",
21999
+ grokComputerUseDescription: "\u8BA9 Grok \u901A\u8FC7 ChatGPT Computer Use\uFF08cua_repl\uFF09\u63A7\u5236 Mac \u5E94\u7528\u3002",
22000
+ grokComputerUseHelp: "ChatGPT \u8BBE\u7F6E \u2192 Computer use \u4ECD\u53EA\u4F5C\u7528\u4E8E\u5B98\u65B9 Codex \u7EBF\u7A0B\u3002Always-allowed \u5E94\u7528\u4ECD\u4FDD\u5B58\u5728\u8BE5\u5217\u8868\u3002\u65B0\u7684 Grok \u7EBF\u7A0B\u4F1A\u8BFB\u53D6\u6B64\u5F00\u5173\u3002",
22001
+ grokComputerUseOn: "\u5DF2\u5F00\u542F \xB7 \u53EF\u7528",
22002
+ grokComputerUseOff: "\u5DF2\u5173\u95ED",
22003
+ grokComputerUseSaving: "\u6B63\u5728\u4FDD\u5B58\u2026",
22004
+ grokComputerUseLoading: "\u6B63\u5728\u8BFB\u53D6 Grok Computer Use\u2026",
22005
+ grokComputerUseLoadError: "\u65E0\u6CD5\u8BFB\u53D6 Grok Computer Use\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u6B64\u9762\u677F\u91CD\u8BD5\u3002",
22006
+ grokComputerUseSaveError: "\u4FDD\u5B58\u5931\u8D25\u3002\u8BF7\u5148\u5B89\u88C5\u5E26 Computer Use \u7684 ChatGPT.app\u3002",
22007
+ grokComputerUseUnavailable: "\u672C\u673A\u672A\u627E\u5230 ChatGPT Desktop \u7684 Computer Use \u6587\u4EF6\u3002",
22008
+ grokBrowserLabel: "Grok \u5185\u7F6E\u6D4F\u89C8\u5668",
22009
+ grokBrowserTitle: "\u5185\u7F6E\u6D4F\u89C8\u5668",
22010
+ grokBrowserDescription: "\u8BA9 Grok \u901A\u8FC7 cua_repl \u4F7F\u7528 ChatGPT \u5185\u7F6E\u6D4F\u89C8\u5668\uFF08Browser Use\uFF09\u3002\u4E0E Computer Use \u76F8\u4E92\u72EC\u7ACB\u3002",
22011
+ grokBrowserHelp: "\u5B98\u65B9 Codex Browser Use \u4E0D\u53D7\u5F71\u54CD\u3002ChatGPT \u4E0D\u6388\u6743\u8FDE\u63A5\u6216\u65E0\u6CD5\u7ED1\u5B9A\u5185\u7F6E\u6D4F\u89C8\u5668\u6807\u7B7E\u9875\u65F6\uFF0CGrok \u4F1A\u76F4\u63A5\u5931\u8D25\u3002Chrome \u6269\u5C55\u662F\u53E6\u4E00\u6761\u8DEF\u5F84\u3002",
22012
+ grokBrowserOn: "\u5DF2\u5F00\u542F \xB7 \u6D4F\u89C8\u5668\u80FD\u529B\u5DF2\u542F\u7528",
22013
+ grokBrowserOff: "\u5DF2\u5173\u95ED",
22014
+ grokBrowserUnavailable: "\u672C\u673A\u672A\u627E\u5230 ChatGPT Desktop \u7684\u5185\u7F6E\u6D4F\u89C8\u5668\u6587\u4EF6\u3002",
22015
+ grokBrowserBlocked: "\u5DF2\u4FDD\u5B58\u4E3A\u610F\u5411\u3002ChatGPT Desktop \u5C1A\u672A\u6388\u6743 Grok \u4F7F\u7528\u5185\u7F6E\u6D4F\u89C8\u5668\u3002",
22016
+ grokComputerUseApplyFailed: "\u65E0\u6CD5\u5C06\u5DF2\u4FDD\u5B58\u7684\u8BBE\u7F6E\u5199\u5165 Grok \u914D\u7F6E\u3002",
21790
22017
  connectionOfficialWebsite: "\u8BBF\u95EE\u5B98\u7F51",
21791
22018
  connectionOpenHarnessWeb: "\u6253\u5F00 DeepSeek Harness Web",
21792
22019
  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",
@@ -21798,6 +22025,7 @@ th[aria-sort] .console-usage-sort__mark {
21798
22025
  harnessVersionCurrent: "\u5F53\u524D\u7248\u672C",
21799
22026
  harnessVersionLatest: "\u6700\u65B0\u7248\u672C",
21800
22027
  harnessVersionChecking: "\u6B63\u5728\u68C0\u67E5\u7248\u672C\u2026",
22028
+ harnessVersionAvailable: "\u6709\u65B0\u7248\u672C",
21801
22029
  harnessVersionUpdate: "\u66F4\u65B0",
21802
22030
  harnessVersionUpdating: "\u6B63\u5728\u66F4\u65B0\u2026",
21803
22031
  harnessVersionUpToDate: "\u5DF2\u662F\u6700\u65B0",
@@ -25512,6 +25740,144 @@ ${detail}` : ""}`
25512
25740
  return section;
25513
25741
  }
25514
25742
 
25743
+ // src/settings/grok-computer-use-controls.ts
25744
+ function createGrokComputerUseControls(document2, messages, settings) {
25745
+ const section = document2.createElement("section");
25746
+ section.className = "settings-grok-computer-use";
25747
+ section.dataset.grokComputerUse = "true";
25748
+ const header = document2.createElement("div");
25749
+ header.className = "settings-grok-computer-use__header";
25750
+ const copy = document2.createElement("div");
25751
+ copy.className = "settings-grok-computer-use__copy";
25752
+ const title = document2.createElement("h3");
25753
+ title.className = "settings-grok-computer-use__title";
25754
+ title.id = "grok-computer-use-title";
25755
+ title.textContent = messages.grokComputerUseTitle;
25756
+ const description = document2.createElement("p");
25757
+ description.className = "settings-grok-computer-use__description";
25758
+ description.id = "grok-computer-use-description";
25759
+ description.textContent = messages.grokComputerUseDescription;
25760
+ copy.append(title, description);
25761
+ const input = createPreferenceSwitch(
25762
+ document2,
25763
+ "grok-computer-use-enabled",
25764
+ "grok-computer-use-description grok-computer-use-help grok-computer-use-status"
25765
+ );
25766
+ input.setAttribute("aria-labelledby", title.id);
25767
+ input.setAttribute("aria-label", messages.grokComputerUseLabel);
25768
+ header.append(copy, input);
25769
+ const help = document2.createElement("p");
25770
+ help.className = "settings-grok-computer-use__help";
25771
+ help.id = "grok-computer-use-help";
25772
+ help.textContent = messages.grokComputerUseHelp;
25773
+ const status = document2.createElement("p");
25774
+ status.className = "settings-grok-computer-use__status";
25775
+ status.id = "grok-computer-use-status";
25776
+ status.setAttribute("role", "status");
25777
+ status.setAttribute("aria-live", "polite");
25778
+ const browserHeader = document2.createElement("div");
25779
+ browserHeader.className = "settings-grok-computer-use__header settings-grok-computer-use__browser";
25780
+ const browserCopy = document2.createElement("div");
25781
+ browserCopy.className = "settings-grok-computer-use__copy";
25782
+ const browserTitle = document2.createElement("h3");
25783
+ browserTitle.className = "settings-grok-computer-use__title";
25784
+ browserTitle.id = "grok-browser-title";
25785
+ browserTitle.textContent = messages.grokBrowserTitle;
25786
+ const browserDescription = document2.createElement("p");
25787
+ browserDescription.className = "settings-grok-computer-use__description";
25788
+ browserDescription.id = "grok-browser-description";
25789
+ browserDescription.textContent = messages.grokBrowserDescription;
25790
+ browserCopy.append(browserTitle, browserDescription);
25791
+ const browserInput = createPreferenceSwitch(
25792
+ document2,
25793
+ "grok-browser-enabled",
25794
+ "grok-browser-description grok-browser-help grok-browser-status"
25795
+ );
25796
+ browserInput.setAttribute("aria-labelledby", browserTitle.id);
25797
+ browserInput.setAttribute("aria-label", messages.grokBrowserLabel);
25798
+ browserHeader.append(browserCopy, browserInput);
25799
+ const browserHelp = document2.createElement("p");
25800
+ browserHelp.className = "settings-grok-computer-use__help";
25801
+ browserHelp.id = "grok-browser-help";
25802
+ browserHelp.textContent = messages.grokBrowserHelp;
25803
+ const browserStatus = document2.createElement("p");
25804
+ browserStatus.className = "settings-grok-computer-use__status";
25805
+ browserStatus.id = "grok-browser-status";
25806
+ browserStatus.setAttribute("role", "status");
25807
+ browserStatus.setAttribute("aria-live", "polite");
25808
+ section.append(header, help, status, browserHeader, browserHelp, browserStatus);
25809
+ let busy = true;
25810
+ let loaded = false;
25811
+ let last;
25812
+ const show = (value) => {
25813
+ last = value;
25814
+ input.checked = value.enabled;
25815
+ input.disabled = busy || !loaded || !value.available && !value.enabled;
25816
+ const browserOn = value.browser === true;
25817
+ const browserFiles = value.browserFilesPresent === true;
25818
+ browserInput.checked = browserOn;
25819
+ browserInput.disabled = busy || !loaded || !browserFiles && !browserOn;
25820
+ if (!browserFiles) {
25821
+ browserStatus.dataset.state = "unavailable";
25822
+ browserStatus.textContent = value.browserUnavailableReason ?? messages.grokBrowserUnavailable;
25823
+ } else if (value.browserAvailable !== true) {
25824
+ browserStatus.dataset.state = browserOn ? "unavailable" : "off";
25825
+ browserStatus.textContent = browserOn ? value.browserUnavailableReason ?? messages.grokBrowserBlocked : messages.grokBrowserOff;
25826
+ } else {
25827
+ browserStatus.dataset.state = browserOn ? "on" : "off";
25828
+ browserStatus.textContent = browserOn ? messages.grokBrowserOn : messages.grokBrowserOff;
25829
+ }
25830
+ if (value.applyFailed) {
25831
+ status.dataset.state = "unavailable";
25832
+ status.textContent = value.applyError ?? messages.grokComputerUseApplyFailed;
25833
+ return;
25834
+ }
25835
+ if (!value.available) {
25836
+ status.dataset.state = "unavailable";
25837
+ status.textContent = value.unavailableReason ?? messages.grokComputerUseUnavailable;
25838
+ return;
25839
+ }
25840
+ status.dataset.state = value.enabled ? "on" : "off";
25841
+ status.textContent = value.enabled ? messages.grokComputerUseOn : messages.grokComputerUseOff;
25842
+ };
25843
+ const save = (update, target) => {
25844
+ if (busy || !loaded) return;
25845
+ busy = true;
25846
+ input.disabled = true;
25847
+ browserInput.disabled = true;
25848
+ target.textContent = messages.grokComputerUseSaving;
25849
+ void settings.set(update).then((value) => {
25850
+ busy = false;
25851
+ show(value);
25852
+ }).catch(() => {
25853
+ busy = false;
25854
+ if (last) show(last);
25855
+ else {
25856
+ input.disabled = false;
25857
+ browserInput.disabled = false;
25858
+ }
25859
+ target.textContent = messages.grokComputerUseSaveError;
25860
+ });
25861
+ };
25862
+ input.addEventListener("change", () => save({ enabled: input.checked }, status));
25863
+ browserInput.addEventListener(
25864
+ "change",
25865
+ () => save({ browser: browserInput.checked }, browserStatus)
25866
+ );
25867
+ status.textContent = messages.grokComputerUseLoading;
25868
+ browserStatus.textContent = messages.grokBrowserOff;
25869
+ void settings.get().then((value) => {
25870
+ loaded = true;
25871
+ busy = false;
25872
+ show(value);
25873
+ }).catch(() => {
25874
+ busy = false;
25875
+ status.textContent = messages.grokComputerUseLoadError;
25876
+ browserStatus.textContent = messages.grokComputerUseLoadError;
25877
+ });
25878
+ return section;
25879
+ }
25880
+
25515
25881
  // src/settings/harness-installation-guides.ts
25516
25882
  function harnessHasInstallCommands(plugin) {
25517
25883
  return (plugin?.installation?.commands.length ?? 0) > 0;
@@ -25663,7 +26029,7 @@ ${detail}` : ""}`
25663
26029
  }
25664
26030
 
25665
26031
  // src/settings/harness-version-panel.ts
25666
- function createHarnessVersionPanel(document2, messages, signal, agent, client) {
26032
+ function createHarnessVersionPanel(document2, messages, signal, agent, client, onChange = () => void 0) {
25667
26033
  const panel = document2.createElement("section");
25668
26034
  panel.className = "settings-harness-version";
25669
26035
  panel.dataset.harnessVersion = agent;
@@ -25689,6 +26055,7 @@ ${detail}` : ""}`
25689
26055
  panel.append(heading, versions, status, actions, note);
25690
26056
  let state;
25691
26057
  let busy = false;
26058
+ let updating = false;
25692
26059
  let unsupported = false;
25693
26060
  const render = () => {
25694
26061
  current.textContent = `${messages.harnessVersionCurrent}: ${state?.currentVersion ?? "\u2014"}`;
@@ -25702,6 +26069,8 @@ ${detail}` : ""}`
25702
26069
  if (busy || unsupported || signal.aborted) return;
25703
26070
  if (action === "update" && (!state?.canUpdate || !state.updateAvailable)) return;
25704
26071
  busy = true;
26072
+ updating = action === "update";
26073
+ onChange();
25705
26074
  status.textContent = action === "check" ? messages.harnessVersionChecking : messages.harnessVersionUpdating;
25706
26075
  render();
25707
26076
  try {
@@ -25716,7 +26085,11 @@ ${detail}` : ""}`
25716
26085
  if (state) state = { ...state, canUpdate: false };
25717
26086
  } finally {
25718
26087
  busy = false;
25719
- if (!signal.aborted) render();
26088
+ updating = false;
26089
+ if (!signal.aborted) {
26090
+ render();
26091
+ onChange();
26092
+ }
25720
26093
  }
25721
26094
  };
25722
26095
  update.addEventListener("click", () => void run("update"));
@@ -25746,7 +26119,43 @@ ${detail}` : ""}`
25746
26119
  } else {
25747
26120
  void run("check");
25748
26121
  }
25749
- return panel;
26122
+ return {
26123
+ element: panel,
26124
+ get state() {
26125
+ return state;
26126
+ },
26127
+ get updating() {
26128
+ return updating;
26129
+ },
26130
+ update: () => void run("update")
26131
+ };
26132
+ }
26133
+
26134
+ // src/settings/connection-versions.ts
26135
+ function createConnectionVersions(document2, messages, signal, diagnostics, onChange) {
26136
+ const panels = /* @__PURE__ */ new Map();
26137
+ const installation = diagnostics?.installation?.bind(diagnostics);
26138
+ return {
26139
+ get(hostId2, agent) {
26140
+ if (!installation || signal.aborted) return void 0;
26141
+ const key = JSON.stringify([hostId2, agent]);
26142
+ let panel = panels.get(key);
26143
+ if (!panel) {
26144
+ panel = createHarnessVersionPanel(
26145
+ document2,
26146
+ messages,
26147
+ signal,
26148
+ agent,
26149
+ {
26150
+ run: (action) => installation(hostId2, agent, action)
26151
+ },
26152
+ onChange
26153
+ );
26154
+ panels.set(key, panel);
26155
+ }
26156
+ return panel;
26157
+ }
26158
+ };
25750
26159
  }
25751
26160
 
25752
26161
  // src/settings/connections-page.ts
@@ -25914,6 +26323,14 @@ ${error51.stderrTail}`] : []
25914
26323
  status.dataset.connectionTone = connectionStatusTone(item.availability, item.error !== null);
25915
26324
  status.setAttribute("role", "cell");
25916
26325
  status.textContent = item.error?.code === "authenticationRequired" ? messages.connectionLoginRequired : item.error?.code === "configurationRequired" ? messages.connectionConfigurationRequired : connectionStatusLabel(item.availability, messages, item.error !== null);
26326
+ const version2 = item.version;
26327
+ if (version2?.state?.updateAvailable && !version2.updating) {
26328
+ const available = document2.createElement("span");
26329
+ available.className = "settings-connection-version-available";
26330
+ available.textContent = `${messages.harnessVersionAvailable}: ${harnessVersionLabel(version2.state, messages.harnessVersion)}`;
26331
+ available.title = `${messages.harnessVersionCurrent}: ${version2.state.currentVersion ?? "\u2014"}`;
26332
+ status.append(available);
26333
+ }
25917
26334
  const action = document2.createElement("div");
25918
26335
  action.className = "settings-connection-row__action";
25919
26336
  action.setAttribute("role", "cell");
@@ -25943,6 +26360,23 @@ ${error51.stderrTail}`] : []
25943
26360
  });
25944
26361
  action.append(viewError);
25945
26362
  }
26363
+ if (version2?.state?.updateAvailable && version2.state.canUpdate) {
26364
+ const update = document2.createElement("button");
26365
+ update.type = "button";
26366
+ update.className = "settings-connection-install-link";
26367
+ update.dataset.connectionAction = "update";
26368
+ update.disabled = version2.updating;
26369
+ update.title = messages.harnessVersionUpdate;
26370
+ update.setAttribute("aria-label", `${messages.harnessVersionUpdate}: ${item.name}`);
26371
+ update.append(createRendererSettingsIcon("download", 17));
26372
+ update.addEventListener("click", (event) => {
26373
+ event.stopPropagation();
26374
+ if (update.disabled) return;
26375
+ version2.update();
26376
+ select();
26377
+ });
26378
+ action.append(update);
26379
+ }
25946
26380
  if (group) {
25947
26381
  const toggle = document2.createElement("button");
25948
26382
  toggle.type = "button";
@@ -26140,6 +26574,16 @@ ${error51.stderrTail}`] : []
26140
26574
  });
26141
26575
  body.append(launchControls);
26142
26576
  }
26577
+ const getGrokComputerUse = diagnostics?.getGrokComputerUse?.bind(diagnostics);
26578
+ const setGrokComputerUse = diagnostics?.setGrokComputerUse?.bind(diagnostics);
26579
+ if (hostId2 === "local" && agent === "grok" && getGrokComputerUse && setGrokComputerUse) {
26580
+ body.append(
26581
+ createGrokComputerUseControls(document2, messages, {
26582
+ get: () => getGrokComputerUse(hostId2),
26583
+ set: (update) => setGrokComputerUse(hostId2, update)
26584
+ })
26585
+ );
26586
+ }
26143
26587
  inspector.append(body);
26144
26588
  return launchControls;
26145
26589
  }
@@ -26231,8 +26675,6 @@ ${error51.stderrTail}`] : []
26231
26675
  let selectedHostId = null;
26232
26676
  let selectedItemKey = null;
26233
26677
  let launchControls = null;
26234
- const versionPanels = /* @__PURE__ */ new Map();
26235
- const updatingVersions = /* @__PURE__ */ new Set();
26236
26678
  const hostNames = /* @__PURE__ */ new Map();
26237
26679
  let latestSnapshot = null;
26238
26680
  let disposeHostScroller = () => void 0;
@@ -26261,6 +26703,13 @@ ${error51.stderrTail}`] : []
26261
26703
  renderFrame = null;
26262
26704
  };
26263
26705
  const diagnostics = getDiagnostics();
26706
+ const versions = createConnectionVersions(
26707
+ document2,
26708
+ messages,
26709
+ context.signal,
26710
+ diagnostics,
26711
+ scheduleRender
26712
+ );
26264
26713
  const installs = diagnostics ? harnessInstallStore(diagnostics) : null;
26265
26714
  const runRefresh = () => {
26266
26715
  if (pending || !diagnostics) return;
@@ -26397,10 +26846,13 @@ ${error51.stderrTail}`] : []
26397
26846
  const agent = item.agentSnapshot?.agent;
26398
26847
  if (!agent) return item;
26399
26848
  const state = installs?.get(selectedHost.hostId, agent);
26849
+ const availability = state?.status ?? item.availability;
26850
+ const version2 = item.agentSnapshot?.availability !== "notInstalled" && availability !== "installing" && availability !== "checking" ? versions.get(selectedHost.hostId, agent) : void 0;
26400
26851
  return {
26401
26852
  ...item,
26402
26853
  ...state ? { availability: state.status } : {},
26403
- ...updatingVersions.has(JSON.stringify([selectedHost.hostId, agent])) ? { availability: "updating" } : {},
26854
+ ...version2 ? { version: version2 } : {},
26855
+ ...version2?.updating ? { availability: "updating" } : {},
26404
26856
  ...state?.error ? { installError: state.error } : {},
26405
26857
  ...diagnostics?.installation && harnessHasInstallCommands(item.agentSnapshot?.plugin) ? {
26406
26858
  install: () => {
@@ -26437,30 +26889,7 @@ ${error51.stderrTail}`] : []
26437
26889
  runRefresh
26438
26890
  );
26439
26891
  launchControls = { hostId: selectedHost.hostId, itemKey: item.key, element };
26440
- const agent = item.agentSnapshot?.agent;
26441
- const installation = diagnostics?.installation?.bind(diagnostics);
26442
- if (agent && item.agentSnapshot?.availability !== "notInstalled" && item.availability !== "installing" && item.availability !== "checking" && installation) {
26443
- const key = JSON.stringify([selectedHost.hostId, agent]);
26444
- let panel = versionPanels.get(key);
26445
- if (!panel) {
26446
- const hostId2 = selectedHost.hostId;
26447
- panel = createHarnessVersionPanel(document2, messages, context.signal, agent, {
26448
- async run(action) {
26449
- if (action !== "update") return installation(hostId2, agent, action);
26450
- updatingVersions.add(key);
26451
- if (diagnostics) render(diagnostics.snapshot());
26452
- try {
26453
- return await installation(hostId2, agent, action);
26454
- } finally {
26455
- updatingVersions.delete(key);
26456
- if (!context.signal.aborted && diagnostics) render(diagnostics.snapshot());
26457
- }
26458
- }
26459
- });
26460
- versionPanels.set(key, panel);
26461
- }
26462
- inspector.append(panel);
26463
- }
26892
+ if (item.version) inspector.append(item.version.element);
26464
26893
  };
26465
26894
  const pinnedItem = items.find((item) => item.key === "renderer-adapter");
26466
26895
  if (pinnedItem) {
@@ -30786,6 +31215,17 @@ ${error51.stderrTail}`] : []
30786
31215
  line-height: 18px;
30787
31216
  }
30788
31217
 
31218
+ .settings-connection-row__status:has(.settings-connection-version-available) {
31219
+ flex-wrap: wrap;
31220
+ max-width: 160px;
31221
+ }
31222
+
31223
+ .settings-connection-version-available {
31224
+ flex-basis: 100%;
31225
+ color: var(--settings-focus);
31226
+ overflow-wrap: anywhere;
31227
+ }
31228
+
30789
31229
  .settings-connection-row__status::before {
30790
31230
  width: 6px;
30791
31231
  height: 6px;
@@ -31129,6 +31569,69 @@ ${error51.stderrTail}`] : []
31129
31569
  gap: 8px;
31130
31570
  }
31131
31571
 
31572
+ .settings-grok-computer-use {
31573
+ display: grid;
31574
+ gap: 10px;
31575
+ min-width: 0;
31576
+ margin-top: 4px;
31577
+ padding: 12px;
31578
+ background: var(--settings-surface);
31579
+ border: 1px solid var(--settings-divider);
31580
+ border-radius: 12px;
31581
+ }
31582
+
31583
+ .settings-grok-computer-use__header {
31584
+ display: flex;
31585
+ align-items: flex-start;
31586
+ justify-content: space-between;
31587
+ gap: 12px;
31588
+ }
31589
+
31590
+ .settings-grok-computer-use__copy {
31591
+ display: grid;
31592
+ gap: 4px;
31593
+ min-width: 0;
31594
+ }
31595
+
31596
+ .settings-grok-computer-use__title {
31597
+ margin: 0;
31598
+ color: var(--settings-text);
31599
+ font-size: 14px;
31600
+ font-weight: 600;
31601
+ line-height: 20px;
31602
+ }
31603
+
31604
+ .settings-grok-computer-use__description {
31605
+ margin: 0;
31606
+ color: var(--settings-muted);
31607
+ font-size: 13px;
31608
+ line-height: 18px;
31609
+ overflow-wrap: anywhere;
31610
+ }
31611
+
31612
+ .settings-grok-computer-use__help,
31613
+ .settings-grok-computer-use__status {
31614
+ margin: 0;
31615
+ color: var(--settings-subtle);
31616
+ font-size: 12px;
31617
+ line-height: 16px;
31618
+ overflow-wrap: anywhere;
31619
+ }
31620
+
31621
+ .settings-grok-computer-use__help {
31622
+ padding-top: 8px;
31623
+ border-top: 1px solid var(--settings-divider);
31624
+ }
31625
+
31626
+ .settings-grok-computer-use__browser {
31627
+ padding-top: 8px;
31628
+ border-top: 1px solid var(--settings-divider);
31629
+ }
31630
+
31631
+ .settings-grok-computer-use__status[data-state="on"] {
31632
+ color: var(--settings-success);
31633
+ }
31634
+
31132
31635
  .settings-connection-install-callout {
31133
31636
  display: grid;
31134
31637
  grid-template-columns: 28px minmax(0, 1fr);
@@ -32378,6 +32881,19 @@ ${error51.stderrTail}`] : []
32378
32881
  border-top: 1px solid var(--settings-divider);
32379
32882
  font-size: 13px;
32380
32883
  }
32884
+ .settings-voice__health {
32885
+ display: grid;
32886
+ gap: 4px;
32887
+ margin: 8px 12px 12px;
32888
+ color: var(--settings-subtle);
32889
+ font-size: 12px;
32890
+ line-height: 16px;
32891
+ }
32892
+
32893
+ .settings-voice__health p {
32894
+ margin: 0;
32895
+ }
32896
+
32381
32897
  .settings-voice__footer p,
32382
32898
  .settings-voice__hint {
32383
32899
  margin: 4px 0 0;