@liberseek/boft-cli-win32-arm64 0.4.4 → 0.5.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.
@@ -14916,6 +14916,22 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14916
14916
  stderrTail: external_exports.string().min(1).optional()
14917
14917
  }).superRefine(rejectExplicitUndefined(["diagnostic", "stage", "durationMs", "stderrTail"]));
14918
14918
 
14919
+ // ../shared-contracts/dist/harness-session-import.js
14920
+ var HARNESS_SESSION_IMPORT_ID_MAX_LENGTH = 1024;
14921
+ var HARNESS_SESSION_IMPORT_CWD_MAX_LENGTH = 16384;
14922
+ var HARNESS_SESSION_IMPORT_TITLE_MAX_LENGTH = 4096;
14923
+ var HARNESS_SESSION_IMPORT_LIST_MAX_LENGTH = 1e3;
14924
+ var HARNESS_SESSION_IMPORT_UPDATED_AT_MAX = 864e13;
14925
+ var nonBlankTextSchema = external_exports.string().refine((value) => value.trim().length > 0, "Value must not be empty or whitespace").refine((value) => !value.includes("\0"), "Value must not contain NUL");
14926
+ var harnessSessionImportIdSchema = nonBlankTextSchema.max(HARNESS_SESSION_IMPORT_ID_MAX_LENGTH);
14927
+ var harnessSessionImportCandidateSchema = external_exports.object({
14928
+ nativeSessionId: harnessSessionImportIdSchema,
14929
+ title: nonBlankTextSchema.max(HARNESS_SESSION_IMPORT_TITLE_MAX_LENGTH).nullable(),
14930
+ updatedAt: external_exports.number().int().nonnegative().max(HARNESS_SESSION_IMPORT_UPDATED_AT_MAX),
14931
+ cwd: nonBlankTextSchema.max(HARNESS_SESSION_IMPORT_CWD_MAX_LENGTH),
14932
+ running: external_exports.boolean()
14933
+ }).strict();
14934
+
14919
14935
  // ../shared-contracts/dist/ids.js
14920
14936
  var opaqueIdSchema = external_exports.string().refine((value) => value.trim().length > 0, {
14921
14937
  message: "Identifier must not be empty or whitespace"
@@ -14926,6 +14942,23 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14926
14942
  var hostItemIdSchema = opaqueIdSchema.brand();
14927
14943
  var hostInteractionIdSchema = opaqueIdSchema.brand();
14928
14944
 
14945
+ // ../shared-contracts/dist/deepseek-modern-sessions.js
14946
+ var DEEPSEEK_MODERN_SESSION_LIST_MAX_LENGTH = HARNESS_SESSION_IMPORT_LIST_MAX_LENGTH;
14947
+ var DEEPSEEK_MODERN_HOST_THREAD_ID_MAX_LENGTH = 1024;
14948
+ var nonBlankTextSchema2 = external_exports.string().refine((value) => value.trim().length > 0, "Value must not be empty or whitespace").refine((value) => !value.includes("\0"), "Value must not contain NUL");
14949
+ var deepSeekModernSessionIdSchema = harnessSessionImportIdSchema;
14950
+ var deepSeekModernSessionCandidateSchema = harnessSessionImportCandidateSchema;
14951
+ var deepSeekModernSessionListParamsSchema = external_exports.object({}).strict();
14952
+ var deepSeekModernSessionListResultSchema = external_exports.object({
14953
+ candidates: external_exports.array(deepSeekModernSessionCandidateSchema).max(DEEPSEEK_MODERN_SESSION_LIST_MAX_LENGTH)
14954
+ }).strict();
14955
+ var deepSeekModernSessionImportParamsSchema = external_exports.object({
14956
+ nativeSessionId: deepSeekModernSessionIdSchema
14957
+ }).strict();
14958
+ var deepSeekModernSessionImportResultSchema = external_exports.object({
14959
+ threadId: nonBlankTextSchema2.max(DEEPSEEK_MODERN_HOST_THREAD_ID_MAX_LENGTH).pipe(hostThreadIdSchema)
14960
+ }).strict();
14961
+
14929
14962
  // ../shared-contracts/dist/external-thread-fork.js
14930
14963
  var externalThreadForkParamsSchema = external_exports.object({
14931
14964
  threadId: hostThreadIdSchema,
@@ -14940,14 +14973,14 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
14940
14973
  var HARNESS_PERMISSION_MODE_LABEL_MAX_LENGTH = 256;
14941
14974
  var HARNESS_PERMISSION_MODE_DESCRIPTION_MAX_LENGTH = 1024;
14942
14975
  var HARNESS_PERMISSION_MODE_CATALOG_MAX_LENGTH = 32;
14943
- var nonBlankTextSchema = external_exports.string().refine((value) => value.trim().length > 0, {
14976
+ var nonBlankTextSchema3 = external_exports.string().refine((value) => value.trim().length > 0, {
14944
14977
  message: "Value must not be empty or whitespace"
14945
14978
  });
14946
- var harnessPermissionModeIdSchema = nonBlankTextSchema.max(HARNESS_PERMISSION_MODE_ID_MAX_LENGTH).regex(/^[A-Za-z0-9._~-]+$/u, "Permission Mode ID must use transport-safe characters").brand();
14979
+ var harnessPermissionModeIdSchema = nonBlankTextSchema3.max(HARNESS_PERMISSION_MODE_ID_MAX_LENGTH).regex(/^[A-Za-z0-9._~-]+$/u, "Permission Mode ID must use transport-safe characters").brand();
14947
14980
  var harnessPermissionModeSchema = external_exports.object({
14948
14981
  id: harnessPermissionModeIdSchema,
14949
- label: nonBlankTextSchema.max(HARNESS_PERMISSION_MODE_LABEL_MAX_LENGTH),
14950
- description: nonBlankTextSchema.max(HARNESS_PERMISSION_MODE_DESCRIPTION_MAX_LENGTH).optional(),
14982
+ label: nonBlankTextSchema3.max(HARNESS_PERMISSION_MODE_LABEL_MAX_LENGTH),
14983
+ description: nonBlankTextSchema3.max(HARNESS_PERMISSION_MODE_DESCRIPTION_MAX_LENGTH).optional(),
14951
14984
  dangerous: external_exports.boolean().optional()
14952
14985
  }).strict();
14953
14986
  var harnessPermissionModeCatalogSchema = external_exports.object({
@@ -15060,22 +15093,22 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15060
15093
  var HARNESS_MODEL_LABEL_MAX_LENGTH = 256;
15061
15094
  var HARNESS_THINKING_OPTION_ID_MAX_LENGTH = 128;
15062
15095
  var THREAD_OWNERSHIP_LIST_MAX_LENGTH = 100;
15063
- var nonBlankTextSchema2 = external_exports.string().refine((value) => value.trim().length > 0, {
15096
+ var nonBlankTextSchema4 = external_exports.string().refine((value) => value.trim().length > 0, {
15064
15097
  message: "Value must not be empty or whitespace"
15065
15098
  });
15066
- var harnessModelRefIdSchema = nonBlankTextSchema2.max(HARNESS_MODEL_REF_MAX_LENGTH).regex(/^[A-Za-z0-9._~-]+$/u, "Model Ref must use transport-safe opaque characters").brand();
15099
+ var harnessModelRefIdSchema = nonBlankTextSchema4.max(HARNESS_MODEL_REF_MAX_LENGTH).regex(/^[A-Za-z0-9._~-]+$/u, "Model Ref must use transport-safe opaque characters").brand();
15067
15100
  var harnessModelRefSchema = external_exports.object({
15068
15101
  id: harnessModelRefIdSchema
15069
15102
  }).strict();
15070
- var harnessThinkingOptionIdSchema = nonBlankTextSchema2.max(HARNESS_THINKING_OPTION_ID_MAX_LENGTH).regex(/^[A-Za-z0-9._~-]+$/u, "Thinking option ID must use transport-safe characters").brand();
15071
- var harnessResolvedModelLabelSchema = nonBlankTextSchema2.max(HARNESS_MODEL_LABEL_MAX_LENGTH);
15103
+ var harnessThinkingOptionIdSchema = nonBlankTextSchema4.max(HARNESS_THINKING_OPTION_ID_MAX_LENGTH).regex(/^[A-Za-z0-9._~-]+$/u, "Thinking option ID must use transport-safe characters").brand();
15104
+ var harnessResolvedModelLabelSchema = nonBlankTextSchema4.max(HARNESS_MODEL_LABEL_MAX_LENGTH);
15072
15105
  var harnessThinkingOptionSchema = external_exports.object({
15073
15106
  id: harnessThinkingOptionIdSchema,
15074
- label: nonBlankTextSchema2.max(HARNESS_MODEL_LABEL_MAX_LENGTH)
15107
+ label: nonBlankTextSchema4.max(HARNESS_MODEL_LABEL_MAX_LENGTH)
15075
15108
  }).strict();
15076
15109
  var harnessModelSchema = external_exports.object({
15077
15110
  ref: harnessModelRefSchema,
15078
- label: nonBlankTextSchema2.max(HARNESS_MODEL_LABEL_MAX_LENGTH),
15111
+ label: nonBlankTextSchema4.max(HARNESS_MODEL_LABEL_MAX_LENGTH),
15079
15112
  resolvedModelLabel: harnessResolvedModelLabelSchema.optional(),
15080
15113
  supportedThinkingOptionIds: external_exports.array(harnessThinkingOptionIdSchema).optional()
15081
15114
  }).strict();
@@ -15187,11 +15220,15 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15187
15220
  }
15188
15221
  });
15189
15222
  var harnessModelSelectionStateSchema = harnessConfigurationStateSchema;
15223
+ var harnessWebUiCapabilitySchema = external_exports.object({
15224
+ open: external_exports.literal(true)
15225
+ }).strict();
15190
15226
  var readyHarnessInspectionSchema = external_exports.object({
15191
15227
  status: external_exports.literal("ready"),
15192
15228
  catalog: harnessModelCatalogSchema,
15193
15229
  permissionModes: harnessPermissionModeCatalogSchema.optional(),
15194
- capabilities: harnessSessionCapabilitiesSchema
15230
+ capabilities: harnessSessionCapabilitiesSchema,
15231
+ webUi: harnessWebUiCapabilitySchema.optional()
15195
15232
  }).strict().superRefine((inspection, context) => {
15196
15233
  const selectable = inspection.capabilities.configuration.selectPermissionMode;
15197
15234
  if (selectable !== Boolean(inspection.permissionModes)) {
@@ -15212,9 +15249,13 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15212
15249
  ]);
15213
15250
  var harnessInspectParamsSchema = external_exports.object({
15214
15251
  harnessId: harnessIdSchema,
15215
- cwd: nonBlankTextSchema2.max(16384).optional(),
15252
+ cwd: nonBlankTextSchema4.max(16384).optional(),
15216
15253
  refresh: external_exports.boolean().optional()
15217
15254
  }).strict();
15255
+ var harnessWebUiOpenParamsSchema = external_exports.object({
15256
+ harnessId: harnessIdSchema
15257
+ }).strict();
15258
+ var harnessWebUiOpenResultSchema = external_exports.object({}).strict();
15218
15259
  var threadModelSelectParamsSchema = external_exports.object({
15219
15260
  threadId: hostThreadIdSchema,
15220
15261
  model: harnessModelRefSchema
@@ -15232,8 +15273,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
15232
15273
  }).strict();
15233
15274
  var externalThreadInspectionSchema = external_exports.object({
15234
15275
  owner: external_exports.literal("external"),
15235
- harnessId: nonBlankTextSchema2.max(256),
15236
- transportModelId: nonBlankTextSchema2.max(1024),
15276
+ harnessId: nonBlankTextSchema4.max(256),
15277
+ transportModelId: nonBlankTextSchema4.max(1024),
15237
15278
  effectiveModel: harnessModelRefSchema.optional(),
15238
15279
  resolvedModelLabel: harnessResolvedModelLabelSchema.optional(),
15239
15280
  effectiveThinkingOptionId: harnessThinkingOptionIdSchema.optional(),
@@ -16255,7 +16296,34 @@ ${error51.stderrTail}`] : []
16255
16296
  body.append(callout, install2);
16256
16297
  return body;
16257
16298
  }
16258
- if (!item.error) return body;
16299
+ if (!item.error) {
16300
+ if (item.openWebUi) {
16301
+ const status = document2.createElement("div");
16302
+ status.className = "settings-connection-state-summary";
16303
+ const title2 = document2.createElement("strong");
16304
+ title2.textContent = connectionStatusLabel(item.availability, messages);
16305
+ const description2 = document2.createElement("p");
16306
+ description2.textContent = item.availability === "ready" ? messages.connectionReadyDescription : messages.connectionUnavailableDescription;
16307
+ status.append(title2, description2);
16308
+ const open = document2.createElement("button");
16309
+ open.type = "button";
16310
+ open.className = "settings-command-button settings-command-button--secondary";
16311
+ open.dataset.connectionAction = "open-web-ui";
16312
+ open.append(
16313
+ messages.connectionOpenHarnessWeb,
16314
+ createRendererSettingsIcon("external-link", 14)
16315
+ );
16316
+ open.addEventListener("click", () => {
16317
+ if (open.disabled) return;
16318
+ open.disabled = true;
16319
+ void item.openWebUi?.().catch(() => void 0).finally(() => {
16320
+ open.disabled = false;
16321
+ });
16322
+ });
16323
+ body.append(status, open);
16324
+ }
16325
+ return body;
16326
+ }
16259
16327
  const summary = document2.createElement("div");
16260
16328
  summary.className = "settings-connection-error-summary";
16261
16329
  const title = document2.createElement("strong");
@@ -16343,7 +16411,7 @@ ${error51.stderrTail}`] : []
16343
16411
  const action = document2.createElement("div");
16344
16412
  action.className = "settings-connection-row__action";
16345
16413
  action.setAttribute("role", "cell");
16346
- const canExpand = item.error !== null || item.agentSnapshot?.availability === "notInstalled";
16414
+ const canExpand = item.error !== null || item.agentSnapshot?.availability === "notInstalled" || item.openWebUi !== void 0;
16347
16415
  if (item.agentSnapshot?.availability === "notInstalled") {
16348
16416
  const install2 = document2.createElement("a");
16349
16417
  install2.className = "settings-connection-install-link";
@@ -16366,12 +16434,6 @@ ${error51.stderrTail}`] : []
16366
16434
  });
16367
16435
  action.append(viewError);
16368
16436
  }
16369
- row.addEventListener("click", (event) => {
16370
- const target = event.target;
16371
- if (target?.closest?.("a")) return;
16372
- if (!canExpand) return;
16373
- toggleExpand();
16374
- });
16375
16437
  row.addEventListener("keydown", (event) => {
16376
16438
  if (event.key !== "Enter" && event.key !== " ") return;
16377
16439
  if (!canExpand) return;
@@ -16392,15 +16454,24 @@ ${error51.stderrTail}`] : []
16392
16454
  if (expanded && canExpand) {
16393
16455
  block.append(createInlineErrorDetail(document2, item, hostId, messages));
16394
16456
  }
16457
+ block.addEventListener("click", (event) => {
16458
+ const target = event.target;
16459
+ if (target?.closest?.("a, button")) return;
16460
+ if (!canExpand) return;
16461
+ toggleExpand();
16462
+ });
16395
16463
  return { block, row };
16396
16464
  }
16397
- function connectionItems(host) {
16465
+ function connectionItems(host, diagnostics) {
16398
16466
  return host.agents.map((agent) => ({
16399
16467
  key: agent.agent,
16400
16468
  name: RENDERER_AGENT_LABELS[agent.agent],
16401
16469
  availability: agent.availability,
16402
16470
  error: agent.availability === "notInstalled" ? null : agent.error,
16403
- agentSnapshot: agent
16471
+ agentSnapshot: agent,
16472
+ ...host.hostId === "local" && agent.webUiAvailable && diagnostics?.openWebUi ? {
16473
+ openWebUi: () => diagnostics.openWebUi?.(host.hostId, agent.agent) ?? Promise.resolve()
16474
+ } : {}
16404
16475
  }));
16405
16476
  }
16406
16477
  var pendingFocusAgent = null;
@@ -16554,7 +16625,7 @@ ${error51.stderrTail}`] : []
16554
16625
  rows.id = panelId;
16555
16626
  rows.dataset.connectionHost = selectedHost.hostId;
16556
16627
  rows.setAttribute("role", "rowgroup");
16557
- const items = connectionItems(selectedHost);
16628
+ const items = connectionItems(selectedHost, diagnostics);
16558
16629
  if (expandedItemKey && !items.some((item) => item.key === expandedItemKey)) {
16559
16630
  expandedItemKey = null;
16560
16631
  }
@@ -16810,6 +16881,29 @@ ${error51.stderrTail}`] : []
16810
16881
  inDevelopment: "In development",
16811
16882
  notAvailable: "Not available",
16812
16883
  runtimeCapabilityNotInstalled: "This runtime capability is not installed yet.",
16884
+ sessionImportHarness: "Harness",
16885
+ sessionImportDescription: "Sessions keep their original project path. If a folder is not in the Codex sidebar, add it as a project first. Original history remains managed by the Harness.",
16886
+ sessionImportAvailabilityNote: "Currently, only DeepSeek Harness Modern sessions can be imported. Support for other Harnesses is coming later.",
16887
+ sessionImportRefresh: "Refresh",
16888
+ sessionImportRefreshing: "Loading local sessions...",
16889
+ sessionImportUnavailable: "Session import requires a local, BOFT CLI-managed DeepSeek Harness 0.1.2-rc.1 Modern runtime.",
16890
+ sessionImportEmpty: "No local DeepSeek Harness sessions are available to import.",
16891
+ sessionImportLoadFailed: "Local sessions could not be loaded.",
16892
+ sessionImportFailed: "The session could not be imported.",
16893
+ sessionImportUntitled: "Untitled session",
16894
+ sessionImportUpdatedAt: "Updated",
16895
+ sessionImportSessionId: "Session ID",
16896
+ sessionImportRunning: "Running",
16897
+ sessionImportRunningHint: "Stop this session in DSH, then refresh.",
16898
+ sessionImportAction: "Import and open",
16899
+ sessionImportImporting: "Importing...",
16900
+ sessionImportImported: "Session imported",
16901
+ sessionImportOpenFailed: "The Codex sidebar has not shown it yet. Make sure the folder below is added as a project, then try opening it again.",
16902
+ sessionImportCopyProjectPath: "Copy project path",
16903
+ sessionImportPathCopied: "Copied",
16904
+ sessionImportPathCopyFailed: "Copy failed",
16905
+ sessionImportRetryOpen: "Try opening again",
16906
+ sessionImportRetrying: "Opening...",
16813
16907
  connectionsDescription: "Add and configure Agent Harnesses supported by the system.",
16814
16908
  pluginsDescription: "Extend and manage Codex plugins.",
16815
16909
  pluginsRefresh: "Scan environment",
@@ -16846,6 +16940,7 @@ ${error51.stderrTail}`] : []
16846
16940
  connectionHostsScrollLeft: "Show previous Hosts",
16847
16941
  connectionHostsScrollRight: "Show more Hosts",
16848
16942
  connectionOpenInstallation: "Open official installation page",
16943
+ connectionOpenHarnessWeb: "Open DeepSeek Harness Web",
16849
16944
  connectionInstall: "Install",
16850
16945
  connectionInstallDescription: "This Harness was not detected. Follow its official installation guide, then return here and run the check again.",
16851
16946
  connectionErrorTitle: "Connection check failed",
@@ -16925,6 +17020,7 @@ ${error51.stderrTail}`] : []
16925
17020
  pageLabels: Object.freeze({
16926
17021
  connections: "Agents",
16927
17022
  plugins: "Plugin",
17023
+ "session-import": "Session Import",
16928
17024
  updates: "Updates",
16929
17025
  about: "About"
16930
17026
  })
@@ -16940,6 +17036,29 @@ ${error51.stderrTail}`] : []
16940
17036
  inDevelopment: "\u5F00\u53D1\u4E2D",
16941
17037
  notAvailable: "\u6682\u4E0D\u53EF\u7528",
16942
17038
  runtimeCapabilityNotInstalled: "\u8FD0\u884C\u65F6\u5C1A\u672A\u5B89\u88C5\u8BE5\u9879\u80FD\u529B\uFF0C\u56E0\u6B64\u6682\u4E0D\u53EF\u7528\u3002",
17039
+ sessionImportHarness: "Harness",
17040
+ sessionImportDescription: "\u4F1A\u8BDD\u5C06\u4FDD\u7559\u539F\u59CB\u9879\u76EE\u8DEF\u5F84\uFF1B\u82E5\u8BE5\u6587\u4EF6\u5939\u5C1A\u672A\u51FA\u73B0\u5728 Codex \u4FA7\u680F\uFF0C\u8BF7\u5148\u5C06\u5176\u6DFB\u52A0\u4E3A\u9879\u76EE\u3002\u539F\u59CB\u5386\u53F2\u4ECD\u7531 Harness \u7BA1\u7406\u3002",
17041
+ sessionImportAvailabilityNote: "\u5F53\u524D\u4EC5\u652F\u6301\u5BFC\u5165 DeepSeek Harness Modern \u4F1A\u8BDD\uFF1B\u5176\u4ED6 Harness \u7684\u4F1A\u8BDD\u5BFC\u5165\u80FD\u529B\u656C\u8BF7\u671F\u5F85\u3002",
17042
+ sessionImportRefresh: "\u5237\u65B0",
17043
+ sessionImportRefreshing: "\u6B63\u5728\u8BFB\u53D6\u672C\u5730\u4F1A\u8BDD\u2026\u2026",
17044
+ sessionImportUnavailable: "\u4F1A\u8BDD\u5BFC\u5165\u4EC5\u652F\u6301\u672C\u5730\u3001\u7531 BOFT CLI \u7BA1\u7406\u7684 DeepSeek Harness 0.1.2-rc.1 Modern \u8FD0\u884C\u65F6\u3002",
17045
+ sessionImportEmpty: "\u6CA1\u6709\u53EF\u5BFC\u5165\u7684\u672C\u5730 DeepSeek Harness \u4F1A\u8BDD\u3002",
17046
+ sessionImportLoadFailed: "\u65E0\u6CD5\u8BFB\u53D6\u672C\u5730\u4F1A\u8BDD\u3002",
17047
+ sessionImportFailed: "\u65E0\u6CD5\u5BFC\u5165\u8BE5\u4F1A\u8BDD\u3002",
17048
+ sessionImportUntitled: "\u672A\u547D\u540D\u4F1A\u8BDD",
17049
+ sessionImportUpdatedAt: "\u66F4\u65B0\u65F6\u95F4",
17050
+ sessionImportSessionId: "\u4F1A\u8BDD ID",
17051
+ sessionImportRunning: "\u8FD0\u884C\u4E2D",
17052
+ sessionImportRunningHint: "\u8BF7\u5148\u5728 DSH \u4E2D\u505C\u6B62\u8BE5\u4F1A\u8BDD\uFF0C\u7136\u540E\u5237\u65B0\u3002",
17053
+ sessionImportAction: "\u5BFC\u5165\u5E76\u6253\u5F00",
17054
+ sessionImportImporting: "\u6B63\u5728\u5BFC\u5165\u2026\u2026",
17055
+ sessionImportImported: "\u4F1A\u8BDD\u5DF2\u5BFC\u5165",
17056
+ sessionImportOpenFailed: "Codex \u4FA7\u680F\u5C1A\u672A\u663E\u793A\u8BE5\u4F1A\u8BDD\u3002\u8BF7\u786E\u8BA4\u4EE5\u4E0B\u6587\u4EF6\u5939\u5DF2\u6DFB\u52A0\u4E3A\u9879\u76EE\uFF0C\u7136\u540E\u91CD\u8BD5\u6253\u5F00\u3002",
17057
+ sessionImportCopyProjectPath: "\u590D\u5236\u9879\u76EE\u8DEF\u5F84",
17058
+ sessionImportPathCopied: "\u5DF2\u590D\u5236",
17059
+ sessionImportPathCopyFailed: "\u590D\u5236\u5931\u8D25",
17060
+ sessionImportRetryOpen: "\u91CD\u8BD5\u6253\u5F00",
17061
+ sessionImportRetrying: "\u6B63\u5728\u6253\u5F00\u2026\u2026",
16943
17062
  connectionsDescription: "\u6DFB\u52A0\u548C\u914D\u7F6E\u7CFB\u7EDF\u4E2D\u652F\u6301\u7684 Agent Harness\u3002",
16944
17063
  pluginsDescription: "\u6269\u5C55\u548C\u7BA1\u7406 Codex \u7684\u63D2\u4EF6\u3002",
16945
17064
  pluginsRefresh: "\u626B\u63CF\u73AF\u5883",
@@ -16976,6 +17095,7 @@ ${error51.stderrTail}`] : []
16976
17095
  connectionHostsScrollLeft: "\u67E5\u770B\u524D\u9762\u7684 Host",
16977
17096
  connectionHostsScrollRight: "\u67E5\u770B\u66F4\u591A Host",
16978
17097
  connectionOpenInstallation: "\u524D\u5F80\u5B98\u65B9\u5B89\u88C5\u9875\u9762",
17098
+ connectionOpenHarnessWeb: "\u6253\u5F00 DeepSeek Harness Web",
16979
17099
  connectionInstall: "\u5B89\u88C5",
16980
17100
  connectionInstallDescription: "\u5C1A\u672A\u68C0\u6D4B\u5230\u8BE5 Harness\u3002\u8BF7\u6309\u7167\u5B98\u65B9\u5B89\u88C5\u6307\u5357\u5B8C\u6210\u5B89\u88C5\uFF0C\u7136\u540E\u8FD4\u56DE\u6B64\u9875\u9762\u91CD\u65B0\u68C0\u67E5\u3002",
16981
17101
  connectionErrorTitle: "\u8FDE\u63A5\u68C0\u67E5\u5931\u8D25",
@@ -17055,6 +17175,7 @@ ${error51.stderrTail}`] : []
17055
17175
  pageLabels: Object.freeze({
17056
17176
  connections: "Agents",
17057
17177
  plugins: "Plugin",
17178
+ "session-import": "\u4F1A\u8BDD\u5BFC\u5165",
17058
17179
  updates: "\u66F4\u65B0",
17059
17180
  about: "\u5173\u4E8E"
17060
17181
  })
@@ -18766,7 +18887,6 @@ ${error51.stderrTail}`] : []
18766
18887
  sessionCostEstimate: "Session cost estimate",
18767
18888
  threadUsage: "Thread Usage",
18768
18889
  threadUsageDetails: "Thread Usage details",
18769
- contextSummary: "context",
18770
18890
  tokensSummary: "tokens",
18771
18891
  tokensPerSecond: "tok/s",
18772
18892
  fiveHourSummary: "5h",
@@ -18787,7 +18907,6 @@ ${error51.stderrTail}`] : []
18787
18907
  sessionCostEstimate: "\u4F1A\u8BDD\u8D39\u7528\u4F30\u7B97",
18788
18908
  threadUsage: "\u5BF9\u8BDD\u7528\u91CF",
18789
18909
  threadUsageDetails: "\u5BF9\u8BDD\u7528\u91CF\u8BE6\u60C5",
18790
- contextSummary: "\u4E0A\u4E0B\u6587",
18791
18910
  tokensSummary: "Token",
18792
18911
  tokensPerSecond: "Token/\u79D2",
18793
18912
  fiveHourSummary: "5 \u5C0F\u65F6",
@@ -18816,6 +18935,9 @@ ${error51.stderrTail}`] : []
18816
18935
  if (absolute < 1e9) return `${sign}${decimal(absolute / 1e6, 1)}M`;
18817
18936
  return `${sign}${decimal(absolute / 1e9, 1)}B`;
18818
18937
  }
18938
+ function formatRendererContextSummary(usedTokens, windowTokens) {
18939
+ return `${decimal(usedTokens / windowTokens * 100, 1)}% / ${formatRendererTokenCount(windowTokens)}`;
18940
+ }
18819
18941
  function formatRendererCreditsPercent(value) {
18820
18942
  return `${decimal(value, 1)}%`;
18821
18943
  }
@@ -19155,7 +19277,7 @@ ${error51.stderrTail}`] : []
19155
19277
  ].filter((value) => value !== null);
19156
19278
  if (summary.length === 0 && hasContext && usage?.contextWindowTokens !== void 0 && usage.contextWindowTokens > 0) {
19157
19279
  summary.push(
19158
- `${decimal((usage.contextUsedTokens ?? 0) / usage.contextWindowTokens * 100, 1)}% ${messages.contextSummary}`
19280
+ formatRendererContextSummary(usage.contextUsedTokens ?? 0, usage.contextWindowTokens)
19159
19281
  );
19160
19282
  }
19161
19283
  if (summary.length === 0 && usage?.totalTokens !== void 0) {
@@ -19617,11 +19739,7 @@ ${error51.stderrTail}`] : []
19617
19739
  menu.style.maxHeight = "min(360px, calc(100vh - 16px))";
19618
19740
  menu.style.overflowY = "auto";
19619
19741
  menu.style.padding = "4px";
19620
- menu.style.border = "1px solid rgba(127, 127, 127, 0.24)";
19621
- menu.style.borderRadius = "10px";
19622
- menu.style.background = "Canvas";
19623
- menu.style.color = "CanvasText";
19624
- menu.style.boxShadow = "0 12px 32px rgba(0, 0, 0, 0.22)";
19742
+ applyRendererPopoverChrome(menu);
19625
19743
  ownerDocument.body.append(menu);
19626
19744
  if (insertBefore?.parentElement === parent) parent.insertBefore(root, insertBefore);
19627
19745
  else parent.append(root);
@@ -20059,11 +20177,8 @@ ${error51.stderrTail}`] : []
20059
20177
  if (control.usage) control.usage.anchor = null;
20060
20178
  return;
20061
20179
  }
20062
- const previousUsageParent = control.usage.root.parentElement;
20063
- const previousUsageNextSibling = control.usage.root.nextElementSibling;
20064
20180
  control.usage.place(anchor);
20065
- const usagePositionChanged = previousUsageParent !== control.usage.root.parentElement || previousUsageNextSibling !== control.usage.root.nextElementSibling;
20066
- if (usagePositionChanged) control.harnessCommands?.placeBefore(control.usage.root);
20181
+ control.harnessCommands?.placeBefore(control.usage.root);
20067
20182
  }
20068
20183
  function refreshCreditsPlacement(control) {
20069
20184
  const anchor = creditsPlacementAnchor(control);
@@ -20232,7 +20347,9 @@ ${error51.stderrTail}`] : []
20232
20347
  var SIDEBAR_THREAD_ID_ATTRIBUTE = "data-app-action-sidebar-thread-id";
20233
20348
  var SIDEBAR_THREAD_HOST_ID_ATTRIBUTE = "data-app-action-sidebar-thread-host-id";
20234
20349
  var SIDEBAR_AGENT_ICON_ATTRIBUTE = "data-codexhost-sidebar-agent-icon";
20350
+ var SIDEBAR_EXTERNAL_THREAD_ATTRIBUTE = "data-codexhost-sidebar-external-thread";
20235
20351
  var OWNERSHIP_RETRY_DELAYS_MS = [100, 300, 800, 1500, 3e3];
20352
+ var PIN_REPLAY_RETRY_DELAYS_MS = [50, 150, 300];
20236
20353
  function isRecord2(value) {
20237
20354
  return typeof value === "object" && value !== null && !Array.isArray(value);
20238
20355
  }
@@ -20315,9 +20432,11 @@ ${error51.stderrTail}`] : []
20315
20432
  ...this.element.querySelectorAll(`[${SIDEBAR_AGENT_ICON_ATTRIBUTE}]`)
20316
20433
  ];
20317
20434
  if (icons.length === 1 && icons[0]?.parentElement === titleTrigger && icons[0].getAttribute(SIDEBAR_AGENT_ICON_ATTRIBUTE) === agent) {
20435
+ this.element.setAttribute(SIDEBAR_EXTERNAL_THREAD_ATTRIBUTE, "true");
20318
20436
  return;
20319
20437
  }
20320
20438
  this.clear();
20439
+ this.element.setAttribute(SIDEBAR_EXTERNAL_THREAD_ATTRIBUTE, "true");
20321
20440
  const label = `${RENDERER_AGENT_LABELS[agent]} Agent`;
20322
20441
  const marker = this.element.ownerDocument.createElement("span");
20323
20442
  marker.setAttribute(SIDEBAR_AGENT_ICON_ATTRIBUTE, agent);
@@ -20335,11 +20454,84 @@ ${error51.stderrTail}`] : []
20335
20454
  titleTrigger.insertBefore(marker, title);
20336
20455
  }
20337
20456
  clear() {
20457
+ this.element.removeAttribute(SIDEBAR_EXTERNAL_THREAD_ATTRIBUTE);
20338
20458
  for (const icon2 of this.element.querySelectorAll(`[${SIDEBAR_AGENT_ICON_ATTRIBUTE}]`)) {
20339
20459
  icon2.remove();
20340
20460
  }
20341
20461
  }
20342
20462
  };
20463
+ function sidebarExternalPinActionFromTarget(target) {
20464
+ if (!(target instanceof Element)) return null;
20465
+ const button = target.closest("button");
20466
+ const row = target.closest(SIDEBAR_THREAD_ROW_SELECTOR);
20467
+ if (!button || !row || row.getAttribute(SIDEBAR_EXTERNAL_THREAD_ATTRIBUTE) !== "true") {
20468
+ return null;
20469
+ }
20470
+ if (row.querySelector("button") !== button) return null;
20471
+ const attributes = sidebarThreadAttributes(row);
20472
+ const threadId = hostThreadIdSchema.safeParse(threadIdFromSidebarRowElement(row));
20473
+ if (!attributes || !threadId.success) return null;
20474
+ return {
20475
+ hostId: attributes.hostId,
20476
+ threadId: threadId.data,
20477
+ isPinned: row.getAttribute("data-app-action-sidebar-thread-pinned") !== "true"
20478
+ };
20479
+ }
20480
+ function installRendererSidebarExternalPinning(options) {
20481
+ const root = options.root ?? document;
20482
+ const replayingButtons = /* @__PURE__ */ new WeakSet();
20483
+ const replayTimers = /* @__PURE__ */ new Set();
20484
+ const currentPinRow = (action) => {
20485
+ for (const row of root.querySelectorAll(SIDEBAR_THREAD_ROW_SELECTOR)) {
20486
+ const attributes = sidebarThreadAttributes(row);
20487
+ if (attributes?.hostId === action.hostId && row.getAttribute(SIDEBAR_EXTERNAL_THREAD_ATTRIBUTE) === "true" && threadIdFromSidebarRowElement(row) === action.threadId) {
20488
+ return row;
20489
+ }
20490
+ }
20491
+ return null;
20492
+ };
20493
+ const replayNativePinAction = (action, originalButton, retryIndex = 0) => {
20494
+ const row = currentPinRow(action);
20495
+ if (row?.getAttribute("data-app-action-sidebar-thread-pinned") === String(action.isPinned)) {
20496
+ return;
20497
+ }
20498
+ const currentButton = row?.querySelector("button") ?? (originalButton.isConnected === false ? null : originalButton);
20499
+ if (currentButton) {
20500
+ replayingButtons.add(currentButton);
20501
+ currentButton.click();
20502
+ return;
20503
+ }
20504
+ const delay = PIN_REPLAY_RETRY_DELAYS_MS[retryIndex];
20505
+ if (delay === void 0) return;
20506
+ const timer = setTimeout(() => {
20507
+ replayTimers.delete(timer);
20508
+ replayNativePinAction(action, originalButton, retryIndex + 1);
20509
+ }, delay);
20510
+ replayTimers.add(timer);
20511
+ };
20512
+ const onClick = (event) => {
20513
+ const action = sidebarExternalPinActionFromTarget(event.target);
20514
+ if (!action) return;
20515
+ const button = event.target instanceof Element ? event.target.closest("button") : null;
20516
+ if (!button) return;
20517
+ if (replayingButtons.delete(button)) return;
20518
+ const update = options.getClient(action.hostId)?.updateThreadPinned;
20519
+ if (!update) return;
20520
+ event.preventDefault();
20521
+ event.stopImmediatePropagation();
20522
+ void update({ threadId: action.threadId, isPinned: action.isPinned }).then(() => {
20523
+ replayNativePinAction(action, button);
20524
+ }).catch((error51) => {
20525
+ options.reportError?.(error51);
20526
+ });
20527
+ };
20528
+ root.addEventListener("click", onClick, true);
20529
+ return () => {
20530
+ root.removeEventListener("click", onClick, true);
20531
+ for (const timer of replayTimers) clearTimeout(timer);
20532
+ replayTimers.clear();
20533
+ };
20534
+ }
20343
20535
  var BrowserSidebarAgentIconDom = class {
20344
20536
  constructor(root) {
20345
20537
  this.root = root;
@@ -20549,6 +20741,64 @@ ${error51.stderrTail}`] : []
20549
20741
  var RESPONSE_CONVERSATION_ATTRIBUTE = "data-response-annotation-conversation";
20550
20742
  var TURN_KEY_ATTRIBUTE = "data-content-search-turn-key";
20551
20743
  var OPEN_THREAD_TIMEOUT_MS = 5e3;
20744
+ function abortError() {
20745
+ return Object.assign(new Error("Thread opening was aborted"), { name: "AbortError" });
20746
+ }
20747
+ function openRendererThread(threadId, options = {}) {
20748
+ const find = () => {
20749
+ for (const row of document.querySelectorAll(SIDEBAR_THREAD_ROW_SELECTOR)) {
20750
+ if ((options.hostId === void 0 || row.getAttribute(SIDEBAR_THREAD_HOST_ID_ATTRIBUTE) === options.hostId) && threadIdFromSidebarRowElement(row) === threadId) {
20751
+ return row;
20752
+ }
20753
+ }
20754
+ return null;
20755
+ };
20756
+ if (options.signal?.aborted) return Promise.reject(abortError());
20757
+ const current = find();
20758
+ if (current) {
20759
+ current.click();
20760
+ return Promise.resolve();
20761
+ }
20762
+ return new Promise((resolve, reject) => {
20763
+ let settled = false;
20764
+ const cleanup = () => {
20765
+ window.clearTimeout(timeout);
20766
+ observer.disconnect();
20767
+ options.signal?.removeEventListener("abort", onAbort);
20768
+ };
20769
+ const finish = (row2) => {
20770
+ if (settled) return;
20771
+ settled = true;
20772
+ cleanup();
20773
+ row2.click();
20774
+ resolve();
20775
+ };
20776
+ const observer = new MutationObserver(() => {
20777
+ const row2 = find();
20778
+ if (row2) finish(row2);
20779
+ });
20780
+ const timeout = window.setTimeout(() => {
20781
+ if (settled) return;
20782
+ settled = true;
20783
+ cleanup();
20784
+ reject(new Error("Thread did not appear in the sidebar"));
20785
+ }, options.timeoutMs ?? OPEN_THREAD_TIMEOUT_MS);
20786
+ const onAbort = () => {
20787
+ if (settled) return;
20788
+ settled = true;
20789
+ cleanup();
20790
+ reject(abortError());
20791
+ };
20792
+ options.signal?.addEventListener("abort", onAbort, { once: true });
20793
+ observer.observe(document.documentElement, { childList: true, subtree: true });
20794
+ if (options.signal?.aborted) {
20795
+ onAbort();
20796
+ return;
20797
+ }
20798
+ const row = find();
20799
+ if (row) finish(row);
20800
+ });
20801
+ }
20552
20802
  function isRecord3(value) {
20553
20803
  return typeof value === "object" && value !== null && !Array.isArray(value);
20554
20804
  }
@@ -20622,35 +20872,7 @@ ${error51.stderrTail}`] : []
20622
20872
  target.control.click();
20623
20873
  }
20624
20874
  openThread(threadId) {
20625
- const find = () => {
20626
- for (const row of document.querySelectorAll(SIDEBAR_THREAD_ROW_SELECTOR)) {
20627
- if (threadIdFromSidebarRowElement(row) === threadId) return row;
20628
- }
20629
- return null;
20630
- };
20631
- const current = find();
20632
- if (current) {
20633
- current.click();
20634
- return Promise.resolve();
20635
- }
20636
- return new Promise((resolve, reject) => {
20637
- const observer = new MutationObserver(() => {
20638
- const row = find();
20639
- if (!row) return;
20640
- cleanup();
20641
- row.click();
20642
- resolve();
20643
- });
20644
- const timeout = window.setTimeout(() => {
20645
- cleanup();
20646
- reject(new Error("Forked Thread did not appear in the sidebar"));
20647
- }, OPEN_THREAD_TIMEOUT_MS);
20648
- const cleanup = () => {
20649
- window.clearTimeout(timeout);
20650
- observer.disconnect();
20651
- };
20652
- observer.observe(document.documentElement, { childList: true, subtree: true });
20653
- });
20875
+ return openRendererThread(threadId);
20654
20876
  }
20655
20877
  };
20656
20878
  function installRendererForkControl(options) {
@@ -20690,6 +20912,9 @@ ${error51.stderrTail}`] : []
20690
20912
 
20691
20913
  // src/renderer-model-client.ts
20692
20914
  var HARNESS_INSPECT_METHOD = "codexhost/harness/inspect";
20915
+ var DEEPSEEK_MODERN_SESSION_LIST_METHOD = "codexhost/deepseek/modern-session/list";
20916
+ var DEEPSEEK_MODERN_SESSION_IMPORT_METHOD = "codexhost/deepseek/modern-session/import";
20917
+ var HARNESS_WEB_UI_OPEN_METHOD = "codexhost/harness/web-ui/open";
20693
20918
  var THREAD_FORK_METHOD = "codexhost/thread/fork";
20694
20919
  var THREAD_INSPECT_METHOD = "codexhost/thread/inspect";
20695
20920
  var THREAD_COMMANDS_INSPECT_METHOD = "codexhost/thread/commands/inspect";
@@ -20698,15 +20923,26 @@ ${error51.stderrTail}`] : []
20698
20923
  var THREAD_THINKING_SELECT_METHOD = "codexhost/thread/thinking/select";
20699
20924
  var THREAD_PERMISSION_MODE_SELECT_METHOD = "codexhost/thread/permission-mode/select";
20700
20925
  var THREAD_OWNERSHIP_LIST_METHOD = "codexhost/thread/ownership/list";
20926
+ var THREAD_METADATA_UPDATE_METHOD = "thread/metadata/update";
20701
20927
  var THREAD_USAGE_INSPECT_METHOD = "codexhost/thread/usage/inspect";
20702
20928
  var THREAD_USAGE_UPDATED_METHOD = "codexhost/thread/usage/updated";
20703
20929
  var THREAD_TOKEN_USAGE_UPDATED_METHOD = "thread/tokenUsage/updated";
20704
20930
  var UPDATE_CHECK_METHOD = "codexhost/update/check";
20705
20931
  var UPDATE_START_METHOD = "codexhost/update/start";
20706
20932
  var UPDATE_STATUS_METHOD = "codexhost/update/status";
20933
+ var RendererDeepSeekSessionUnavailableError = class extends Error {
20934
+ constructor() {
20935
+ super("DeepSeek Modern Session import is unavailable");
20936
+ this.name = "RendererDeepSeekSessionUnavailableError";
20937
+ }
20938
+ };
20707
20939
  function isRecord4(value) {
20708
20940
  return typeof value === "object" && value !== null && !Array.isArray(value);
20709
20941
  }
20942
+ function normalizeDeepSeekSessionError(error51) {
20943
+ const code = isRecord4(error51) ? error51.code : void 0;
20944
+ return code === -32076 || code === -32077 ? new RendererDeepSeekSessionUnavailableError() : error51;
20945
+ }
20710
20946
  function notifiedThreadId(notification) {
20711
20947
  if (!isRecord4(notification) || notification.method !== THREAD_TOKEN_USAGE_UPDATED_METHOD && notification.method !== THREAD_USAGE_UPDATED_METHOD) {
20712
20948
  return null;
@@ -20757,6 +20993,7 @@ ${error51.stderrTail}`] : []
20757
20993
  );
20758
20994
  const manager = managers[0];
20759
20995
  if (managers.length !== 1 || !manager) return null;
20996
+ const pendingDeepSeekImports = /* @__PURE__ */ new Map();
20760
20997
  const inspectHarness = async (input) => {
20761
20998
  const params = harnessInspectParamsSchema.parse(input);
20762
20999
  const result = await manager.sendRequest(HARNESS_INSPECT_METHOD, params);
@@ -20792,13 +21029,47 @@ ${error51.stderrTail}`] : []
20792
21029
  const result = await manager.sendRequest(THREAD_PERMISSION_MODE_SELECT_METHOD, params);
20793
21030
  return harnessConfigurationStateSchema.parse(result);
20794
21031
  };
21032
+ const importDeepSeekModernSession = async (input) => {
21033
+ const params = deepSeekModernSessionImportParamsSchema.parse(input);
21034
+ const pending = pendingDeepSeekImports.get(params.nativeSessionId);
21035
+ if (pending) return pending;
21036
+ const request = (async () => {
21037
+ try {
21038
+ const result = await manager.sendRequest(DEEPSEEK_MODERN_SESSION_IMPORT_METHOD, params);
21039
+ return deepSeekModernSessionImportResultSchema.parse(result);
21040
+ } catch (error51) {
21041
+ throw normalizeDeepSeekSessionError(error51);
21042
+ }
21043
+ })().finally(() => {
21044
+ if (pendingDeepSeekImports.get(params.nativeSessionId) === request) {
21045
+ pendingDeepSeekImports.delete(params.nativeSessionId);
21046
+ }
21047
+ });
21048
+ pendingDeepSeekImports.set(params.nativeSessionId, request);
21049
+ return request;
21050
+ };
20795
21051
  return Object.freeze({
21052
+ async listDeepSeekModernSessions(input) {
21053
+ const params = deepSeekModernSessionListParamsSchema.parse(input);
21054
+ try {
21055
+ const result = await manager.sendRequest(DEEPSEEK_MODERN_SESSION_LIST_METHOD, params);
21056
+ return deepSeekModernSessionListResultSchema.parse(result);
21057
+ } catch (error51) {
21058
+ throw normalizeDeepSeekSessionError(error51);
21059
+ }
21060
+ },
21061
+ importDeepSeekModernSession,
20796
21062
  async forkThread(input) {
20797
21063
  const params = externalThreadForkParamsSchema.parse(input);
20798
21064
  const result = await manager.sendRequest(THREAD_FORK_METHOD, params);
20799
21065
  return externalThreadForkResultSchema.parse(result);
20800
21066
  },
20801
21067
  inspectHarness,
21068
+ async openHarnessWebUi(input) {
21069
+ const params = harnessWebUiOpenParamsSchema.parse(input);
21070
+ const result = await manager.sendRequest(HARNESS_WEB_UI_OPEN_METHOD, params);
21071
+ harnessWebUiOpenResultSchema.parse(result);
21072
+ },
20802
21073
  async inspectThread(input) {
20803
21074
  const params = threadInspectionParamsSchema.parse(input);
20804
21075
  const result = await manager.sendRequest(THREAD_INSPECT_METHOD, params);
@@ -20815,6 +21086,13 @@ ${error51.stderrTail}`] : []
20815
21086
  }
20816
21087
  return result;
20817
21088
  },
21089
+ async updateThreadPinned(input) {
21090
+ const threadId = hostThreadIdSchema.parse(input.threadId);
21091
+ await manager.sendRequest(THREAD_METADATA_UPDATE_METHOD, {
21092
+ threadId,
21093
+ isPinned: input.isPinned
21094
+ });
21095
+ },
20818
21096
  inspectThreadUsage,
20819
21097
  subscribeThreadUsage(listener) {
20820
21098
  const notifications = notificationTarget(manager);
@@ -21701,6 +21979,55 @@ ${error51.stderrTail}`] : []
21701
21979
  );
21702
21980
  }
21703
21981
 
21982
+ // src/renderer-harness-command-claim.ts
21983
+ function inputEvent(editor, text) {
21984
+ const view = editor.ownerDocument.defaultView;
21985
+ return view?.InputEvent ? new view.InputEvent("input", {
21986
+ bubbles: true,
21987
+ composed: true,
21988
+ data: text,
21989
+ inputType: "insertText"
21990
+ }) : new (view?.Event ?? Event)("input", { bubbles: true, composed: true });
21991
+ }
21992
+ function prependTextarea(editor, prefix) {
21993
+ const view = editor.ownerDocument.defaultView;
21994
+ if (!view || !(editor instanceof view.HTMLTextAreaElement)) return false;
21995
+ const setter = Object.getOwnPropertyDescriptor(view.HTMLTextAreaElement.prototype, "value")?.set;
21996
+ if (!setter) return false;
21997
+ const start = editor.selectionStart;
21998
+ const end = editor.selectionEnd;
21999
+ setter.call(editor, prefix + editor.value);
22000
+ editor.dispatchEvent(inputEvent(editor, prefix));
22001
+ editor.focus({ preventScroll: true });
22002
+ if (start !== null && end !== null) {
22003
+ editor.setSelectionRange(start + prefix.length, end + prefix.length);
22004
+ }
22005
+ return true;
22006
+ }
22007
+ function prependContentEditable(editor, prefix) {
22008
+ if (editor.getAttribute("contenteditable") !== "true") return false;
22009
+ const document2 = editor.ownerDocument;
22010
+ const selection = document2.getSelection();
22011
+ if (!selection || typeof document2.execCommand !== "function") return false;
22012
+ const range = document2.createRange();
22013
+ range.selectNodeContents(editor);
22014
+ range.collapse(true);
22015
+ editor.focus({ preventScroll: true });
22016
+ selection.removeAllRanges();
22017
+ selection.addRange(range);
22018
+ return document2.execCommand("insertText", false, prefix);
22019
+ }
22020
+ function prependEditor(editor, prefix) {
22021
+ return prependTextarea(editor, prefix) || prependContentEditable(editor, prefix);
22022
+ }
22023
+ function routeRendererHarnessCommandSelection(editor, command, execute) {
22024
+ if (command.argumentMode === "none") {
22025
+ execute();
22026
+ return true;
22027
+ }
22028
+ return editor !== null && prependEditor(editor, `${command.invocation} `);
22029
+ }
22030
+
21704
22031
  // src/codex-locale-adapter.ts
21705
22032
  var GET_LOCALE_OVERRIDE_URL = "vscode://codex/get-setting";
21706
22033
  var GET_LOCALE_INFO_URL = "vscode://codex/locale-info";
@@ -21723,7 +22050,7 @@ ${error51.stderrTail}`] : []
21723
22050
  }
21724
22051
  return canonicalLocale(ownerWindow.navigator.language);
21725
22052
  }
21726
- function abortError() {
22053
+ function abortError2() {
21727
22054
  return new DOMException("The operation was aborted", "AbortError");
21728
22055
  }
21729
22056
  function parseLocaleOverride(value) {
@@ -21753,7 +22080,7 @@ ${error51.stderrTail}`] : []
21753
22080
  if (typeof bridge?.sendMessageFromView !== "function") {
21754
22081
  return Promise.reject(new Error("Codex locale bridge is unavailable"));
21755
22082
  }
21756
- if (signal?.aborted) return Promise.reject(abortError());
22083
+ if (signal?.aborted) return Promise.reject(abortError2());
21757
22084
  const requestId = ownerWindow.crypto.randomUUID();
21758
22085
  return new Promise((resolve, reject) => {
21759
22086
  let settled = false;
@@ -21768,7 +22095,7 @@ ${error51.stderrTail}`] : []
21768
22095
  cleanup();
21769
22096
  operation();
21770
22097
  };
21771
- const onAbort = () => settle(() => reject(abortError()));
22098
+ const onAbort = () => settle(() => reject(abortError2()));
21772
22099
  const onMessage = (event) => {
21773
22100
  const message2 = event.data;
21774
22101
  if (!isRecord7(message2) || message2.type !== "fetch-response") return;
@@ -21835,12 +22162,12 @@ ${error51.stderrTail}`] : []
21835
22162
  if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
21836
22163
  throw new Error("Codex locale request timeout must be positive");
21837
22164
  }
21838
- if (options.signal?.aborted) throw abortError();
22165
+ if (options.signal?.aborted) throw abortError2();
21839
22166
  const [overrideResult, localeInfoResult] = await Promise.allSettled([
21840
22167
  readLocaleOverride(ownerWindow, options.signal, timeoutMs),
21841
22168
  readLocaleInfo(ownerWindow, options.signal, timeoutMs)
21842
22169
  ]);
21843
- if (options.signal?.aborted) throw abortError();
22170
+ if (options.signal?.aborted) throw abortError2();
21844
22171
  const navigatorLocale = firstNavigatorLocale(ownerWindow);
21845
22172
  const overrideKnown = overrideResult.status === "fulfilled";
21846
22173
  const localeOverride = overrideKnown ? overrideResult.value.value : void 0;
@@ -21983,6 +22310,346 @@ ${error51.stderrTail}`] : []
21983
22310
  }
21984
22311
  };
21985
22312
 
22313
+ // src/settings/deepseek-session-import-page.ts
22314
+ var SESSION_IMPORT_HARNESSES = KNOWN_RENDERER_AGENTS.filter(
22315
+ (agent) => agent !== "codex"
22316
+ );
22317
+ function shortSessionId(value) {
22318
+ return value.length <= 18 ? value : `${value.slice(0, 10)}\u2026${value.slice(-6)}`;
22319
+ }
22320
+ function createStatus(document2, message, error51 = false) {
22321
+ const status = document2.createElement("div");
22322
+ status.className = error51 ? "settings-session-import-status is-error" : "settings-session-import-status";
22323
+ status.setAttribute("role", error51 ? "alert" : "status");
22324
+ status.append(createRendererSettingsIcon(error51 ? "alert" : "download", 18));
22325
+ const copy = document2.createElement("span");
22326
+ copy.textContent = message;
22327
+ status.append(copy);
22328
+ return status;
22329
+ }
22330
+ function createAccessibleText(document2, message) {
22331
+ const text = document2.createElement("span");
22332
+ text.className = "settings-visually-hidden";
22333
+ text.textContent = message;
22334
+ return text;
22335
+ }
22336
+ function createDeepSeekSessionImportSettingsPage(messages, getClient, openImportedThread) {
22337
+ return Object.freeze({
22338
+ id: "session-import",
22339
+ label: messages.pageLabels["session-import"],
22340
+ icon: "download",
22341
+ mount(context) {
22342
+ const document2 = context.content.ownerDocument;
22343
+ const header = document2.createElement("div");
22344
+ header.className = "settings-connection-page-header";
22345
+ const headingCopy = document2.createElement("div");
22346
+ const heading = document2.createElement("h2");
22347
+ heading.className = "settings-section-label";
22348
+ heading.textContent = messages.pageLabels["session-import"];
22349
+ const description = document2.createElement("p");
22350
+ description.className = "settings-page-description";
22351
+ description.textContent = messages.sessionImportDescription;
22352
+ headingCopy.append(heading, description);
22353
+ const refresh = document2.createElement("button");
22354
+ refresh.type = "button";
22355
+ refresh.className = "settings-command-button settings-command-button--secondary";
22356
+ refresh.dataset.sessionImportAction = "refresh";
22357
+ const setRefreshLabel = (loading) => {
22358
+ refresh.replaceChildren(
22359
+ createRendererSettingsIcon("refresh", 15),
22360
+ loading ? messages.sessionImportRefreshing : messages.sessionImportRefresh
22361
+ );
22362
+ };
22363
+ setRefreshLabel(false);
22364
+ header.append(headingCopy, refresh);
22365
+ const harness = document2.createElement("div");
22366
+ harness.className = "settings-session-import-harness";
22367
+ const harnessLabel = document2.createElement("span");
22368
+ harnessLabel.textContent = messages.sessionImportHarness;
22369
+ const harnessOptions = document2.createElement("div");
22370
+ harnessOptions.className = "settings-segmented settings-session-import-harness__options";
22371
+ harnessOptions.dataset.sessionImportHarness = "selector";
22372
+ harnessOptions.setAttribute("role", "group");
22373
+ harnessOptions.setAttribute("aria-label", messages.sessionImportHarness);
22374
+ for (const agent of SESSION_IMPORT_HARNESSES) {
22375
+ const selected = agent === "deepseek-harness";
22376
+ const option = document2.createElement("button");
22377
+ option.type = "button";
22378
+ option.className = selected ? "settings-segmented__item settings-segmented__item--selected settings-session-import-harness__option" : "settings-segmented__item settings-session-import-harness__option";
22379
+ option.dataset.sessionImportHarnessOption = agent;
22380
+ option.textContent = RENDERER_AGENT_LABELS[agent];
22381
+ option.disabled = !selected;
22382
+ option.setAttribute("aria-pressed", selected ? "true" : "false");
22383
+ harnessOptions.append(option);
22384
+ }
22385
+ harness.append(harnessLabel, harnessOptions);
22386
+ const availabilityNote = document2.createElement("p");
22387
+ availabilityNote.className = "settings-page-description settings-session-import-availability-note";
22388
+ availabilityNote.textContent = messages.sessionImportAvailabilityNote;
22389
+ const content = document2.createElement("section");
22390
+ content.className = "settings-session-import-content";
22391
+ context.content.append(header, harness, availabilityNote, content);
22392
+ let candidates = [];
22393
+ let importingId = null;
22394
+ let actions = [];
22395
+ const updateImportActions = () => {
22396
+ for (const { button, candidate } of actions) {
22397
+ const importing = importingId === candidate.nativeSessionId;
22398
+ button.disabled = candidate.running;
22399
+ button.setAttribute(
22400
+ "aria-disabled",
22401
+ candidate.running || importingId !== null ? "true" : "false"
22402
+ );
22403
+ button.setAttribute("aria-busy", importing ? "true" : "false");
22404
+ button.replaceChildren(
22405
+ createRendererSettingsIcon("download", 15),
22406
+ importing ? messages.sessionImportImporting : messages.sessionImportAction
22407
+ );
22408
+ }
22409
+ };
22410
+ const renderUnavailable = (focus = false) => {
22411
+ candidates = [];
22412
+ actions = [];
22413
+ const status = createStatus(document2, messages.sessionImportUnavailable);
22414
+ content.replaceChildren(status);
22415
+ if (focus) {
22416
+ status.tabIndex = -1;
22417
+ status.focus();
22418
+ }
22419
+ };
22420
+ const renderFailure = (error51, operation = "list") => {
22421
+ if (error51 instanceof RendererDeepSeekSessionUnavailableError) {
22422
+ renderUnavailable(operation === "import");
22423
+ return;
22424
+ }
22425
+ actions = [];
22426
+ const status = createStatus(
22427
+ document2,
22428
+ operation === "import" ? messages.sessionImportFailed : messages.sessionImportLoadFailed,
22429
+ true
22430
+ );
22431
+ content.replaceChildren(status);
22432
+ if (operation === "import") {
22433
+ status.tabIndex = -1;
22434
+ status.focus();
22435
+ }
22436
+ };
22437
+ const renderOpenRecovery = (candidate, threadId) => {
22438
+ actions = [];
22439
+ refresh.disabled = false;
22440
+ const recovery = document2.createElement("section");
22441
+ recovery.className = "settings-session-import-recovery";
22442
+ recovery.setAttribute("role", "region");
22443
+ recovery.setAttribute("aria-label", messages.sessionImportImported);
22444
+ recovery.tabIndex = -1;
22445
+ const recoveryCopy = document2.createElement("div");
22446
+ recoveryCopy.className = "settings-session-import-recovery__copy";
22447
+ const title = document2.createElement("strong");
22448
+ title.textContent = messages.sessionImportImported;
22449
+ const explanation = document2.createElement("p");
22450
+ explanation.textContent = messages.sessionImportOpenFailed;
22451
+ recoveryCopy.append(title, explanation);
22452
+ const path = document2.createElement("div");
22453
+ path.className = "settings-session-import-recovery__path";
22454
+ const cwd = document2.createElement("code");
22455
+ cwd.textContent = candidate.cwd;
22456
+ cwd.title = candidate.cwd;
22457
+ const copyPath = document2.createElement("button");
22458
+ copyPath.type = "button";
22459
+ copyPath.className = "settings-command-button settings-command-button--secondary";
22460
+ copyPath.dataset.sessionImportAction = "copy-project-path";
22461
+ const setCopyLabel = (label) => {
22462
+ copyPath.replaceChildren(createRendererSettingsIcon("copy", 15), label);
22463
+ };
22464
+ const showCopyFeedback = (label) => {
22465
+ setCopyLabel(label);
22466
+ document2.defaultView?.setTimeout(
22467
+ () => setCopyLabel(messages.sessionImportCopyProjectPath),
22468
+ 2e3
22469
+ );
22470
+ };
22471
+ setCopyLabel(messages.sessionImportCopyProjectPath);
22472
+ copyPath.addEventListener("click", () => {
22473
+ const clipboard = document2.defaultView?.navigator.clipboard;
22474
+ if (!clipboard) {
22475
+ showCopyFeedback(messages.sessionImportPathCopyFailed);
22476
+ return;
22477
+ }
22478
+ void clipboard.writeText(candidate.cwd).then(
22479
+ () => showCopyFeedback(messages.sessionImportPathCopied),
22480
+ () => showCopyFeedback(messages.sessionImportPathCopyFailed)
22481
+ );
22482
+ });
22483
+ path.append(cwd, copyPath);
22484
+ const retry = document2.createElement("button");
22485
+ retry.type = "button";
22486
+ retry.className = "settings-command-button";
22487
+ retry.dataset.sessionImportAction = "retry-open";
22488
+ const setRetrying = (pending) => {
22489
+ retry.disabled = pending;
22490
+ refresh.disabled = pending;
22491
+ retry.setAttribute("aria-busy", pending ? "true" : "false");
22492
+ retry.replaceChildren(
22493
+ createRendererSettingsIcon("refresh", 15),
22494
+ pending ? messages.sessionImportRetrying : messages.sessionImportRetryOpen
22495
+ );
22496
+ };
22497
+ setRetrying(false);
22498
+ retry.addEventListener("click", () => {
22499
+ if (retry.disabled) return;
22500
+ setRetrying(true);
22501
+ void context.runLatest((signal) => openImportedThread(threadId, signal), {
22502
+ success() {
22503
+ setRetrying(false);
22504
+ },
22505
+ failure() {
22506
+ renderOpenRecovery(candidate, threadId);
22507
+ }
22508
+ });
22509
+ });
22510
+ recovery.append(recoveryCopy, path, retry);
22511
+ content.replaceChildren(recovery);
22512
+ recovery.focus();
22513
+ };
22514
+ const renderCandidates = () => {
22515
+ actions = [];
22516
+ content.replaceChildren();
22517
+ if (candidates.length === 0) {
22518
+ content.append(createStatus(document2, messages.sessionImportEmpty));
22519
+ return;
22520
+ }
22521
+ const list = document2.createElement("div");
22522
+ list.className = "settings-session-import-list";
22523
+ for (const candidate of candidates) {
22524
+ const row = document2.createElement("article");
22525
+ row.className = "settings-session-import-row";
22526
+ row.dataset.sessionImportId = candidate.nativeSessionId;
22527
+ const copy = document2.createElement("div");
22528
+ copy.className = "settings-session-import-row__copy";
22529
+ const title = document2.createElement("strong");
22530
+ title.textContent = candidate.title ?? messages.sessionImportUntitled;
22531
+ const metadata = document2.createElement("span");
22532
+ metadata.textContent = `${messages.sessionImportUpdatedAt}: ${new Intl.DateTimeFormat(
22533
+ messages.locale === "zh-CN" ? "zh-CN" : "en",
22534
+ { dateStyle: "medium", timeStyle: "short" }
22535
+ ).format(new Date(candidate.updatedAt))}`;
22536
+ const cwd = document2.createElement("code");
22537
+ cwd.className = "settings-session-import-row__cwd";
22538
+ cwd.textContent = candidate.cwd;
22539
+ cwd.title = candidate.cwd;
22540
+ const identity = document2.createElement("span");
22541
+ identity.textContent = `${messages.sessionImportSessionId}: ${shortSessionId(candidate.nativeSessionId)}`;
22542
+ identity.title = candidate.nativeSessionId;
22543
+ identity.setAttribute("aria-hidden", "true");
22544
+ copy.append(
22545
+ title,
22546
+ metadata,
22547
+ cwd,
22548
+ identity,
22549
+ createAccessibleText(
22550
+ document2,
22551
+ `${messages.sessionImportSessionId}: ${candidate.nativeSessionId}`
22552
+ )
22553
+ );
22554
+ const actionArea = document2.createElement("div");
22555
+ actionArea.className = "settings-session-import-row__action";
22556
+ if (candidate.running) {
22557
+ const running = document2.createElement("span");
22558
+ running.className = "settings-session-import-running";
22559
+ running.textContent = messages.sessionImportRunning;
22560
+ running.title = messages.sessionImportRunningHint;
22561
+ running.setAttribute("aria-hidden", "true");
22562
+ actionArea.append(
22563
+ running,
22564
+ createAccessibleText(
22565
+ document2,
22566
+ `${messages.sessionImportRunning}: ${messages.sessionImportRunningHint}`
22567
+ )
22568
+ );
22569
+ }
22570
+ const action = document2.createElement("button");
22571
+ action.type = "button";
22572
+ action.className = "settings-command-button";
22573
+ action.dataset.sessionImportAction = "import";
22574
+ action.addEventListener("click", () => {
22575
+ if (candidate.running || importingId !== null) return;
22576
+ const client = getClient();
22577
+ if (!client) {
22578
+ renderUnavailable(true);
22579
+ return;
22580
+ }
22581
+ importingId = candidate.nativeSessionId;
22582
+ refresh.disabled = true;
22583
+ updateImportActions();
22584
+ let committedThreadId = null;
22585
+ void context.runLatest(
22586
+ async (signal) => {
22587
+ const result = await client.importDeepSeekModernSession({
22588
+ nativeSessionId: candidate.nativeSessionId
22589
+ });
22590
+ committedThreadId = result.threadId;
22591
+ await openImportedThread(result.threadId, signal);
22592
+ },
22593
+ {
22594
+ success() {
22595
+ importingId = null;
22596
+ refresh.disabled = false;
22597
+ updateImportActions();
22598
+ },
22599
+ failure(error51) {
22600
+ importingId = null;
22601
+ refresh.disabled = false;
22602
+ if (committedThreadId) {
22603
+ renderOpenRecovery(candidate, committedThreadId);
22604
+ } else {
22605
+ renderFailure(error51, "import");
22606
+ }
22607
+ }
22608
+ }
22609
+ );
22610
+ });
22611
+ actions.push({ button: action, candidate });
22612
+ actionArea.append(action);
22613
+ row.append(copy, actionArea);
22614
+ list.append(row);
22615
+ }
22616
+ content.append(list);
22617
+ updateImportActions();
22618
+ };
22619
+ const load = () => {
22620
+ if (importingId !== null) return;
22621
+ const client = getClient();
22622
+ if (!client) {
22623
+ refresh.disabled = false;
22624
+ setRefreshLabel(false);
22625
+ renderUnavailable();
22626
+ return;
22627
+ }
22628
+ refresh.disabled = true;
22629
+ setRefreshLabel(true);
22630
+ content.replaceChildren(createStatus(document2, messages.sessionImportRefreshing));
22631
+ void context.runLatest(() => client.listDeepSeekModernSessions({}), {
22632
+ success(result) {
22633
+ candidates = result.candidates;
22634
+ refresh.disabled = false;
22635
+ setRefreshLabel(false);
22636
+ renderCandidates();
22637
+ },
22638
+ failure(error51) {
22639
+ candidates = [];
22640
+ refresh.disabled = false;
22641
+ setRefreshLabel(false);
22642
+ renderFailure(error51);
22643
+ }
22644
+ });
22645
+ };
22646
+ refresh.addEventListener("click", load);
22647
+ load();
22648
+ return void 0;
22649
+ }
22650
+ });
22651
+ }
22652
+
21986
22653
  // src/settings/plugins-page.ts
21987
22654
  function adapterStatusLabel(availability, messages) {
21988
22655
  if (availability === "ready") return messages.connectionStatusReady;
@@ -22844,22 +23511,29 @@ ${error51.stderrTail}`] : []
22844
23511
  }
22845
23512
  });
22846
23513
  }
22847
- function createDefaultRendererSettingsPages(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null) {
23514
+ function createDefaultRendererSettingsPages(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null, getSessionImportClient = () => null, openImportedThread = () => Promise.reject(new Error("Imported Thread navigation is unavailable"))) {
22848
23515
  return Object.freeze([
22849
23516
  createConnectionsSettingsPage(messages, getDiagnostics),
22850
23517
  createPluginsSettingsPage(messages, getDiagnostics),
23518
+ createDeepSeekSessionImportSettingsPage(messages, getSessionImportClient, openImportedThread),
22851
23519
  updatesPage(messages, getUpdateClient),
22852
23520
  aboutPage(messages)
22853
23521
  ]);
22854
23522
  }
22855
- function createDefaultRendererSettingsRegistry(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null) {
23523
+ function createDefaultRendererSettingsRegistry(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null, getSessionImportClient = () => null, openImportedThread) {
22856
23524
  return createRendererSettingsPageRegistry(
22857
- createDefaultRendererSettingsPages(messages, getUpdateClient, getDiagnostics)
23525
+ createDefaultRendererSettingsPages(
23526
+ messages,
23527
+ getUpdateClient,
23528
+ getDiagnostics,
23529
+ getSessionImportClient,
23530
+ openImportedThread
23531
+ )
22858
23532
  );
22859
23533
  }
22860
23534
 
22861
23535
  // src/settings/shell.css
22862
- var shell_default = ':host {\n /* Inherit Codex Desktop color-scheme; light-dark() tracks the host page. */\n --settings-bg: light-dark(#ffffff, #181818);\n --settings-sidebar: light-dark(#f4f4f5, #1c1c1c);\n --settings-panel: transparent;\n --settings-text: light-dark(#171717, #f5f5f5);\n --settings-muted: light-dark(#737373, #a1a1a1);\n --settings-border: light-dark(rgb(15 23 42 / 10%), rgb(255 255 255 / 10%));\n --settings-divider: light-dark(rgb(15 23 42 / 10%), rgb(255 255 255 / 10%));\n --settings-hover: light-dark(rgb(15 23 42 / 5%), rgb(255 255 255 / 6%));\n --settings-active: light-dark(rgb(51 156 255 / 14%), rgb(51 156 255 / 12%));\n --settings-focus: #339cff;\n --settings-elevated: light-dark(#ffffff, #2c2c2e);\n --settings-inset: light-dark(rgb(15 23 42 / 4%), rgb(0 0 0 / 18%));\n --settings-surface: light-dark(rgb(15 23 42 / 3%), rgb(255 255 255 / 2%));\n --settings-surface-strong: light-dark(rgb(15 23 42 / 6%), rgb(255 255 255 / 6%));\n --settings-mark: light-dark(#52525b, #d4d8de);\n --settings-dialog-shadow: light-dark(\n 0 24px 64px rgb(15 23 42 / 16%),\n 0 24px 64px rgb(0 0 0 / 38%)\n );\n --settings-backdrop: light-dark(rgb(15 23 42 / 28%), rgb(0 0 0 / 52%));\n --settings-segmented-shadow:\n 0 0 0 0.5px light-dark(rgb(15 23 42 / 6%), rgb(0 0 0 / 4%)),\n 0 3px 1px 0 light-dark(rgb(15 23 42 / 4%), rgb(0 0 0 / 4%)),\n 0 3px 8px 0 light-dark(rgb(15 23 42 / 10%), rgb(0 0 0 / 12%));\n color: var(--settings-text);\n font:\n 14px/1.5 system-ui,\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n letter-spacing: 0;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n\nbutton,\ninput,\nselect {\n font: inherit;\n}\n\nbutton {\n color: inherit;\n}\n\n[hidden] {\n display: none !important;\n}\n\n.codexhost-settings-dialog {\n width: min(1120px, calc(100vw - 32px));\n height: min(780px, calc(100vh - 32px));\n max-width: none;\n max-height: none;\n margin: auto;\n padding: 0;\n overflow: hidden;\n color: var(--settings-text);\n background: var(--settings-bg);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n box-shadow: var(--settings-dialog-shadow);\n}\n\n.codexhost-settings-dialog::backdrop {\n background: var(--settings-backdrop);\n}\n\n.settings-frame,\n.settings-layout {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n}\n\n.settings-frame {\n display: flex;\n flex-direction: column;\n}\n\n.settings-layout {\n flex: 1;\n display: grid;\n grid-template-columns: 240px minmax(0, 1fr);\n background: var(--settings-bg);\n}\n\n.settings-sidebar {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n background: var(--settings-sidebar);\n border-right: 1px solid var(--settings-border);\n padding-top: 28px;\n}\n\n.settings-header {\n display: flex;\n align-items: center;\n min-width: 0;\n height: 64px;\n flex: none;\n padding: 0 16px;\n border-bottom: 1px solid var(--settings-border);\n}\n\n.settings-header-actions {\n display: flex;\n align-items: center;\n flex: none;\n gap: 12px;\n margin-left: auto;\n}\n\n.settings-brand {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 8px;\n}\n\n.settings-brand__mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n flex: none;\n color: var(--settings-text);\n}\n\n.settings-brand__mark .codexhost-settings-icon {\n width: 32px;\n height: 32px;\n object-fit: contain;\n}\n\n.settings-brand__copy {\n display: flex;\n min-width: 0;\n align-items: baseline;\n gap: 0;\n line-height: 20px;\n}\n\n.settings-brand__name {\n overflow: hidden;\n color: var(--settings-text);\n font-size: 14px;\n font-weight: 500;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-brand__title {\n margin-left: 14px;\n padding-left: 14px;\n color: var(--settings-muted);\n font-size: 14px;\n font-weight: 400;\n border-left: 1px solid var(--settings-border);\n}\n\n.settings-nav {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n gap: 4px;\n padding: 0 12px 16px;\n overflow-y: auto;\n}\n\n.settings-nav-section-label {\n min-height: 28px;\n padding: 7px 12px 3px;\n color: var(--settings-muted);\n font-size: 12px;\n font-weight: 600;\n line-height: 18px;\n}\n\n.settings-nav-section-label:not(:first-child) {\n margin-top: 14px;\n}\n\n.settings-nav-button {\n display: grid;\n grid-template-columns: 16px minmax(0, 1fr);\n align-items: center;\n width: 100%;\n position: relative;\n min-height: 48px;\n flex: none;\n gap: 14px;\n padding: 10px 14px;\n color: var(--settings-text);\n font-size: 14px;\n font-weight: 600;\n line-height: 21px;\n text-align: left;\n background: transparent;\n border: 0;\n border-radius: 12px;\n cursor: pointer;\n}\n\n.settings-nav-button .codexhost-settings-icon {\n width: 18px;\n height: 18px;\n opacity: 0.9;\n}\n\n.settings-nav-button:hover {\n background: var(--settings-hover);\n}\n\n.settings-nav-button[aria-current="page"] {\n background: var(--settings-active);\n color: var(--settings-focus);\n}\n\n.settings-nav-button[aria-current="page"]::before {\n position: absolute;\n left: 0;\n width: 3px;\n height: 22px;\n content: "";\n background: var(--settings-focus);\n border-radius: 0 3px 3px 0;\n}\n\n.settings-nav-button span {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-icon-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex: none;\n padding: 0;\n color: var(--settings-muted);\n background: transparent;\n border: 0;\n border-radius: 8px;\n cursor: pointer;\n}\n\n.settings-icon-button:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-icon-button:focus-visible,\n.settings-nav-button:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 1px;\n}\n\n.settings-page {\n display: block;\n position: relative;\n min-width: 0;\n min-height: 0;\n overflow-y: auto;\n background: var(--settings-bg);\n scrollbar-gutter: stable;\n}\n\n.settings-page__content {\n width: min(930px, calc(100% - 80px));\n margin-inline: auto;\n}\n\n.settings-page__content {\n min-width: 0;\n padding: 44px 0 56px;\n}\n\n.settings-section-label {\n min-height: auto;\n padding: 0 0 28px;\n color: var(--settings-text);\n font-size: 24px;\n font-weight: 600;\n line-height: 30px;\n}\n\n.settings-status-list,\n.settings-empty {\n overflow: hidden;\n background: var(--settings-panel);\n}\n\n.settings-status-row {\n display: grid;\n grid-template-columns: minmax(170px, 1fr) auto minmax(280px, 1.45fr);\n position: relative;\n align-items: center;\n min-height: 88px;\n gap: 28px;\n padding: 16px 0;\n}\n\n.settings-status-row:not(:last-child)::after {\n content: "";\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n height: 1px;\n background: var(--settings-divider);\n}\n\n.settings-status-row__identity {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n color: var(--settings-text);\n gap: 14px;\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n.settings-status-row__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 44px;\n height: 44px;\n flex: none;\n color: var(--settings-muted);\n background: var(--settings-surface-strong);\n border-radius: 50%;\n}\n\n.settings-status-badge {\n flex: none;\n padding: 5px 12px;\n color: var(--settings-muted);\n font-size: 13px;\n font-weight: 500;\n line-height: 18px;\n background: var(--settings-surface-strong);\n border: 1px solid var(--settings-border);\n border-radius: 6px;\n}\n\n.settings-status-row__detail {\n min-width: 0;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-page-description {\n max-width: 760px;\n margin: -12px 0 24px;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-preference-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 32px;\n min-height: 88px;\n padding: 18px 0;\n border-top: 1px solid var(--settings-divider);\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-preference-row__copy {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n min-width: 0;\n gap: 5px;\n}\n\n.settings-preference-row__copy strong {\n color: var(--settings-text);\n font-size: 15px;\n font-weight: 600;\n line-height: 22px;\n}\n\n.settings-preference-row__copy span {\n max-width: 680px;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-preference-switch {\n display: inline-flex;\n align-items: center;\n width: 42px;\n height: 24px;\n flex: none;\n padding: 2px;\n border: 0;\n border-radius: 999px;\n background: var(--settings-surface-strong);\n cursor: pointer;\n transition: background 120ms ease;\n}\n\n.settings-preference-switch[aria-checked="true"] {\n justify-content: flex-end;\n background: var(--settings-focus);\n}\n\n.settings-preference-switch:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 2px;\n}\n\n.settings-preference-switch__thumb {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: white;\n box-shadow: 0 1px 3px rgb(0 0 0 / 35%);\n}\n\n.settings-connection-page-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 24px;\n margin-bottom: 24px;\n}\n\n.settings-connection-page-header .settings-section-label {\n padding-bottom: 0;\n}\n\n.settings-connection-page-header .settings-page-description {\n margin: 8px 0 0;\n}\n\n.settings-connections-content,\n.settings-plugins-content,\n.settings-connection-list,\n.settings-connection-rows {\n min-width: 0;\n}\n\n.settings-connections-content,\n.settings-plugins-content {\n display: grid;\n gap: 12px;\n}\n\n.settings-connection-list {\n overflow: hidden;\n background: var(--settings-surface);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n}\n\n.settings-segmented {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: center;\n width: fit-content;\n max-width: 100%;\n padding: 2px;\n gap: 3px;\n background: var(--settings-surface-strong);\n border-radius: 10px;\n}\n\n.settings-segmented__item {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-height: 28px;\n padding: 4px 14px;\n color: var(--settings-muted);\n font: inherit;\n font-size: 12px;\n font-weight: 600;\n line-height: 18px;\n white-space: nowrap;\n background: transparent;\n border: 0;\n border-radius: 8px;\n cursor: pointer;\n transition:\n color 0.15s ease,\n background-color 0.15s ease,\n box-shadow 0.15s ease;\n}\n\n.settings-segmented__item:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-segmented__item--selected,\n.settings-segmented__item[aria-selected="true"] {\n color: var(--settings-text);\n background: var(--settings-elevated);\n box-shadow: var(--settings-segmented-shadow);\n}\n\n.settings-segmented__item:focus-visible,\n.settings-connection-row:focus-visible,\n.settings-connection-install-link:focus-visible,\n.settings-connection-view-error:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 1px;\n}\n\n.settings-connection-table-header,\n.settings-connection-row {\n display: grid;\n /* Component : Status : Actions = 4 : 3 : 3 */\n grid-template-columns: minmax(0, 4fr) minmax(0, 3fr) minmax(0, 3fr);\n align-items: center;\n min-width: 0;\n column-gap: 16px;\n}\n\n.settings-connection-table-header {\n min-height: 36px;\n padding: 0 12px;\n color: var(--settings-muted);\n font-size: 10px;\n font-weight: 600;\n line-height: 16px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n background: var(--settings-surface);\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-rows > .settings-connection-row,\n.settings-connection-rows > .settings-connection-block {\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-rows > .settings-connection-row:last-child,\n.settings-connection-rows > .settings-connection-block:last-child {\n border-bottom: 0;\n}\n\n.settings-connection-row {\n min-height: 64px;\n padding: 10px 12px;\n cursor: pointer;\n}\n\n.settings-connection-row:hover {\n background: var(--settings-hover);\n}\n\n.settings-connection-row[data-connection-selected="true"] {\n background: var(--settings-active);\n}\n\n.settings-connection-row__identity,\n.settings-connection-inspector__identity {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n gap: 9px;\n color: var(--settings-text);\n}\n\n.settings-connection-row__identity strong,\n.settings-connection-inspector__identity strong {\n min-width: 0;\n overflow-wrap: anywhere;\n font-size: 13px;\n font-weight: 600;\n line-height: 19px;\n}\n\n.settings-connection-row__mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex: none;\n color: var(--settings-mark);\n font-size: 10px;\n font-weight: 700;\n background: var(--settings-surface-strong);\n border-radius: 7px;\n}\n\n.settings-connection-row__mark--logo {\n color: var(--settings-text);\n background: transparent;\n}\n\n.settings-connection-row__mark--logo > img,\n.settings-connection-row__mark--logo > svg {\n display: block;\n max-width: 22px;\n max-height: 22px;\n}\n\n.settings-connection-table-header > :last-child {\n text-align: end;\n}\n\n.settings-connection-row__status {\n display: inline-flex;\n align-items: center;\n width: fit-content;\n max-width: 100%;\n gap: 6px;\n color: var(--settings-muted);\n font-size: 12px;\n font-weight: 500;\n line-height: 18px;\n}\n\n.settings-connection-row__status::before {\n width: 7px;\n height: 7px;\n flex: none;\n content: "";\n background: currentColor;\n border-radius: 50%;\n}\n\n.settings-connection-row__status[data-connection-tone="ready"] {\n color: #4ade80;\n}\n\n.settings-connection-row__status[data-connection-tone="checking"] {\n color: #f5c542;\n}\n\n.settings-connection-row__status[data-connection-tone="setup"] {\n color: var(--settings-muted);\n}\n\n.settings-connection-row__status[data-connection-tone="setup"]::before {\n background: transparent;\n border: 1.5px solid currentColor;\n}\n\n.settings-connection-row__status[data-connection-tone="failed"] {\n color: #f87171;\n}\n\n.settings-connection-row__action {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n min-width: 0;\n gap: 4px;\n}\n\n.settings-connection-row__handle {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 16px;\n color: var(--settings-muted);\n cursor: grab;\n opacity: 0.6;\n}\n\n.settings-connection-row__handle:hover {\n opacity: 1;\n}\n\n.settings-connection-row[draggable="true"] {\n cursor: grab;\n}\n\n.settings-connection-row[data-connection-dragging="true"] {\n opacity: 0.4;\n}\n\n.settings-connection-row[data-connection-drop-indicator="before"] {\n box-shadow: inset 0 2px 0 0 var(--settings-focus);\n}\n\n.settings-connection-row[data-connection-drop-indicator="after"] {\n box-shadow: inset 0 -2px 0 0 var(--settings-focus);\n}\n\n.settings-connection-inline-detail {\n display: grid;\n gap: 12px;\n margin-top: 2px;\n padding: 14px 12px 16px;\n border-top: 1px solid var(--settings-divider);\n background: var(--settings-inset);\n}\n\n.settings-connection-group-divider {\n padding: 10px 12px 6px;\n color: var(--settings-muted);\n font-size: 10px;\n font-weight: 600;\n line-height: 16px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n /* No border-top here: the row immediately above already carries its own\n border-bottom (it is no longer :last-child once this divider follows\n it), so adding one here would double the separator line. */\n}\n\n.settings-connection-group-divider[data-connection-drag-over="true"] {\n color: var(--settings-focus);\n background: rgb(51 156 255 / 8%);\n border-radius: 6px;\n}\n\n.settings-connection-group-more[data-connection-drag-over="true"] {\n background: rgb(51 156 255 / 8%);\n}\n\n.settings-connection-group-hint {\n display: grid;\n gap: 3px;\n margin: 0 12px 12px;\n padding: 14px 16px;\n text-align: center;\n border: 1.5px dashed var(--settings-border);\n border-radius: 10px;\n}\n\n.settings-connection-group-more[data-connection-drag-over="true"] .settings-connection-group-hint {\n border-color: var(--settings-focus);\n}\n\n.settings-connection-group-hint strong {\n color: var(--settings-text);\n font-size: 12.5px;\n font-weight: 500;\n line-height: 18px;\n}\n\n.settings-connection-group-hint span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 17px;\n}\n\n.settings-connection-group-reset {\n display: flex;\n width: 100%;\n align-items: center;\n gap: 6px;\n padding: 10px 12px;\n color: var(--settings-muted);\n font: inherit;\n font-size: 12px;\n text-align: left;\n background: transparent;\n border: 0;\n border-top: 1px solid var(--settings-divider);\n cursor: pointer;\n}\n\n.settings-connection-group-reset:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-connection-install-link {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n color: var(--settings-focus);\n text-decoration: none;\n background: transparent;\n border: 1px solid transparent;\n border-radius: 7px;\n}\n\n.settings-connection-install-link:hover {\n color: #8cc5ff;\n background: rgb(51 156 255 / 10%);\n border-color: rgb(51 156 255 / 22%);\n}\n\n.settings-connection-view-error {\n padding: 4px 7px;\n color: #f87171;\n font: inherit;\n font-size: 11px;\n line-height: 18px;\n background: transparent;\n border: 0;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.settings-connection-view-error:hover {\n color: #fca5a5;\n background: rgb(239 68 68 / 9%);\n}\n\n.settings-connection-inspector {\n position: sticky;\n top: 24px;\n}\n\n.settings-connection-inspector__header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n min-width: 0;\n gap: 12px;\n padding: 16px;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-inspector__body {\n display: grid;\n min-width: 0;\n gap: 14px;\n padding: 16px;\n}\n\n.settings-connection-install-callout {\n display: grid;\n grid-template-columns: 32px minmax(0, 1fr);\n gap: 10px;\n padding: 14px;\n background: linear-gradient(rgb(51 156 255 / 8%), rgb(51 156 255 / 4%));\n border: 1px solid rgb(51 156 255 / 20%);\n border-radius: 10px;\n}\n\n.settings-connection-install-callout__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n color: var(--settings-focus);\n background: var(--settings-active);\n border-radius: 8px;\n}\n\n.settings-connection-install-callout strong,\n.settings-connection-error-summary strong,\n.settings-connection-state-summary strong {\n display: block;\n margin: 0 0 4px;\n color: var(--settings-text);\n font-size: 13px;\n font-weight: 600;\n line-height: 19px;\n}\n\n.settings-connection-install-callout p,\n.settings-connection-error-summary p,\n.settings-connection-state-summary p,\n.settings-connection-issue-note {\n margin: 0;\n color: var(--settings-muted);\n font-size: 11px;\n line-height: 17px;\n}\n\n.settings-connection-install-button {\n width: 100%;\n}\n\n.settings-connection-error-summary {\n padding: 13px 14px;\n color: #fecaca;\n background: rgb(239 68 68 / 7%);\n border: 1px solid rgb(239 68 68 / 20%);\n border-radius: 10px;\n}\n\n.settings-connection-error-metadata {\n display: grid;\n gap: 7px;\n padding: 12px;\n background: var(--settings-inset);\n border: 1px solid var(--settings-border);\n border-radius: 9px;\n}\n\n.settings-connection-detail-line {\n display: grid;\n grid-template-columns: 92px minmax(0, 1fr);\n gap: 10px;\n min-width: 0;\n color: var(--settings-muted);\n font-size: 10px;\n line-height: 16px;\n}\n\n.settings-connection-detail-line code {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n white-space: pre-wrap;\n}\n\n.settings-connection-error-log-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 10px;\n}\n\n.settings-connection-error-log-header strong {\n color: var(--settings-text);\n font-size: 11px;\n font-weight: 600;\n}\n\n.settings-connection-error-log-header .settings-command-button {\n min-height: 30px;\n padding: 5px 9px;\n font-size: 11px;\n}\n\n.settings-connection-stderr {\n max-height: 220px;\n min-width: 0;\n margin: 0;\n padding: 11px;\n overflow: auto;\n color: var(--settings-text);\n font:\n 10px/16px ui-monospace,\n "SFMono-Regular",\n Consolas,\n "Liberation Mono",\n monospace;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n background: var(--settings-inset);\n border: 1px solid var(--settings-border);\n border-radius: 9px;\n}\n\n.settings-connection-error-actions {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n gap: 8px;\n}\n\n.settings-connection-error-actions .settings-command-button {\n width: 100%;\n}\n\n.settings-connection-issue-note {\n margin-top: -4px;\n}\n\n.settings-connection-state-summary {\n padding: 14px;\n background: var(--settings-surface);\n border: 1px solid var(--settings-border);\n border-radius: 10px;\n}\n\n.settings-empty {\n display: flex;\n align-items: center;\n min-height: 72px;\n padding: 12px 16px;\n}\n\n.settings-empty > div {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n\n.settings-empty strong {\n color: var(--settings-text);\n font-size: 13px;\n font-weight: 500;\n line-height: 19px;\n}\n\n.settings-empty span {\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 19px;\n}\n\n.settings-about-page {\n display: flex;\n flex-direction: column;\n gap: 18px;\n box-sizing: border-box;\n min-height: min(620px, calc(100vh - 200px));\n max-width: 720px;\n}\n\n.settings-about-page > .settings-section-label {\n padding-bottom: 10px;\n}\n\n.settings-about-panel {\n display: grid;\n gap: 18px;\n padding: 28px;\n background: rgb(255 255 255 / 2%);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n}\n\n.settings-about-product {\n color: var(--settings-text);\n font-size: 24px;\n font-weight: 700;\n line-height: 32px;\n}\n\n.settings-about-tagline {\n color: var(--settings-text);\n font-size: 16px;\n font-weight: 600;\n line-height: 24px;\n}\n\n.settings-about-copy {\n display: grid;\n max-width: 660px;\n gap: 12px;\n}\n\n.settings-about-lead,\n.settings-about-extension,\n.settings-about-closing p,\n.settings-about-copy p {\n margin: 0;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 21px;\n}\n\n.settings-about-lead {\n color: var(--settings-text);\n font-weight: 500;\n}\n\n.settings-about-agents {\n display: grid;\n gap: 10px;\n margin: 2px 0;\n padding: 0;\n list-style: none;\n}\n\n.settings-about-agent {\n display: grid;\n gap: 4px;\n padding-left: 2px;\n}\n\n.settings-about-agent-name {\n color: var(--settings-text);\n font-size: 13px;\n font-weight: 600;\n line-height: 18px;\n}\n\n.settings-about-agent-name::before {\n content: "\xB7 ";\n color: var(--settings-muted);\n font-weight: 600;\n}\n\n.settings-about-agent-description {\n display: block;\n padding-left: 0.85em;\n color: var(--settings-muted);\n font-size: 12px;\n font-weight: 400;\n line-height: 18px;\n}\n\n.settings-about-closing {\n display: grid;\n gap: 8px;\n}\n\n.settings-about-repository {\n gap: 10px;\n}\n\n.settings-about-open-source {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 0.35em;\n margin: 0;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 21px;\n}\n\n.settings-about-repository p {\n margin: 0;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 21px;\n}\n\n.settings-about-star-callout {\n margin: 4px 0 0;\n color: #f5c542;\n font-size: 14px;\n font-weight: 600;\n line-height: 22px;\n}\n\n.settings-about-repository-link {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n color: #7cb8ff;\n font-weight: 600;\n line-height: 1;\n text-decoration: none;\n}\n\n.settings-about-repository-link .codexhost-settings-icon {\n display: block;\n flex: none;\n}\n\n.settings-about-repository-link:hover {\n text-decoration: underline;\n}\n\n.settings-about-brand {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n margin-top: auto;\n padding-top: 12px;\n color: inherit;\n opacity: 0.9;\n text-decoration: none;\n transition: opacity 160ms ease;\n}\n\n.settings-about-brand:hover {\n opacity: 1;\n}\n\n.settings-about-brand-video {\n width: 40px;\n height: 40px;\n flex: none;\n overflow: hidden;\n object-fit: cover;\n border-radius: 999px;\n box-shadow: 0 1px 2px rgb(0 0 0 / 18%);\n}\n\n.settings-about-brand-copy {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 2px;\n}\n\n.settings-about-brand-name {\n color: var(--settings-text);\n font-size: 14px;\n font-weight: 800;\n letter-spacing: 0.18em;\n line-height: 18px;\n}\n\n.settings-about-brand-tagline {\n color: var(--settings-muted);\n font-size: 12px;\n font-weight: 500;\n letter-spacing: 0.18em;\n line-height: 16px;\n}\n\n.settings-page-error {\n padding: 16px;\n color: var(--settings-text);\n font-size: 13px;\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 20px;\n}\n\n.settings-update-metadata {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 24px;\n margin-bottom: 24px;\n padding: 0 4px 20px;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-update-metadata__item {\n display: grid;\n min-width: 0;\n gap: 4px;\n}\n\n.settings-update-metadata__item span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-metadata__item strong {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n/* The only emphasis on this screen: a latest version newer than the installed one. */\n.settings-update-metadata__value--newer {\n color: #4aa3f0;\n}\n\n.settings-update-panel {\n display: grid;\n gap: 12px;\n padding: 20px;\n color: var(--settings-text);\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\n}\n\n/* Soft status copy (unavailable / request failure) should not sit in a framed card. */\n.settings-update-panel[data-update-state="unavailable"],\n.settings-update-panel[data-update-state="failed"],\n.settings-update-panel[data-update-state="error"] {\n padding: 4px 0 0;\n border: 0;\n border-radius: 0;\n}\n\n.settings-update-panel__status-row {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px;\n min-width: 0;\n}\n\n.settings-update-panel__status-row .settings-update-actions {\n flex: none;\n}\n\n.settings-update-panel__status-row .settings-update-panel__head {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.settings-update-panel__head {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 8px;\n}\n\n.settings-update-panel__head .codexhost-settings-icon {\n color: var(--settings-muted);\n}\n\n.settings-update-panel[data-update-state="available"]\n .settings-update-panel__head\n .codexhost-settings-icon,\n.settings-update-panel[data-update-state="downloading"]\n .settings-update-panel__head\n .codexhost-settings-icon,\n.settings-update-panel[data-update-state="installing"]\n .settings-update-panel__head\n .codexhost-settings-icon,\n.settings-update-panel[data-update-state="restarting"]\n .settings-update-panel__head\n .codexhost-settings-icon {\n color: #4aa3f0;\n}\n\n.settings-update-panel[data-update-state="current"]\n .settings-update-panel__head\n .codexhost-settings-icon {\n color: #4ade80;\n}\n\n.settings-update-panel[data-update-state="failed"]\n .settings-update-panel__head\n .codexhost-settings-icon,\n.settings-update-panel[data-update-state="error"]\n .settings-update-panel__head\n .codexhost-settings-icon {\n color: #ef4444;\n}\n\n.settings-update-panel[data-update-state="unavailable"]\n .settings-update-panel__head\n .codexhost-settings-icon {\n color: var(--settings-muted);\n}\n\n.settings-update-panel__title {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-size: 14px;\n font-weight: 600;\n line-height: 22px;\n}\n\n.settings-update-summary,\n.settings-update-error {\n margin: 0;\n overflow-wrap: anywhere;\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-update-summary {\n color: var(--settings-muted);\n}\n\n.settings-update-error {\n color: #ef4444;\n}\n\n.settings-update-progress {\n width: 100%;\n height: 8px;\n accent-color: #238be8;\n}\n\n.settings-update-progress-detail {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n/* Release notes scroll with the page; a scroller inside a scroller traps the wheel. */\n.settings-update-notes-section {\n min-width: 0;\n margin-top: 24px;\n padding-top: 24px;\n border-top: 1px solid var(--settings-divider);\n}\n\n.settings-update-notes-section:empty {\n display: none;\n}\n\n.settings-update-notes {\n display: grid;\n min-width: 0;\n gap: 12px;\n color: var(--settings-muted);\n font-size: 14px;\n line-height: 22px;\n overflow-wrap: anywhere;\n}\n\n.settings-update-notes > :first-child {\n margin-top: 0;\n}\n\n.settings-update-notes > :last-child {\n margin-bottom: 0;\n}\n\n.settings-update-notes h1,\n.settings-update-notes h2,\n.settings-update-notes h3,\n.settings-update-notes h4,\n.settings-update-notes h5,\n.settings-update-notes h6 {\n margin: 6px 0 0;\n color: var(--settings-text);\n font-weight: 600;\n}\n\n.settings-update-notes h1 {\n font-size: 18px;\n line-height: 26px;\n}\n\n.settings-update-notes h2 {\n font-size: 17px;\n line-height: 24px;\n}\n\n.settings-update-notes h3,\n.settings-update-notes h4,\n.settings-update-notes h5,\n.settings-update-notes h6 {\n font-size: 14px;\n line-height: 22px;\n}\n\n.settings-update-notes p,\n.settings-update-notes ul,\n.settings-update-notes ol,\n.settings-update-notes pre,\n.settings-update-notes blockquote {\n margin: 0;\n}\n\n.settings-update-notes ul,\n.settings-update-notes ol {\n padding-left: 24px;\n}\n\n.settings-update-notes li {\n padding-left: 4px;\n}\n\n.settings-update-notes li::marker {\n color: var(--settings-muted);\n font-size: 0.85em;\n}\n\n.settings-update-notes li + li {\n margin-top: 14px;\n}\n\n.settings-update-notes .release-note-translation {\n display: block;\n margin-top: 3px;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-update-notes blockquote {\n padding: 8px 12px;\n color: var(--settings-muted);\n border-left: 3px solid var(--settings-focus);\n background: var(--settings-surface);\n}\n\n.settings-update-notes hr {\n width: 100%;\n margin: 2px 0;\n border: 0;\n border-top: 1px solid var(--settings-divider);\n}\n\n.settings-update-notes strong {\n color: var(--settings-text);\n font-weight: 600;\n}\n\n.settings-update-notes a {\n color: #7cb8ff;\n text-decoration: none;\n}\n\n.settings-update-notes a:hover {\n text-decoration: underline;\n}\n\n.settings-update-notes code {\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n}\n\n.settings-update-notes :not(pre) > code {\n padding: 1px 5px;\n background: var(--settings-surface-strong);\n border-radius: 4px;\n}\n\n.settings-update-notes pre {\n min-width: 0;\n max-width: 100%;\n padding: 10px 12px;\n overflow-x: auto;\n overflow-y: hidden;\n background: var(--settings-inset);\n border-radius: 6px;\n}\n\n.settings-update-notes pre code {\n line-height: 18px;\n white-space: pre-wrap;\n}\n\n/* Manual update sits directly under the status panel, not behind a disclosure:\n automatic updates can fail for machine-local reasons and this is the way out. */\n.settings-update-controls {\n display: grid;\n min-width: 0;\n gap: 10px;\n margin-top: 24px;\n}\n\n.settings-update-manual-title {\n color: var(--settings-text);\n font-size: 15px;\n font-weight: 600;\n line-height: 22px;\n}\n\n.settings-update-manual {\n display: grid;\n min-width: 0;\n gap: 8px;\n}\n\n.settings-update-manual[hidden] {\n display: none;\n}\n\n.settings-update-manual-description {\n margin: 0;\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-manual-description.is-fallback {\n color: #ef4444;\n}\n\n.settings-update-command {\n display: flex;\n align-items: stretch;\n min-width: 0;\n overflow: hidden;\n border: 1px solid var(--settings-border);\n border-radius: 6px;\n}\n\n.settings-update-command code {\n min-width: 0;\n flex: 1;\n padding: 9px 12px;\n overflow-x: auto;\n color: var(--settings-text);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n line-height: 20px;\n white-space: nowrap;\n}\n\n.settings-update-command__copy {\n display: inline-flex;\n align-items: center;\n flex: none;\n gap: 6px;\n padding: 0 12px;\n color: var(--settings-muted);\n font-size: 12px;\n background: transparent;\n border: 0;\n border-left: 1px solid var(--settings-border);\n cursor: pointer;\n}\n\n.settings-update-command__copy:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-update-command__copy:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: -2px;\n}\n\n.settings-update-actions {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.settings-command-button,\n.settings-update-link {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: fit-content;\n min-height: 36px;\n gap: 8px;\n padding: 8px 12px;\n color: white;\n font: inherit;\n font-size: 13px;\n text-decoration: none;\n background: #1677d2;\n border: 1px solid #238be8;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.settings-command-button--secondary,\n.settings-update-link {\n color: var(--settings-muted);\n background: transparent;\n border-color: var(--settings-border);\n}\n\n.settings-command-button--secondary .codexhost-settings-icon,\n.settings-update-link .codexhost-settings-icon {\n color: var(--settings-muted);\n}\n\n.settings-command-button:hover:not(.settings-command-button--secondary) {\n filter: brightness(1.08);\n}\n\n.settings-command-button--secondary:hover,\n.settings-update-link:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-command-button--secondary:hover .codexhost-settings-icon,\n.settings-update-link:hover .codexhost-settings-icon {\n color: var(--settings-text);\n}\n\n.settings-command-button:focus-visible,\n.settings-update-link:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 2px;\n}\n\n.codexhost-settings-icon {\n display: block;\n flex: none;\n stroke: currentColor;\n}\n\n@media (max-width: 720px) {\n .codexhost-settings-dialog {\n width: calc(100vw - 16px);\n height: calc(100vh - 16px);\n border-radius: 10px;\n }\n\n .settings-layout {\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr);\n }\n\n .settings-sidebar {\n border-right: 0;\n border-bottom: 1px solid var(--settings-border);\n }\n\n .settings-header {\n height: 56px;\n padding-inline: 14px;\n }\n\n .settings-sidebar {\n padding-top: 20px;\n }\n\n .settings-nav {\n flex: none;\n flex-direction: row;\n gap: 4px;\n padding: 7px 8px 8px;\n overflow-x: auto;\n overflow-y: hidden;\n }\n\n .settings-nav-section-label {\n display: none;\n }\n\n .settings-nav-button {\n width: auto;\n min-width: max-content;\n min-height: 34px;\n grid-template-columns: 16px auto;\n border-radius: 10px;\n }\n\n .settings-page__content {\n width: calc(100% - 40px);\n }\n\n .settings-page__content {\n padding-top: 32px;\n padding-bottom: 32px;\n }\n\n .settings-section-label {\n padding-bottom: 20px;\n font-size: 20px;\n line-height: 26px;\n }\n\n .settings-update-metadata {\n grid-template-columns: minmax(0, 1fr);\n gap: 16px;\n }\n\n .settings-status-row {\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 16px;\n }\n\n .settings-connection-page-header {\n flex-direction: column;\n }\n\n .settings-connection-page-header > .settings-command-button {\n width: 100%;\n }\n\n .settings-status-row__detail {\n grid-column: 1 / -1;\n margin: -8px 0 0 58px;\n }\n}\n\n@media (forced-colors: active) {\n :host,\n :host([data-theme="light"]),\n :host([data-theme="dark"]) {\n --settings-bg: Canvas;\n --settings-sidebar: Canvas;\n --settings-panel: Canvas;\n --settings-text: CanvasText;\n --settings-muted: GrayText;\n --settings-border: ButtonBorder;\n --settings-divider: ButtonBorder;\n --settings-hover: Highlight;\n --settings-active: Highlight;\n --settings-focus: Highlight;\n --settings-elevated: Canvas;\n --settings-inset: Canvas;\n --settings-surface: Canvas;\n --settings-surface-strong: Canvas;\n --settings-mark: CanvasText;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n scroll-behavior: auto !important;\n }\n}\n';
23536
+ var shell_default = ':host {\n /* Inherit Codex Desktop color-scheme; light-dark() tracks the host page. */\n --settings-bg: light-dark(#ffffff, #181818);\n --settings-sidebar: light-dark(#f4f4f5, #1c1c1c);\n --settings-panel: transparent;\n --settings-text: light-dark(#171717, #f5f5f5);\n --settings-muted: light-dark(#737373, #a1a1a1);\n --settings-border: light-dark(rgb(15 23 42 / 10%), rgb(255 255 255 / 10%));\n --settings-divider: light-dark(rgb(15 23 42 / 10%), rgb(255 255 255 / 10%));\n --settings-hover: light-dark(rgb(15 23 42 / 5%), rgb(255 255 255 / 6%));\n --settings-active: light-dark(rgb(51 156 255 / 14%), rgb(51 156 255 / 12%));\n --settings-focus: #339cff;\n --settings-elevated: light-dark(#ffffff, #2c2c2e);\n --settings-inset: light-dark(rgb(15 23 42 / 4%), rgb(0 0 0 / 18%));\n --settings-surface: light-dark(rgb(15 23 42 / 3%), rgb(255 255 255 / 2%));\n --settings-surface-strong: light-dark(rgb(15 23 42 / 6%), rgb(255 255 255 / 6%));\n --settings-mark: light-dark(#52525b, #d4d8de);\n --settings-dialog-shadow: light-dark(\n 0 24px 64px rgb(15 23 42 / 16%),\n 0 24px 64px rgb(0 0 0 / 38%)\n );\n --settings-backdrop: light-dark(rgb(15 23 42 / 28%), rgb(0 0 0 / 52%));\n --settings-segmented-shadow:\n 0 0 0 0.5px light-dark(rgb(15 23 42 / 6%), rgb(0 0 0 / 4%)),\n 0 3px 1px 0 light-dark(rgb(15 23 42 / 4%), rgb(0 0 0 / 4%)),\n 0 3px 8px 0 light-dark(rgb(15 23 42 / 10%), rgb(0 0 0 / 12%));\n color: var(--settings-text);\n font:\n 14px/1.5 system-ui,\n -apple-system,\n BlinkMacSystemFont,\n "Segoe UI",\n sans-serif;\n letter-spacing: 0;\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n letter-spacing: 0;\n}\n\nbutton,\ninput,\nselect {\n font: inherit;\n}\n\nbutton {\n color: inherit;\n}\n\n[hidden] {\n display: none !important;\n}\n\n.codexhost-settings-dialog {\n width: min(1120px, calc(100vw - 32px));\n height: min(780px, calc(100vh - 32px));\n max-width: none;\n max-height: none;\n margin: auto;\n padding: 0;\n overflow: hidden;\n color: var(--settings-text);\n background: var(--settings-bg);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n box-shadow: var(--settings-dialog-shadow);\n}\n\n.codexhost-settings-dialog::backdrop {\n background: var(--settings-backdrop);\n}\n\n.settings-frame,\n.settings-layout {\n width: 100%;\n height: 100%;\n min-width: 0;\n min-height: 0;\n}\n\n.settings-frame {\n display: flex;\n flex-direction: column;\n}\n\n.settings-layout {\n flex: 1;\n display: grid;\n grid-template-columns: 240px minmax(0, 1fr);\n background: var(--settings-bg);\n}\n\n.settings-sidebar {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex-direction: column;\n overflow: hidden;\n background: var(--settings-sidebar);\n border-right: 1px solid var(--settings-border);\n padding-top: 28px;\n}\n\n.settings-header {\n display: flex;\n align-items: center;\n min-width: 0;\n height: 64px;\n flex: none;\n padding: 0 16px;\n border-bottom: 1px solid var(--settings-border);\n}\n\n.settings-header-actions {\n display: flex;\n align-items: center;\n flex: none;\n gap: 12px;\n margin-left: auto;\n}\n\n.settings-brand {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 8px;\n}\n\n.settings-brand__mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n flex: none;\n color: var(--settings-text);\n}\n\n.settings-brand__mark .codexhost-settings-icon {\n width: 32px;\n height: 32px;\n object-fit: contain;\n}\n\n.settings-brand__copy {\n display: flex;\n min-width: 0;\n align-items: baseline;\n gap: 0;\n line-height: 20px;\n}\n\n.settings-brand__name {\n overflow: hidden;\n color: var(--settings-text);\n font-size: 14px;\n font-weight: 500;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-brand__title {\n margin-left: 14px;\n padding-left: 14px;\n color: var(--settings-muted);\n font-size: 14px;\n font-weight: 400;\n border-left: 1px solid var(--settings-border);\n}\n\n.settings-nav {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex: 1;\n flex-direction: column;\n gap: 4px;\n padding: 0 12px 16px;\n overflow-y: auto;\n}\n\n.settings-nav-section-label {\n min-height: 28px;\n padding: 7px 12px 3px;\n color: var(--settings-muted);\n font-size: 12px;\n font-weight: 600;\n line-height: 18px;\n}\n\n.settings-nav-section-label:not(:first-child) {\n margin-top: 14px;\n}\n\n.settings-nav-button {\n display: grid;\n grid-template-columns: 16px minmax(0, 1fr);\n align-items: center;\n width: 100%;\n position: relative;\n min-height: 48px;\n flex: none;\n gap: 14px;\n padding: 10px 14px;\n color: var(--settings-text);\n font-size: 14px;\n font-weight: 600;\n line-height: 21px;\n text-align: left;\n background: transparent;\n border: 0;\n border-radius: 12px;\n cursor: pointer;\n}\n\n.settings-nav-button .codexhost-settings-icon {\n width: 18px;\n height: 18px;\n opacity: 0.9;\n}\n\n.settings-nav-button:hover {\n background: var(--settings-hover);\n}\n\n.settings-nav-button[aria-current="page"] {\n background: var(--settings-active);\n color: var(--settings-focus);\n}\n\n.settings-nav-button[aria-current="page"]::before {\n position: absolute;\n left: 0;\n width: 3px;\n height: 22px;\n content: "";\n background: var(--settings-focus);\n border-radius: 0 3px 3px 0;\n}\n\n.settings-nav-button span {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-icon-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex: none;\n padding: 0;\n color: var(--settings-muted);\n background: transparent;\n border: 0;\n border-radius: 8px;\n cursor: pointer;\n}\n\n.settings-icon-button:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-icon-button:focus-visible,\n.settings-nav-button:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 1px;\n}\n\n.settings-page {\n display: block;\n position: relative;\n min-width: 0;\n min-height: 0;\n overflow-y: auto;\n background: var(--settings-bg);\n scrollbar-gutter: stable;\n}\n\n.settings-page__content {\n width: min(930px, calc(100% - 80px));\n margin-inline: auto;\n}\n\n.settings-page__content {\n min-width: 0;\n padding: 44px 0 56px;\n}\n\n.settings-section-label {\n min-height: auto;\n padding: 0 0 28px;\n color: var(--settings-text);\n font-size: 24px;\n font-weight: 600;\n line-height: 30px;\n}\n\n.settings-status-list,\n.settings-empty {\n overflow: hidden;\n background: var(--settings-panel);\n}\n\n.settings-status-row {\n display: grid;\n grid-template-columns: minmax(170px, 1fr) auto minmax(280px, 1.45fr);\n position: relative;\n align-items: center;\n min-height: 88px;\n gap: 28px;\n padding: 16px 0;\n}\n\n.settings-status-row:not(:last-child)::after {\n content: "";\n position: absolute;\n right: 0;\n bottom: 0;\n left: 0;\n height: 1px;\n background: var(--settings-divider);\n}\n\n.settings-status-row__identity {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n color: var(--settings-text);\n gap: 14px;\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n.settings-status-row__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 44px;\n height: 44px;\n flex: none;\n color: var(--settings-muted);\n background: var(--settings-surface-strong);\n border-radius: 50%;\n}\n\n.settings-status-badge {\n flex: none;\n padding: 5px 12px;\n color: var(--settings-muted);\n font-size: 13px;\n font-weight: 500;\n line-height: 18px;\n background: var(--settings-surface-strong);\n border: 1px solid var(--settings-border);\n border-radius: 6px;\n}\n\n.settings-status-row__detail {\n min-width: 0;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-page-description {\n max-width: 760px;\n margin: -12px 0 24px;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-preference-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 32px;\n min-height: 88px;\n padding: 18px 0;\n border-top: 1px solid var(--settings-divider);\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-preference-row__copy {\n display: flex;\n flex: 1 1 auto;\n flex-direction: column;\n min-width: 0;\n gap: 5px;\n}\n\n.settings-preference-row__copy strong {\n color: var(--settings-text);\n font-size: 15px;\n font-weight: 600;\n line-height: 22px;\n}\n\n.settings-preference-row__copy span {\n max-width: 680px;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-preference-switch {\n display: inline-flex;\n align-items: center;\n width: 42px;\n height: 24px;\n flex: none;\n padding: 2px;\n border: 0;\n border-radius: 999px;\n background: var(--settings-surface-strong);\n cursor: pointer;\n transition: background 120ms ease;\n}\n\n.settings-preference-switch[aria-checked="true"] {\n justify-content: flex-end;\n background: var(--settings-focus);\n}\n\n.settings-preference-switch:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 2px;\n}\n\n.settings-preference-switch__thumb {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n background: white;\n box-shadow: 0 1px 3px rgb(0 0 0 / 35%);\n}\n\n.settings-connection-page-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 24px;\n margin-bottom: 24px;\n}\n\n.settings-connection-page-header .settings-section-label {\n padding-bottom: 0;\n}\n\n.settings-connection-page-header .settings-page-description {\n margin: 8px 0 0;\n}\n\n.settings-connections-content,\n.settings-plugins-content,\n.settings-connection-list,\n.settings-connection-rows {\n min-width: 0;\n}\n\n.settings-connections-content,\n.settings-plugins-content {\n display: grid;\n gap: 12px;\n}\n\n.settings-connection-list {\n overflow: hidden;\n background: var(--settings-surface);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n}\n\n.settings-segmented {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: center;\n width: fit-content;\n max-width: 100%;\n padding: 2px;\n gap: 3px;\n background: var(--settings-surface-strong);\n border-radius: 10px;\n}\n\n.settings-segmented__item {\n position: relative;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n min-height: 28px;\n padding: 4px 14px;\n color: var(--settings-muted);\n font: inherit;\n font-size: 12px;\n font-weight: 600;\n line-height: 18px;\n white-space: nowrap;\n background: transparent;\n border: 0;\n border-radius: 8px;\n cursor: pointer;\n transition:\n color 0.15s ease,\n background-color 0.15s ease,\n box-shadow 0.15s ease;\n}\n\n.settings-segmented__item:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-segmented__item--selected,\n.settings-segmented__item[aria-selected="true"],\n.settings-segmented__item[aria-pressed="true"] {\n color: var(--settings-text);\n background: var(--settings-elevated);\n box-shadow: var(--settings-segmented-shadow);\n}\n\n.settings-segmented__item:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n\n.settings-segmented__item:disabled:hover {\n color: var(--settings-muted);\n background: transparent;\n}\n\n.settings-segmented__item:focus-visible,\n.settings-connection-row:focus-visible,\n.settings-connection-install-link:focus-visible,\n.settings-connection-view-error:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 1px;\n}\n\n.settings-connection-table-header,\n.settings-connection-row {\n display: grid;\n /* Component : Status : Actions = 4 : 3 : 3 */\n grid-template-columns: minmax(0, 4fr) minmax(0, 3fr) minmax(0, 3fr);\n align-items: center;\n min-width: 0;\n column-gap: 16px;\n}\n\n.settings-connection-table-header {\n min-height: 36px;\n padding: 0 12px;\n color: var(--settings-muted);\n font-size: 10px;\n font-weight: 600;\n line-height: 16px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n background: var(--settings-surface);\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-rows > .settings-connection-row,\n.settings-connection-rows > .settings-connection-block {\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-rows > .settings-connection-row:last-child,\n.settings-connection-rows > .settings-connection-block:last-child {\n border-bottom: 0;\n}\n\n.settings-connection-row {\n min-height: 64px;\n padding: 10px 12px;\n cursor: pointer;\n}\n\n.settings-connection-row:hover {\n background: var(--settings-hover);\n}\n\n.settings-connection-row[data-connection-selected="true"] {\n background: var(--settings-active);\n}\n\n.settings-connection-row__identity,\n.settings-connection-inspector__identity {\n display: inline-flex;\n align-items: center;\n min-width: 0;\n gap: 9px;\n color: var(--settings-text);\n}\n\n.settings-connection-row__identity strong,\n.settings-connection-inspector__identity strong {\n min-width: 0;\n overflow-wrap: anywhere;\n font-size: 13px;\n font-weight: 600;\n line-height: 19px;\n}\n\n.settings-connection-row__mark {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 28px;\n height: 28px;\n flex: none;\n color: var(--settings-mark);\n font-size: 10px;\n font-weight: 700;\n background: var(--settings-surface-strong);\n border-radius: 7px;\n}\n\n.settings-connection-row__mark--logo {\n color: var(--settings-text);\n background: transparent;\n}\n\n.settings-connection-row__mark--logo > img,\n.settings-connection-row__mark--logo > svg {\n display: block;\n max-width: 22px;\n max-height: 22px;\n}\n\n.settings-connection-table-header > :last-child {\n text-align: end;\n}\n\n.settings-connection-row__status {\n display: inline-flex;\n align-items: center;\n width: fit-content;\n max-width: 100%;\n gap: 6px;\n color: var(--settings-muted);\n font-size: 12px;\n font-weight: 500;\n line-height: 18px;\n}\n\n.settings-connection-row__status::before {\n width: 7px;\n height: 7px;\n flex: none;\n content: "";\n background: currentColor;\n border-radius: 50%;\n}\n\n.settings-connection-row__status[data-connection-tone="ready"] {\n color: #4ade80;\n}\n\n.settings-connection-row__status[data-connection-tone="checking"] {\n color: #f5c542;\n}\n\n.settings-connection-row__status[data-connection-tone="setup"] {\n color: var(--settings-muted);\n}\n\n.settings-connection-row__status[data-connection-tone="setup"]::before {\n background: transparent;\n border: 1.5px solid currentColor;\n}\n\n.settings-connection-row__status[data-connection-tone="failed"] {\n color: #f87171;\n}\n\n.settings-connection-row__action {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n min-width: 0;\n gap: 4px;\n}\n\n.settings-connection-row__handle {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 16px;\n color: var(--settings-muted);\n cursor: grab;\n opacity: 0.6;\n}\n\n.settings-connection-row__handle:hover {\n opacity: 1;\n}\n\n.settings-connection-row[draggable="true"] {\n cursor: grab;\n}\n\n.settings-connection-row[data-connection-dragging="true"] {\n opacity: 0.4;\n}\n\n.settings-connection-row[data-connection-drop-indicator="before"] {\n box-shadow: inset 0 2px 0 0 var(--settings-focus);\n}\n\n.settings-connection-row[data-connection-drop-indicator="after"] {\n box-shadow: inset 0 -2px 0 0 var(--settings-focus);\n}\n\n.settings-connection-inline-detail {\n display: grid;\n gap: 12px;\n margin-top: 2px;\n padding: 14px 12px 16px;\n border-top: 1px solid var(--settings-divider);\n background: var(--settings-inset);\n}\n\n.settings-connection-group-divider {\n padding: 10px 12px 6px;\n color: var(--settings-muted);\n font-size: 10px;\n font-weight: 600;\n line-height: 16px;\n text-transform: uppercase;\n letter-spacing: 0.06em;\n /* No border-top here: the row immediately above already carries its own\n border-bottom (it is no longer :last-child once this divider follows\n it), so adding one here would double the separator line. */\n}\n\n.settings-connection-group-divider[data-connection-drag-over="true"] {\n color: var(--settings-focus);\n background: rgb(51 156 255 / 8%);\n border-radius: 6px;\n}\n\n.settings-connection-group-more[data-connection-drag-over="true"] {\n background: rgb(51 156 255 / 8%);\n}\n\n.settings-connection-group-hint {\n display: grid;\n gap: 3px;\n margin: 0 12px 12px;\n padding: 14px 16px;\n text-align: center;\n border: 1.5px dashed var(--settings-border);\n border-radius: 10px;\n}\n\n.settings-connection-group-more[data-connection-drag-over="true"] .settings-connection-group-hint {\n border-color: var(--settings-focus);\n}\n\n.settings-connection-group-hint strong {\n color: var(--settings-text);\n font-size: 12.5px;\n font-weight: 500;\n line-height: 18px;\n}\n\n.settings-connection-group-hint span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 17px;\n}\n\n.settings-connection-group-reset {\n display: flex;\n width: 100%;\n align-items: center;\n gap: 6px;\n padding: 10px 12px;\n color: var(--settings-muted);\n font: inherit;\n font-size: 12px;\n text-align: left;\n background: transparent;\n border: 0;\n border-top: 1px solid var(--settings-divider);\n cursor: pointer;\n}\n\n.settings-connection-group-reset:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-connection-install-link {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 30px;\n color: var(--settings-focus);\n text-decoration: none;\n background: transparent;\n border: 1px solid transparent;\n border-radius: 7px;\n}\n\n.settings-connection-install-link:hover {\n color: #8cc5ff;\n background: rgb(51 156 255 / 10%);\n border-color: rgb(51 156 255 / 22%);\n}\n\n.settings-connection-view-error {\n padding: 4px 7px;\n color: #f87171;\n font: inherit;\n font-size: 11px;\n line-height: 18px;\n background: transparent;\n border: 0;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.settings-connection-view-error:hover {\n color: #fca5a5;\n background: rgb(239 68 68 / 9%);\n}\n\n.settings-connection-inspector {\n position: sticky;\n top: 24px;\n}\n\n.settings-connection-inspector__header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n min-width: 0;\n gap: 12px;\n padding: 16px;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-inspector__body {\n display: grid;\n min-width: 0;\n gap: 14px;\n padding: 16px;\n}\n\n.settings-connection-install-callout {\n display: grid;\n grid-template-columns: 32px minmax(0, 1fr);\n gap: 10px;\n padding: 14px;\n background: linear-gradient(rgb(51 156 255 / 8%), rgb(51 156 255 / 4%));\n border: 1px solid rgb(51 156 255 / 20%);\n border-radius: 10px;\n}\n\n.settings-connection-install-callout__icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n color: var(--settings-focus);\n background: var(--settings-active);\n border-radius: 8px;\n}\n\n.settings-connection-install-callout strong,\n.settings-connection-error-summary strong,\n.settings-connection-state-summary strong {\n display: block;\n margin: 0 0 4px;\n color: var(--settings-text);\n font-size: 13px;\n font-weight: 600;\n line-height: 19px;\n}\n\n.settings-connection-install-callout p,\n.settings-connection-error-summary p,\n.settings-connection-state-summary p,\n.settings-connection-issue-note {\n margin: 0;\n color: var(--settings-muted);\n font-size: 11px;\n line-height: 17px;\n}\n\n.settings-connection-install-button {\n width: 100%;\n}\n\n.settings-connection-error-summary {\n padding: 13px 14px;\n color: #fecaca;\n background: rgb(239 68 68 / 7%);\n border: 1px solid rgb(239 68 68 / 20%);\n border-radius: 10px;\n}\n\n.settings-connection-error-metadata {\n display: grid;\n gap: 7px;\n padding: 12px;\n background: var(--settings-inset);\n border: 1px solid var(--settings-border);\n border-radius: 9px;\n}\n\n.settings-connection-detail-line {\n display: grid;\n grid-template-columns: 92px minmax(0, 1fr);\n gap: 10px;\n min-width: 0;\n color: var(--settings-muted);\n font-size: 10px;\n line-height: 16px;\n}\n\n.settings-connection-detail-line code {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n white-space: pre-wrap;\n}\n\n.settings-connection-error-log-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 10px;\n}\n\n.settings-connection-error-log-header strong {\n color: var(--settings-text);\n font-size: 11px;\n font-weight: 600;\n}\n\n.settings-connection-error-log-header .settings-command-button {\n min-height: 30px;\n padding: 5px 9px;\n font-size: 11px;\n}\n\n.settings-connection-stderr {\n max-height: 220px;\n min-width: 0;\n margin: 0;\n padding: 11px;\n overflow: auto;\n color: var(--settings-text);\n font:\n 10px/16px ui-monospace,\n "SFMono-Regular",\n Consolas,\n "Liberation Mono",\n monospace;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n background: var(--settings-inset);\n border: 1px solid var(--settings-border);\n border-radius: 9px;\n}\n\n.settings-connection-error-actions {\n display: grid;\n grid-template-columns: minmax(0, 1fr);\n gap: 8px;\n}\n\n.settings-connection-error-actions .settings-command-button {\n width: 100%;\n}\n\n.settings-connection-issue-note {\n margin-top: -4px;\n}\n\n.settings-connection-state-summary {\n padding: 14px;\n background: var(--settings-surface);\n border: 1px solid var(--settings-border);\n border-radius: 10px;\n}\n\n.settings-empty {\n display: flex;\n align-items: center;\n min-height: 72px;\n padding: 12px 16px;\n}\n\n.settings-empty > div {\n display: grid;\n min-width: 0;\n gap: 2px;\n}\n\n.settings-empty strong {\n color: var(--settings-text);\n font-size: 13px;\n font-weight: 500;\n line-height: 19px;\n}\n\n.settings-empty span {\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 19px;\n}\n\n.settings-about-page {\n display: flex;\n flex-direction: column;\n gap: 18px;\n box-sizing: border-box;\n min-height: min(620px, calc(100vh - 200px));\n max-width: 720px;\n}\n\n.settings-about-page > .settings-section-label {\n padding-bottom: 10px;\n}\n\n.settings-about-panel {\n display: grid;\n gap: 18px;\n padding: 28px;\n background: rgb(255 255 255 / 2%);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n}\n\n.settings-about-product {\n color: var(--settings-text);\n font-size: 24px;\n font-weight: 700;\n line-height: 32px;\n}\n\n.settings-about-tagline {\n color: var(--settings-text);\n font-size: 16px;\n font-weight: 600;\n line-height: 24px;\n}\n\n.settings-about-copy {\n display: grid;\n max-width: 660px;\n gap: 12px;\n}\n\n.settings-about-lead,\n.settings-about-extension,\n.settings-about-closing p,\n.settings-about-copy p {\n margin: 0;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 21px;\n}\n\n.settings-about-lead {\n color: var(--settings-text);\n font-weight: 500;\n}\n\n.settings-about-agents {\n display: grid;\n gap: 10px;\n margin: 2px 0;\n padding: 0;\n list-style: none;\n}\n\n.settings-about-agent {\n display: grid;\n gap: 4px;\n padding-left: 2px;\n}\n\n.settings-about-agent-name {\n color: var(--settings-text);\n font-size: 13px;\n font-weight: 600;\n line-height: 18px;\n}\n\n.settings-about-agent-name::before {\n content: "\xB7 ";\n color: var(--settings-muted);\n font-weight: 600;\n}\n\n.settings-about-agent-description {\n display: block;\n padding-left: 0.85em;\n color: var(--settings-muted);\n font-size: 12px;\n font-weight: 400;\n line-height: 18px;\n}\n\n.settings-about-closing {\n display: grid;\n gap: 8px;\n}\n\n.settings-about-repository {\n gap: 10px;\n}\n\n.settings-about-open-source {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 0.35em;\n margin: 0;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 21px;\n}\n\n.settings-about-repository p {\n margin: 0;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 21px;\n}\n\n.settings-about-star-callout {\n margin: 4px 0 0;\n color: #f5c542;\n font-size: 14px;\n font-weight: 600;\n line-height: 22px;\n}\n\n.settings-about-repository-link {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n color: #7cb8ff;\n font-weight: 600;\n line-height: 1;\n text-decoration: none;\n}\n\n.settings-about-repository-link .codexhost-settings-icon {\n display: block;\n flex: none;\n}\n\n.settings-about-repository-link:hover {\n text-decoration: underline;\n}\n\n.settings-about-brand {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n margin-top: auto;\n padding-top: 12px;\n color: inherit;\n opacity: 0.9;\n text-decoration: none;\n transition: opacity 160ms ease;\n}\n\n.settings-about-brand:hover {\n opacity: 1;\n}\n\n.settings-about-brand-video {\n width: 40px;\n height: 40px;\n flex: none;\n overflow: hidden;\n object-fit: cover;\n border-radius: 999px;\n box-shadow: 0 1px 2px rgb(0 0 0 / 18%);\n}\n\n.settings-about-brand-copy {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 2px;\n}\n\n.settings-about-brand-name {\n color: var(--settings-text);\n font-size: 14px;\n font-weight: 800;\n letter-spacing: 0.18em;\n line-height: 18px;\n}\n\n.settings-about-brand-tagline {\n color: var(--settings-muted);\n font-size: 12px;\n font-weight: 500;\n letter-spacing: 0.18em;\n line-height: 16px;\n}\n\n.settings-page-error {\n padding: 16px;\n color: var(--settings-text);\n font-size: 13px;\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 20px;\n}\n\n.settings-update-metadata {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: 24px;\n margin-bottom: 24px;\n padding: 0 4px 20px;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-update-metadata__item {\n display: grid;\n min-width: 0;\n gap: 4px;\n}\n\n.settings-update-metadata__item span {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-metadata__item strong {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-size: 15px;\n font-weight: 500;\n line-height: 22px;\n}\n\n/* The only emphasis on this screen: a latest version newer than the installed one. */\n.settings-update-metadata__value--newer {\n color: #4aa3f0;\n}\n\n.settings-update-panel {\n display: grid;\n gap: 12px;\n padding: 20px;\n color: var(--settings-text);\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\n}\n\n/* Soft status copy (unavailable / request failure) should not sit in a framed card. */\n.settings-update-panel[data-update-state="unavailable"],\n.settings-update-panel[data-update-state="failed"],\n.settings-update-panel[data-update-state="error"] {\n padding: 4px 0 0;\n border: 0;\n border-radius: 0;\n}\n\n.settings-update-panel__status-row {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 8px;\n min-width: 0;\n}\n\n.settings-update-panel__status-row .settings-update-actions {\n flex: none;\n}\n\n.settings-update-panel__status-row .settings-update-panel__head {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.settings-update-panel__head {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 8px;\n}\n\n.settings-update-panel__head .codexhost-settings-icon {\n color: var(--settings-muted);\n}\n\n.settings-update-panel[data-update-state="available"]\n .settings-update-panel__head\n .codexhost-settings-icon,\n.settings-update-panel[data-update-state="downloading"]\n .settings-update-panel__head\n .codexhost-settings-icon,\n.settings-update-panel[data-update-state="installing"]\n .settings-update-panel__head\n .codexhost-settings-icon,\n.settings-update-panel[data-update-state="restarting"]\n .settings-update-panel__head\n .codexhost-settings-icon {\n color: #4aa3f0;\n}\n\n.settings-update-panel[data-update-state="current"]\n .settings-update-panel__head\n .codexhost-settings-icon {\n color: #4ade80;\n}\n\n.settings-update-panel[data-update-state="failed"]\n .settings-update-panel__head\n .codexhost-settings-icon,\n.settings-update-panel[data-update-state="error"]\n .settings-update-panel__head\n .codexhost-settings-icon {\n color: #ef4444;\n}\n\n.settings-update-panel[data-update-state="unavailable"]\n .settings-update-panel__head\n .codexhost-settings-icon {\n color: var(--settings-muted);\n}\n\n.settings-update-panel__title {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-size: 14px;\n font-weight: 600;\n line-height: 22px;\n}\n\n.settings-update-summary,\n.settings-update-error {\n margin: 0;\n overflow-wrap: anywhere;\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-update-summary {\n color: var(--settings-muted);\n}\n\n.settings-update-error {\n color: #ef4444;\n}\n\n.settings-update-progress {\n width: 100%;\n height: 8px;\n accent-color: #238be8;\n}\n\n.settings-update-progress-detail {\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n/* Release notes scroll with the page; a scroller inside a scroller traps the wheel. */\n.settings-update-notes-section {\n min-width: 0;\n margin-top: 24px;\n padding-top: 24px;\n border-top: 1px solid var(--settings-divider);\n}\n\n.settings-update-notes-section:empty {\n display: none;\n}\n\n.settings-update-notes {\n display: grid;\n min-width: 0;\n gap: 12px;\n color: var(--settings-muted);\n font-size: 14px;\n line-height: 22px;\n overflow-wrap: anywhere;\n}\n\n.settings-update-notes > :first-child {\n margin-top: 0;\n}\n\n.settings-update-notes > :last-child {\n margin-bottom: 0;\n}\n\n.settings-update-notes h1,\n.settings-update-notes h2,\n.settings-update-notes h3,\n.settings-update-notes h4,\n.settings-update-notes h5,\n.settings-update-notes h6 {\n margin: 6px 0 0;\n color: var(--settings-text);\n font-weight: 600;\n}\n\n.settings-update-notes h1 {\n font-size: 18px;\n line-height: 26px;\n}\n\n.settings-update-notes h2 {\n font-size: 17px;\n line-height: 24px;\n}\n\n.settings-update-notes h3,\n.settings-update-notes h4,\n.settings-update-notes h5,\n.settings-update-notes h6 {\n font-size: 14px;\n line-height: 22px;\n}\n\n.settings-update-notes p,\n.settings-update-notes ul,\n.settings-update-notes ol,\n.settings-update-notes pre,\n.settings-update-notes blockquote {\n margin: 0;\n}\n\n.settings-update-notes ul,\n.settings-update-notes ol {\n padding-left: 24px;\n}\n\n.settings-update-notes li {\n padding-left: 4px;\n}\n\n.settings-update-notes li::marker {\n color: var(--settings-muted);\n font-size: 0.85em;\n}\n\n.settings-update-notes li + li {\n margin-top: 14px;\n}\n\n.settings-update-notes .release-note-translation {\n display: block;\n margin-top: 3px;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-update-notes blockquote {\n padding: 8px 12px;\n color: var(--settings-muted);\n border-left: 3px solid var(--settings-focus);\n background: var(--settings-surface);\n}\n\n.settings-update-notes hr {\n width: 100%;\n margin: 2px 0;\n border: 0;\n border-top: 1px solid var(--settings-divider);\n}\n\n.settings-update-notes strong {\n color: var(--settings-text);\n font-weight: 600;\n}\n\n.settings-update-notes a {\n color: #7cb8ff;\n text-decoration: none;\n}\n\n.settings-update-notes a:hover {\n text-decoration: underline;\n}\n\n.settings-update-notes code {\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n}\n\n.settings-update-notes :not(pre) > code {\n padding: 1px 5px;\n background: var(--settings-surface-strong);\n border-radius: 4px;\n}\n\n.settings-update-notes pre {\n min-width: 0;\n max-width: 100%;\n padding: 10px 12px;\n overflow-x: auto;\n overflow-y: hidden;\n background: var(--settings-inset);\n border-radius: 6px;\n}\n\n.settings-update-notes pre code {\n line-height: 18px;\n white-space: pre-wrap;\n}\n\n/* Manual update sits directly under the status panel, not behind a disclosure:\n automatic updates can fail for machine-local reasons and this is the way out. */\n.settings-update-controls {\n display: grid;\n min-width: 0;\n gap: 10px;\n margin-top: 24px;\n}\n\n.settings-update-manual-title {\n color: var(--settings-text);\n font-size: 15px;\n font-weight: 600;\n line-height: 22px;\n}\n\n.settings-update-manual {\n display: grid;\n min-width: 0;\n gap: 8px;\n}\n\n.settings-update-manual[hidden] {\n display: none;\n}\n\n.settings-update-manual-description {\n margin: 0;\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-update-manual-description.is-fallback {\n color: #ef4444;\n}\n\n.settings-update-command {\n display: flex;\n align-items: stretch;\n min-width: 0;\n overflow: hidden;\n border: 1px solid var(--settings-border);\n border-radius: 6px;\n}\n\n.settings-update-command code {\n min-width: 0;\n flex: 1;\n padding: 9px 12px;\n overflow-x: auto;\n color: var(--settings-text);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n line-height: 20px;\n white-space: nowrap;\n}\n\n.settings-update-command__copy {\n display: inline-flex;\n align-items: center;\n flex: none;\n gap: 6px;\n padding: 0 12px;\n color: var(--settings-muted);\n font-size: 12px;\n background: transparent;\n border: 0;\n border-left: 1px solid var(--settings-border);\n cursor: pointer;\n}\n\n.settings-update-command__copy:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-update-command__copy:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: -2px;\n}\n\n.settings-update-actions {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 12px;\n flex-wrap: wrap;\n}\n\n.settings-command-button,\n.settings-update-link {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: fit-content;\n min-height: 36px;\n gap: 8px;\n padding: 8px 12px;\n color: white;\n font: inherit;\n font-size: 13px;\n text-decoration: none;\n background: #1677d2;\n border: 1px solid #238be8;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.settings-command-button--secondary,\n.settings-update-link {\n color: var(--settings-muted);\n background: transparent;\n border-color: var(--settings-border);\n}\n\n.settings-command-button--secondary .codexhost-settings-icon,\n.settings-update-link .codexhost-settings-icon {\n color: var(--settings-muted);\n}\n\n.settings-command-button:hover:not(.settings-command-button--secondary) {\n filter: brightness(1.08);\n}\n\n.settings-command-button--secondary:hover,\n.settings-update-link:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-command-button--secondary:hover .codexhost-settings-icon,\n.settings-update-link:hover .codexhost-settings-icon {\n color: var(--settings-text);\n}\n\n.settings-command-button:disabled,\n.settings-command-button[aria-disabled="true"] {\n opacity: 0.55;\n cursor: not-allowed;\n filter: none;\n}\n\n.settings-command-button:focus-visible,\n.settings-update-link:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 2px;\n}\n\n.settings-visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n.settings-session-import-harness {\n display: grid;\n gap: 8px;\n min-width: 0;\n}\n\n.settings-session-import-harness > span {\n color: var(--settings-muted);\n font-size: 12px;\n font-weight: 600;\n line-height: 18px;\n}\n\n.settings-session-import-harness__options {\n width: 100%;\n}\n\n.settings-session-import-availability-note {\n margin: 16px 0 20px;\n}\n\n.settings-session-import-content {\n display: grid;\n min-width: 0;\n gap: 12px;\n}\n\n.settings-session-import-status {\n display: flex;\n align-items: flex-start;\n min-width: 0;\n gap: 10px;\n padding: 14px 16px;\n color: var(--settings-muted);\n background: var(--settings-surface);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n}\n\n.settings-session-import-status.is-error {\n color: #fecaca;\n background: rgb(239 68 68 / 7%);\n border-color: rgb(239 68 68 / 20%);\n}\n\n.settings-session-import-list {\n display: grid;\n min-width: 0;\n overflow: hidden;\n background: var(--settings-surface);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n}\n\n.settings-session-import-row {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: center;\n min-width: 0;\n gap: 16px;\n padding: 14px 16px;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-session-import-row:last-child {\n border-bottom: 0;\n}\n\n.settings-session-import-row__copy {\n display: grid;\n min-width: 0;\n gap: 4px;\n}\n\n.settings-session-import-row__copy strong {\n color: var(--settings-text);\n font-size: 14px;\n font-weight: 600;\n line-height: 20px;\n}\n\n.settings-session-import-row__copy span,\n.settings-session-import-row__cwd {\n min-width: 0;\n overflow-wrap: anywhere;\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n}\n\n.settings-session-import-row__cwd {\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n}\n\n.settings-session-import-row__action {\n display: flex;\n align-items: center;\n flex: none;\n gap: 8px;\n}\n\n.settings-session-import-running {\n color: #f5c542;\n font-size: 12px;\n font-weight: 500;\n line-height: 18px;\n white-space: nowrap;\n}\n\n.settings-session-import-recovery {\n display: grid;\n min-width: 0;\n gap: 12px;\n padding: 16px;\n background: var(--settings-surface);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n}\n\n.settings-session-import-recovery__copy {\n display: grid;\n gap: 6px;\n}\n\n.settings-session-import-recovery__copy strong {\n color: var(--settings-text);\n font-size: 15px;\n font-weight: 600;\n line-height: 22px;\n}\n\n.settings-session-import-recovery__copy p {\n margin: 0;\n color: var(--settings-muted);\n font-size: 13px;\n line-height: 20px;\n}\n\n.settings-session-import-recovery__path {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 8px;\n}\n\n.settings-session-import-recovery__path code {\n min-width: 0;\n flex: 1;\n overflow-wrap: anywhere;\n color: var(--settings-text);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 12px;\n line-height: 18px;\n}\n\n.codexhost-settings-icon {\n display: block;\n flex: none;\n stroke: currentColor;\n}\n\n@media (max-width: 720px) {\n .codexhost-settings-dialog {\n width: calc(100vw - 16px);\n height: calc(100vh - 16px);\n border-radius: 10px;\n }\n\n .settings-layout {\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr);\n }\n\n .settings-sidebar {\n border-right: 0;\n border-bottom: 1px solid var(--settings-border);\n }\n\n .settings-header {\n height: 56px;\n padding-inline: 14px;\n }\n\n .settings-sidebar {\n padding-top: 20px;\n }\n\n .settings-nav {\n flex: none;\n flex-direction: row;\n gap: 4px;\n padding: 7px 8px 8px;\n overflow-x: auto;\n overflow-y: hidden;\n }\n\n .settings-nav-section-label {\n display: none;\n }\n\n .settings-nav-button {\n width: auto;\n min-width: max-content;\n min-height: 34px;\n grid-template-columns: 16px auto;\n border-radius: 10px;\n }\n\n .settings-page__content {\n width: calc(100% - 40px);\n }\n\n .settings-page__content {\n padding-top: 32px;\n padding-bottom: 32px;\n }\n\n .settings-section-label {\n padding-bottom: 20px;\n font-size: 20px;\n line-height: 26px;\n }\n\n .settings-update-metadata {\n grid-template-columns: minmax(0, 1fr);\n gap: 16px;\n }\n\n .settings-status-row {\n grid-template-columns: minmax(0, 1fr) auto;\n gap: 16px;\n }\n\n .settings-connection-page-header {\n flex-direction: column;\n }\n\n .settings-connection-page-header > .settings-command-button {\n width: 100%;\n }\n\n .settings-session-import-row {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .settings-session-import-row__action {\n justify-content: flex-start;\n flex-wrap: wrap;\n }\n\n .settings-status-row__detail {\n grid-column: 1 / -1;\n margin: -8px 0 0 58px;\n }\n}\n\n@media (forced-colors: active) {\n :host,\n :host([data-theme="light"]),\n :host([data-theme="dark"]) {\n --settings-bg: Canvas;\n --settings-sidebar: Canvas;\n --settings-panel: Canvas;\n --settings-text: CanvasText;\n --settings-muted: GrayText;\n --settings-border: ButtonBorder;\n --settings-divider: ButtonBorder;\n --settings-hover: Highlight;\n --settings-active: Highlight;\n --settings-focus: Highlight;\n --settings-elevated: Canvas;\n --settings-inset: Canvas;\n --settings-surface: Canvas;\n --settings-surface-strong: Canvas;\n --settings-mark: CanvasText;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n scroll-behavior: auto !important;\n }\n}\n';
22863
23537
 
22864
23538
  // src/settings/shell.ts
22865
23539
  var SETTINGS_SHELL_ATTRIBUTE = "data-codexhost-settings-shell";
@@ -23441,7 +24115,15 @@ ${error51.stderrTail}`] : []
23441
24115
  const definitions = createDefaultRendererSettingsPages(
23442
24116
  messages,
23443
24117
  options.getUpdateClient ?? (() => null),
23444
- options.getConnectionDiagnostics ?? (() => null)
24118
+ options.getConnectionDiagnostics ?? (() => null),
24119
+ options.getSessionImportClient ?? (() => null),
24120
+ async (threadId, signal) => {
24121
+ if (!options.openImportedThread) {
24122
+ throw new Error("Imported Thread navigation is unavailable");
24123
+ }
24124
+ await options.openImportedThread(threadId, signal);
24125
+ if (!disposed && !signal.aborted) shell?.close();
24126
+ }
23445
24127
  );
23446
24128
  const nextShell = installRendererSettingsShell(definitions, messages, ownerWindow.document);
23447
24129
  const nextTrigger = installRendererSettingsHeaderTrigger({
@@ -23872,10 +24554,30 @@ ${error51.stderrTail}`] : []
23872
24554
  getClient: (hostId) => modelClientForHost(hostId),
23873
24555
  getLocalAgent: localAgentForSidebarThread
23874
24556
  });
24557
+ const stopSidebarExternalPinning = installRendererSidebarExternalPinning({
24558
+ getClient: (hostId) => modelClientForHost(hostId),
24559
+ reportError: (error51) => {
24560
+ console.error(
24561
+ "codexhost External Thread pin update failed",
24562
+ error51 instanceof Error ? error51.message : String(error51)
24563
+ );
24564
+ }
24565
+ });
23875
24566
  let connectionDiagnostics = null;
23876
24567
  const settingsLifecycle = installRendererSettingsLifecycle(window, {
23877
24568
  getUpdateClient: () => modelControl,
23878
24569
  getConnectionDiagnostics: () => connectionDiagnostics,
24570
+ getSessionImportClient: () => {
24571
+ const client = modelClientForHost("local");
24572
+ const list = client?.listDeepSeekModernSessions;
24573
+ const importSession = client?.importDeepSeekModernSession;
24574
+ if (!list || !importSession) return null;
24575
+ return {
24576
+ listDeepSeekModernSessions: (input) => list(input),
24577
+ importDeepSeekModernSession: (input) => importSession(input)
24578
+ };
24579
+ },
24580
+ openImportedThread: (threadId, signal) => openRendererThread(threadId, { hostId: "local", signal }),
23879
24581
  onLocaleChange() {
23880
24582
  for (const mounted of mountedByComposer.values()) renderMounted(mounted);
23881
24583
  }
@@ -23899,6 +24601,9 @@ ${error51.stderrTail}`] : []
23899
24601
  omp: void 0,
23900
24602
  antigravity: void 0
23901
24603
  },
24604
+ webUi: Object.fromEntries(
24605
+ externalAgents.map((agent) => [agent, false])
24606
+ ),
23902
24607
  requestGeneration: 0,
23903
24608
  request: null,
23904
24609
  retryTimer: null,
@@ -24003,6 +24708,17 @@ ${error51.stderrTail}`] : []
24003
24708
  mounted.control.harnessCommands.setExecuting(null);
24004
24709
  }
24005
24710
  };
24711
+ const selectCommand = (mounted, command) => {
24712
+ const threadId = threadIdFromComposerModelTarget(mounted.modelTarget);
24713
+ if (!threadId || !modelControl || controller.get(mounted.composer).agent === "codex") return;
24714
+ const editor = mounted.composer.querySelector(EDITOR_SELECTOR);
24715
+ if (routeRendererHarnessCommandSelection(editor, command, () => {
24716
+ void executeCommand(mounted, command);
24717
+ })) {
24718
+ return;
24719
+ }
24720
+ console.error("codexhost Harness command could not claim the current Composer editor");
24721
+ };
24006
24722
  const applyThreadUsageUpdate = (update) => {
24007
24723
  for (const mounted of mountedByComposer.values()) {
24008
24724
  if (threadIdFromComposerModelTarget(mounted.modelTarget) !== update.threadId) continue;
@@ -24858,12 +25574,14 @@ ${error51.stderrTail}`] : []
24858
25574
  agentsToInspect.map(async (agent) => {
24859
25575
  let status = "error";
24860
25576
  let nextError;
25577
+ let webUiAvailable = false;
24861
25578
  try {
24862
25579
  const inspection = await client.inspectHarness({
24863
25580
  harnessId: externalHarnessIds[agent],
24864
25581
  refresh
24865
25582
  });
24866
25583
  status = inspection.status === "ready" ? "ready" : inspection.status;
25584
+ webUiAvailable = hostId === "local" && inspection.status === "ready" && inspection.webUi?.open === true;
24867
25585
  if (inspection.status !== "ready") {
24868
25586
  const error51 = inspection.error;
24869
25587
  nextError = {
@@ -24889,6 +25607,7 @@ ${error51.stderrTail}`] : []
24889
25607
  const previousStatus = state.availability[agent];
24890
25608
  state.errors[agent] = nextError;
24891
25609
  state.availability = { ...state.availability, [agent]: status };
25610
+ state.webUi = { ...state.webUi, [agent]: webUiAvailable };
24892
25611
  if (hostId !== activeAvailabilityHostId) {
24893
25612
  publishConnectionStatus();
24894
25613
  return;
@@ -24993,7 +25712,8 @@ ${error51.stderrTail}`] : []
24993
25712
  agents: externalAgents.map((agent) => ({
24994
25713
  agent,
24995
25714
  availability: state.availability[agent] ?? "checking",
24996
- error: state.errors[agent] ?? null
25715
+ error: state.errors[agent] ?? null,
25716
+ ...state.webUi[agent] ? { webUiAvailable: true } : {}
24997
25717
  }))
24998
25718
  };
24999
25719
  })
@@ -25005,6 +25725,21 @@ ${error51.stderrTail}`] : []
25005
25725
  (hostId) => refreshHarnessAvailabilityForHost(hostId, true, false, true)
25006
25726
  );
25007
25727
  },
25728
+ async openWebUi(hostId, agent) {
25729
+ const state = hostHarnessAvailabilityState(hostId);
25730
+ const client = hostId === "local" ? modelClientForHost(hostId) : null;
25731
+ if (state.availability[agent] !== "ready" || state.webUi[agent] !== true || !client?.openHarnessWebUi) {
25732
+ throw new Error("Harness Web UI is unavailable");
25733
+ }
25734
+ try {
25735
+ await client.openHarnessWebUi({ harnessId: externalHarnessIds[agent] });
25736
+ } catch (error51) {
25737
+ state.webUi = { ...state.webUi, [agent]: false };
25738
+ publishConnectionStatus();
25739
+ void refreshHarnessAvailabilityForHost(hostId, true, false, true).catch(() => void 0);
25740
+ throw error51;
25741
+ }
25742
+ },
25008
25743
  subscribe(listener) {
25009
25744
  connectionListeners.add(listener);
25010
25745
  return () => connectionListeners.delete(listener);
@@ -25055,7 +25790,7 @@ ${error51.stderrTail}`] : []
25055
25790
  },
25056
25791
  (command) => {
25057
25792
  const mounted2 = mountedByComposer.get(composer);
25058
- if (mounted2) void executeCommand(mounted2, command);
25793
+ if (mounted2) selectCommand(mounted2, command);
25059
25794
  }
25060
25795
  );
25061
25796
  const mounted = {
@@ -25453,6 +26188,7 @@ ${error51.stderrTail}`] : []
25453
26188
  modelControl = null;
25454
26189
  mutationObserver.disconnect();
25455
26190
  sidebarAgentIcons.dispose();
26191
+ stopSidebarExternalPinning();
25456
26192
  settingsLifecycle.dispose();
25457
26193
  document.removeEventListener("beforeinput", onBeforeInput, true);
25458
26194
  document.removeEventListener("submit", onSubmit, true);