@codexhost/cli-darwin-x64 0.4.3 → 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(),
@@ -16175,15 +16216,15 @@ ${error51.stderrTail}`] : []
16175
16216
  action.className = "settings-connection-row__action";
16176
16217
  action.setAttribute("role", "cell");
16177
16218
  if (item.agentSnapshot?.availability === "notInstalled") {
16178
- const install = document2.createElement("a");
16179
- install.className = "settings-connection-install-link";
16180
- install.href = HARNESS_INSTALL_URLS[item.agentSnapshot.agent];
16181
- install.target = "_blank";
16182
- install.rel = "noopener noreferrer";
16183
- install.setAttribute("aria-label", `${messages.connectionOpenInstallation}: ${item.name}`);
16184
- install.title = messages.connectionOpenInstallation;
16185
- install.append(createRendererSettingsIcon("download", 17));
16186
- action.append(install);
16219
+ const install2 = document2.createElement("a");
16220
+ install2.className = "settings-connection-install-link";
16221
+ install2.href = HARNESS_INSTALL_URLS[item.agentSnapshot.agent];
16222
+ install2.target = "_blank";
16223
+ install2.rel = "noopener noreferrer";
16224
+ install2.setAttribute("aria-label", `${messages.connectionOpenInstallation}: ${item.name}`);
16225
+ install2.title = messages.connectionOpenInstallation;
16226
+ install2.append(createRendererSettingsIcon("download", 17));
16227
+ action.append(install2);
16187
16228
  } else if (item.error) {
16188
16229
  const viewError = document2.createElement("button");
16189
16230
  viewError.type = "button";
@@ -16264,16 +16305,16 @@ ${error51.stderrTail}`] : []
16264
16305
  description.textContent = messages.connectionInstallDescription;
16265
16306
  copy.append(title, description);
16266
16307
  callout.append(icon2, copy);
16267
- const install = document2.createElement("a");
16268
- install.className = "settings-command-button settings-connection-install-button";
16269
- install.href = HARNESS_INSTALL_URLS[item.agentSnapshot.agent];
16270
- install.target = "_blank";
16271
- install.rel = "noopener noreferrer";
16272
- install.append(
16308
+ const install2 = document2.createElement("a");
16309
+ install2.className = "settings-command-button settings-connection-install-button";
16310
+ install2.href = HARNESS_INSTALL_URLS[item.agentSnapshot.agent];
16311
+ install2.target = "_blank";
16312
+ install2.rel = "noopener noreferrer";
16313
+ install2.append(
16273
16314
  messages.connectionOpenInstallation,
16274
16315
  createRendererSettingsIcon("external-link", 14)
16275
16316
  );
16276
- body.append(callout, install);
16317
+ body.append(callout, install2);
16277
16318
  } else if (item.error) {
16278
16319
  const summary = document2.createElement("div");
16279
16320
  summary.className = "settings-connection-error-summary";
@@ -16337,10 +16378,28 @@ ${error51.stderrTail}`] : []
16337
16378
  description.textContent = item.availability === "ready" ? messages.connectionReadyDescription : messages.connectionUnavailableDescription;
16338
16379
  status.append(title, description);
16339
16380
  body.append(status);
16381
+ if (item.openWebUi) {
16382
+ const open = document2.createElement("button");
16383
+ open.type = "button";
16384
+ open.className = "settings-command-button settings-command-button--secondary";
16385
+ open.dataset.connectionAction = "open-web-ui";
16386
+ open.append(
16387
+ messages.connectionOpenHarnessWeb,
16388
+ createRendererSettingsIcon("external-link", 14)
16389
+ );
16390
+ open.addEventListener("click", () => {
16391
+ if (open.disabled) return;
16392
+ open.disabled = true;
16393
+ void item.openWebUi?.().catch(() => void 0).finally(() => {
16394
+ open.disabled = false;
16395
+ });
16396
+ });
16397
+ body.append(open);
16398
+ }
16340
16399
  }
16341
16400
  inspector.append(body);
16342
16401
  }
16343
- function connectionItems(snapshot, host, messages) {
16402
+ function connectionItems(snapshot, host, messages, diagnostics) {
16344
16403
  return [
16345
16404
  {
16346
16405
  key: "renderer-adapter",
@@ -16353,7 +16412,10 @@ ${error51.stderrTail}`] : []
16353
16412
  name: RENDERER_AGENT_LABELS[agent.agent],
16354
16413
  availability: agent.availability,
16355
16414
  error: agent.availability === "notInstalled" ? null : agent.error,
16356
- agentSnapshot: agent
16415
+ agentSnapshot: agent,
16416
+ ...host.hostId === "local" && agent.webUiAvailable && diagnostics?.openWebUi ? {
16417
+ openWebUi: () => diagnostics.openWebUi?.(host.hostId, agent.agent) ?? Promise.resolve()
16418
+ } : {}
16357
16419
  }))
16358
16420
  ];
16359
16421
  }
@@ -16545,7 +16607,7 @@ ${error51.stderrTail}`] : []
16545
16607
  const inspector = document2.createElement("aside");
16546
16608
  inspector.className = "settings-connection-inspector";
16547
16609
  inspector.setAttribute("aria-live", "polite");
16548
- const items = connectionItems(snapshot, selectedHost, messages);
16610
+ const items = connectionItems(snapshot, selectedHost, messages, diagnostics);
16549
16611
  if (!items.some((item) => item.key === selectedItemKey)) {
16550
16612
  const requestedFocus = pendingFocusAgent;
16551
16613
  pendingFocusAgent = null;
@@ -16761,6 +16823,29 @@ ${error51.stderrTail}`] : []
16761
16823
  inDevelopment: "In development",
16762
16824
  notAvailable: "Not available",
16763
16825
  runtimeCapabilityNotInstalled: "This runtime capability is not installed yet.",
16826
+ sessionImportHarness: "Harness",
16827
+ 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.",
16828
+ sessionImportAvailabilityNote: "Currently, only DeepSeek Harness Modern sessions can be imported. Support for other Harnesses is coming later.",
16829
+ sessionImportRefresh: "Refresh",
16830
+ sessionImportRefreshing: "Loading local sessions...",
16831
+ sessionImportUnavailable: "Session import requires a local, codexhost-managed DeepSeek Harness 0.1.2-rc.1 Modern runtime.",
16832
+ sessionImportEmpty: "No local DeepSeek Harness sessions are available to import.",
16833
+ sessionImportLoadFailed: "Local sessions could not be loaded.",
16834
+ sessionImportFailed: "The session could not be imported.",
16835
+ sessionImportUntitled: "Untitled session",
16836
+ sessionImportUpdatedAt: "Updated",
16837
+ sessionImportSessionId: "Session ID",
16838
+ sessionImportRunning: "Running",
16839
+ sessionImportRunningHint: "Stop this session in DSH, then refresh.",
16840
+ sessionImportAction: "Import and open",
16841
+ sessionImportImporting: "Importing...",
16842
+ sessionImportImported: "Session imported",
16843
+ sessionImportOpenFailed: "The Codex sidebar has not shown it yet. Make sure the folder below is added as a project, then try opening it again.",
16844
+ sessionImportCopyProjectPath: "Copy project path",
16845
+ sessionImportPathCopied: "Copied",
16846
+ sessionImportPathCopyFailed: "Copy failed",
16847
+ sessionImportRetryOpen: "Try opening again",
16848
+ sessionImportRetrying: "Opening...",
16764
16849
  connectionsDescription: "View runtime status by Host. Select an item to inspect details or complete its setup.",
16765
16850
  connectionAdapter: "Renderer adapter",
16766
16851
  connectionHosts: "Hosts",
@@ -16793,6 +16878,7 @@ ${error51.stderrTail}`] : []
16793
16878
  connectionHostsScrollLeft: "Show previous Hosts",
16794
16879
  connectionHostsScrollRight: "Show more Hosts",
16795
16880
  connectionOpenInstallation: "Open official installation page",
16881
+ connectionOpenHarnessWeb: "Open DeepSeek Harness Web",
16796
16882
  connectionInstall: "Install",
16797
16883
  connectionInstallDescription: "This Harness was not detected. Follow its official installation guide, then return here and run the check again.",
16798
16884
  connectionErrorTitle: "Connection check failed",
@@ -16859,6 +16945,7 @@ ${error51.stderrTail}`] : []
16859
16945
  aboutRepository: "Open-source repository",
16860
16946
  pageLabels: Object.freeze({
16861
16947
  connections: "Connections",
16948
+ "session-import": "Session Import",
16862
16949
  updates: "Updates",
16863
16950
  about: "About"
16864
16951
  })
@@ -16875,6 +16962,29 @@ ${error51.stderrTail}`] : []
16875
16962
  inDevelopment: "\u5F00\u53D1\u4E2D",
16876
16963
  notAvailable: "\u6682\u4E0D\u53EF\u7528",
16877
16964
  runtimeCapabilityNotInstalled: "\u8FD0\u884C\u65F6\u5C1A\u672A\u5B89\u88C5\u8BE5\u9879\u80FD\u529B\uFF0C\u56E0\u6B64\u6682\u4E0D\u53EF\u7528\u3002",
16965
+ sessionImportHarness: "Harness",
16966
+ 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",
16967
+ 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",
16968
+ sessionImportRefresh: "\u5237\u65B0",
16969
+ sessionImportRefreshing: "\u6B63\u5728\u8BFB\u53D6\u672C\u5730\u4F1A\u8BDD\u2026\u2026",
16970
+ sessionImportUnavailable: "\u4F1A\u8BDD\u5BFC\u5165\u4EC5\u652F\u6301\u672C\u5730\u3001\u7531 codexhost \u7BA1\u7406\u7684 DeepSeek Harness 0.1.2-rc.1 Modern \u8FD0\u884C\u65F6\u3002",
16971
+ sessionImportEmpty: "\u6CA1\u6709\u53EF\u5BFC\u5165\u7684\u672C\u5730 DeepSeek Harness \u4F1A\u8BDD\u3002",
16972
+ sessionImportLoadFailed: "\u65E0\u6CD5\u8BFB\u53D6\u672C\u5730\u4F1A\u8BDD\u3002",
16973
+ sessionImportFailed: "\u65E0\u6CD5\u5BFC\u5165\u8BE5\u4F1A\u8BDD\u3002",
16974
+ sessionImportUntitled: "\u672A\u547D\u540D\u4F1A\u8BDD",
16975
+ sessionImportUpdatedAt: "\u66F4\u65B0\u65F6\u95F4",
16976
+ sessionImportSessionId: "\u4F1A\u8BDD ID",
16977
+ sessionImportRunning: "\u8FD0\u884C\u4E2D",
16978
+ sessionImportRunningHint: "\u8BF7\u5148\u5728 DSH \u4E2D\u505C\u6B62\u8BE5\u4F1A\u8BDD\uFF0C\u7136\u540E\u5237\u65B0\u3002",
16979
+ sessionImportAction: "\u5BFC\u5165\u5E76\u6253\u5F00",
16980
+ sessionImportImporting: "\u6B63\u5728\u5BFC\u5165\u2026\u2026",
16981
+ sessionImportImported: "\u4F1A\u8BDD\u5DF2\u5BFC\u5165",
16982
+ 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",
16983
+ sessionImportCopyProjectPath: "\u590D\u5236\u9879\u76EE\u8DEF\u5F84",
16984
+ sessionImportPathCopied: "\u5DF2\u590D\u5236",
16985
+ sessionImportPathCopyFailed: "\u590D\u5236\u5931\u8D25",
16986
+ sessionImportRetryOpen: "\u91CD\u8BD5\u6253\u5F00",
16987
+ sessionImportRetrying: "\u6B63\u5728\u6253\u5F00\u2026\u2026",
16878
16988
  connectionsDescription: "\u6309 Host \u67E5\u770B\u8FD0\u884C\u65F6\u72B6\u6001\u3002\u9009\u62E9\u4E00\u9879\uFF0C\u5728\u53F3\u4FA7\u68C0\u67E5\u8BE6\u60C5\u6216\u5B8C\u6210\u914D\u7F6E\u3002",
16879
16989
  connectionAdapter: "Renderer \u9002\u914D\u5668",
16880
16990
  connectionHosts: "Host \u5217\u8868",
@@ -16907,6 +17017,7 @@ ${error51.stderrTail}`] : []
16907
17017
  connectionHostsScrollLeft: "\u67E5\u770B\u524D\u9762\u7684 Host",
16908
17018
  connectionHostsScrollRight: "\u67E5\u770B\u66F4\u591A Host",
16909
17019
  connectionOpenInstallation: "\u524D\u5F80\u5B98\u65B9\u5B89\u88C5\u9875\u9762",
17020
+ connectionOpenHarnessWeb: "\u6253\u5F00 DeepSeek Harness Web",
16910
17021
  connectionInstall: "\u5B89\u88C5",
16911
17022
  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",
16912
17023
  connectionErrorTitle: "\u8FDE\u63A5\u68C0\u67E5\u5931\u8D25",
@@ -16973,6 +17084,7 @@ ${error51.stderrTail}`] : []
16973
17084
  aboutRepository: "\u5F00\u6E90\u4ED3\u5E93",
16974
17085
  pageLabels: Object.freeze({
16975
17086
  connections: "\u8FDE\u63A5",
17087
+ "session-import": "\u4F1A\u8BDD\u5BFC\u5165",
16976
17088
  updates: "\u66F4\u65B0",
16977
17089
  about: "\u5173\u4E8E"
16978
17090
  })
@@ -18581,7 +18693,6 @@ ${error51.stderrTail}`] : []
18581
18693
  sessionCostEstimate: "Session cost estimate",
18582
18694
  threadUsage: "Thread Usage",
18583
18695
  threadUsageDetails: "Thread Usage details",
18584
- contextSummary: "context",
18585
18696
  tokensSummary: "tokens",
18586
18697
  tokensPerSecond: "tok/s",
18587
18698
  fiveHourSummary: "5h",
@@ -18602,7 +18713,6 @@ ${error51.stderrTail}`] : []
18602
18713
  sessionCostEstimate: "\u4F1A\u8BDD\u8D39\u7528\u4F30\u7B97",
18603
18714
  threadUsage: "\u5BF9\u8BDD\u7528\u91CF",
18604
18715
  threadUsageDetails: "\u5BF9\u8BDD\u7528\u91CF\u8BE6\u60C5",
18605
- contextSummary: "\u4E0A\u4E0B\u6587",
18606
18716
  tokensSummary: "Token",
18607
18717
  tokensPerSecond: "Token/\u79D2",
18608
18718
  fiveHourSummary: "5 \u5C0F\u65F6",
@@ -18631,6 +18741,9 @@ ${error51.stderrTail}`] : []
18631
18741
  if (absolute < 1e9) return `${sign}${decimal(absolute / 1e6, 1)}M`;
18632
18742
  return `${sign}${decimal(absolute / 1e9, 1)}B`;
18633
18743
  }
18744
+ function formatRendererContextSummary(usedTokens, windowTokens) {
18745
+ return `${decimal(usedTokens / windowTokens * 100, 1)}% / ${formatRendererTokenCount(windowTokens)}`;
18746
+ }
18634
18747
  function formatRendererCreditsPercent(value) {
18635
18748
  return `${decimal(value, 1)}%`;
18636
18749
  }
@@ -18974,7 +19087,7 @@ ${error51.stderrTail}`] : []
18974
19087
  ].filter((value) => value !== null);
18975
19088
  if (summary.length === 0 && hasContext && usage?.contextWindowTokens !== void 0 && usage.contextWindowTokens > 0) {
18976
19089
  summary.push(
18977
- `${decimal((usage.contextUsedTokens ?? 0) / usage.contextWindowTokens * 100, 1)}% ${messages.contextSummary}`
19090
+ formatRendererContextSummary(usage.contextUsedTokens ?? 0, usage.contextWindowTokens)
18978
19091
  );
18979
19092
  }
18980
19093
  if (summary.length === 0 && usage?.totalTokens !== void 0) {
@@ -20190,7 +20303,7 @@ ${error51.stderrTail}`] : []
20190
20303
  }
20191
20304
  };
20192
20305
  function installRendererSidebarAgentIcons(options) {
20193
- const dom = options.dom ?? new BrowserSidebarAgentIconDom(document.documentElement);
20306
+ const dom = options.dom ?? new BrowserSidebarAgentIconDom(document);
20194
20307
  const ownershipByThread = /* @__PURE__ */ new Map();
20195
20308
  const pending = /* @__PURE__ */ new Set();
20196
20309
  const failed = /* @__PURE__ */ new Set();
@@ -20360,6 +20473,64 @@ ${error51.stderrTail}`] : []
20360
20473
  var RESPONSE_CONVERSATION_ATTRIBUTE = "data-response-annotation-conversation";
20361
20474
  var TURN_KEY_ATTRIBUTE = "data-content-search-turn-key";
20362
20475
  var OPEN_THREAD_TIMEOUT_MS = 5e3;
20476
+ function abortError() {
20477
+ return Object.assign(new Error("Thread opening was aborted"), { name: "AbortError" });
20478
+ }
20479
+ function openRendererThread(threadId, options = {}) {
20480
+ const find = () => {
20481
+ for (const row of document.querySelectorAll(SIDEBAR_THREAD_ROW_SELECTOR)) {
20482
+ if ((options.hostId === void 0 || row.getAttribute(SIDEBAR_THREAD_HOST_ID_ATTRIBUTE) === options.hostId) && threadIdFromSidebarRowElement(row) === threadId) {
20483
+ return row;
20484
+ }
20485
+ }
20486
+ return null;
20487
+ };
20488
+ if (options.signal?.aborted) return Promise.reject(abortError());
20489
+ const current = find();
20490
+ if (current) {
20491
+ current.click();
20492
+ return Promise.resolve();
20493
+ }
20494
+ return new Promise((resolve, reject) => {
20495
+ let settled = false;
20496
+ const cleanup = () => {
20497
+ window.clearTimeout(timeout);
20498
+ observer.disconnect();
20499
+ options.signal?.removeEventListener("abort", onAbort);
20500
+ };
20501
+ const finish = (row2) => {
20502
+ if (settled) return;
20503
+ settled = true;
20504
+ cleanup();
20505
+ row2.click();
20506
+ resolve();
20507
+ };
20508
+ const observer = new MutationObserver(() => {
20509
+ const row2 = find();
20510
+ if (row2) finish(row2);
20511
+ });
20512
+ const timeout = window.setTimeout(() => {
20513
+ if (settled) return;
20514
+ settled = true;
20515
+ cleanup();
20516
+ reject(new Error("Thread did not appear in the sidebar"));
20517
+ }, options.timeoutMs ?? OPEN_THREAD_TIMEOUT_MS);
20518
+ const onAbort = () => {
20519
+ if (settled) return;
20520
+ settled = true;
20521
+ cleanup();
20522
+ reject(abortError());
20523
+ };
20524
+ options.signal?.addEventListener("abort", onAbort, { once: true });
20525
+ observer.observe(document.documentElement, { childList: true, subtree: true });
20526
+ if (options.signal?.aborted) {
20527
+ onAbort();
20528
+ return;
20529
+ }
20530
+ const row = find();
20531
+ if (row) finish(row);
20532
+ });
20533
+ }
20363
20534
  function isRecord3(value) {
20364
20535
  return typeof value === "object" && value !== null && !Array.isArray(value);
20365
20536
  }
@@ -20433,35 +20604,7 @@ ${error51.stderrTail}`] : []
20433
20604
  target.control.click();
20434
20605
  }
20435
20606
  openThread(threadId) {
20436
- const find = () => {
20437
- for (const row of document.querySelectorAll(SIDEBAR_THREAD_ROW_SELECTOR)) {
20438
- if (threadIdFromSidebarRowElement(row) === threadId) return row;
20439
- }
20440
- return null;
20441
- };
20442
- const current = find();
20443
- if (current) {
20444
- current.click();
20445
- return Promise.resolve();
20446
- }
20447
- return new Promise((resolve, reject) => {
20448
- const observer = new MutationObserver(() => {
20449
- const row = find();
20450
- if (!row) return;
20451
- cleanup();
20452
- row.click();
20453
- resolve();
20454
- });
20455
- const timeout = window.setTimeout(() => {
20456
- cleanup();
20457
- reject(new Error("Forked Thread did not appear in the sidebar"));
20458
- }, OPEN_THREAD_TIMEOUT_MS);
20459
- const cleanup = () => {
20460
- window.clearTimeout(timeout);
20461
- observer.disconnect();
20462
- };
20463
- observer.observe(document.documentElement, { childList: true, subtree: true });
20464
- });
20607
+ return openRendererThread(threadId);
20465
20608
  }
20466
20609
  };
20467
20610
  function installRendererForkControl(options) {
@@ -20501,6 +20644,9 @@ ${error51.stderrTail}`] : []
20501
20644
 
20502
20645
  // src/renderer-model-client.ts
20503
20646
  var HARNESS_INSPECT_METHOD = "codexhost/harness/inspect";
20647
+ var DEEPSEEK_MODERN_SESSION_LIST_METHOD = "codexhost/deepseek/modern-session/list";
20648
+ var DEEPSEEK_MODERN_SESSION_IMPORT_METHOD = "codexhost/deepseek/modern-session/import";
20649
+ var HARNESS_WEB_UI_OPEN_METHOD = "codexhost/harness/web-ui/open";
20504
20650
  var THREAD_FORK_METHOD = "codexhost/thread/fork";
20505
20651
  var THREAD_INSPECT_METHOD = "codexhost/thread/inspect";
20506
20652
  var THREAD_COMMANDS_INSPECT_METHOD = "codexhost/thread/commands/inspect";
@@ -20515,9 +20661,19 @@ ${error51.stderrTail}`] : []
20515
20661
  var UPDATE_CHECK_METHOD = "codexhost/update/check";
20516
20662
  var UPDATE_START_METHOD = "codexhost/update/start";
20517
20663
  var UPDATE_STATUS_METHOD = "codexhost/update/status";
20664
+ var RendererDeepSeekSessionUnavailableError = class extends Error {
20665
+ constructor() {
20666
+ super("DeepSeek Modern Session import is unavailable");
20667
+ this.name = "RendererDeepSeekSessionUnavailableError";
20668
+ }
20669
+ };
20518
20670
  function isRecord4(value) {
20519
20671
  return typeof value === "object" && value !== null && !Array.isArray(value);
20520
20672
  }
20673
+ function normalizeDeepSeekSessionError(error51) {
20674
+ const code = isRecord4(error51) ? error51.code : void 0;
20675
+ return code === -32076 || code === -32077 ? new RendererDeepSeekSessionUnavailableError() : error51;
20676
+ }
20521
20677
  function notifiedThreadId(notification) {
20522
20678
  if (!isRecord4(notification) || notification.method !== THREAD_TOKEN_USAGE_UPDATED_METHOD && notification.method !== THREAD_USAGE_UPDATED_METHOD) {
20523
20679
  return null;
@@ -20568,6 +20724,7 @@ ${error51.stderrTail}`] : []
20568
20724
  );
20569
20725
  const manager = managers[0];
20570
20726
  if (managers.length !== 1 || !manager) return null;
20727
+ const pendingDeepSeekImports = /* @__PURE__ */ new Map();
20571
20728
  const inspectHarness = async (input) => {
20572
20729
  const params = harnessInspectParamsSchema.parse(input);
20573
20730
  const result = await manager.sendRequest(HARNESS_INSPECT_METHOD, params);
@@ -20603,13 +20760,47 @@ ${error51.stderrTail}`] : []
20603
20760
  const result = await manager.sendRequest(THREAD_PERMISSION_MODE_SELECT_METHOD, params);
20604
20761
  return harnessConfigurationStateSchema.parse(result);
20605
20762
  };
20763
+ const importDeepSeekModernSession = async (input) => {
20764
+ const params = deepSeekModernSessionImportParamsSchema.parse(input);
20765
+ const pending = pendingDeepSeekImports.get(params.nativeSessionId);
20766
+ if (pending) return pending;
20767
+ const request = (async () => {
20768
+ try {
20769
+ const result = await manager.sendRequest(DEEPSEEK_MODERN_SESSION_IMPORT_METHOD, params);
20770
+ return deepSeekModernSessionImportResultSchema.parse(result);
20771
+ } catch (error51) {
20772
+ throw normalizeDeepSeekSessionError(error51);
20773
+ }
20774
+ })().finally(() => {
20775
+ if (pendingDeepSeekImports.get(params.nativeSessionId) === request) {
20776
+ pendingDeepSeekImports.delete(params.nativeSessionId);
20777
+ }
20778
+ });
20779
+ pendingDeepSeekImports.set(params.nativeSessionId, request);
20780
+ return request;
20781
+ };
20606
20782
  return Object.freeze({
20783
+ async listDeepSeekModernSessions(input) {
20784
+ const params = deepSeekModernSessionListParamsSchema.parse(input);
20785
+ try {
20786
+ const result = await manager.sendRequest(DEEPSEEK_MODERN_SESSION_LIST_METHOD, params);
20787
+ return deepSeekModernSessionListResultSchema.parse(result);
20788
+ } catch (error51) {
20789
+ throw normalizeDeepSeekSessionError(error51);
20790
+ }
20791
+ },
20792
+ importDeepSeekModernSession,
20607
20793
  async forkThread(input) {
20608
20794
  const params = externalThreadForkParamsSchema.parse(input);
20609
20795
  const result = await manager.sendRequest(THREAD_FORK_METHOD, params);
20610
20796
  return externalThreadForkResultSchema.parse(result);
20611
20797
  },
20612
20798
  inspectHarness,
20799
+ async openHarnessWebUi(input) {
20800
+ const params = harnessWebUiOpenParamsSchema.parse(input);
20801
+ const result = await manager.sendRequest(HARNESS_WEB_UI_OPEN_METHOD, params);
20802
+ harnessWebUiOpenResultSchema.parse(result);
20803
+ },
20613
20804
  async inspectThread(input) {
20614
20805
  const params = threadInspectionParamsSchema.parse(input);
20615
20806
  const result = await manager.sendRequest(THREAD_INSPECT_METHOD, params);
@@ -21512,6 +21703,55 @@ ${error51.stderrTail}`] : []
21512
21703
  );
21513
21704
  }
21514
21705
 
21706
+ // src/renderer-harness-command-claim.ts
21707
+ function inputEvent(editor, text) {
21708
+ const view = editor.ownerDocument.defaultView;
21709
+ return view?.InputEvent ? new view.InputEvent("input", {
21710
+ bubbles: true,
21711
+ composed: true,
21712
+ data: text,
21713
+ inputType: "insertText"
21714
+ }) : new (view?.Event ?? Event)("input", { bubbles: true, composed: true });
21715
+ }
21716
+ function prependTextarea(editor, prefix) {
21717
+ const view = editor.ownerDocument.defaultView;
21718
+ if (!view || !(editor instanceof view.HTMLTextAreaElement)) return false;
21719
+ const setter = Object.getOwnPropertyDescriptor(view.HTMLTextAreaElement.prototype, "value")?.set;
21720
+ if (!setter) return false;
21721
+ const start = editor.selectionStart;
21722
+ const end = editor.selectionEnd;
21723
+ setter.call(editor, prefix + editor.value);
21724
+ editor.dispatchEvent(inputEvent(editor, prefix));
21725
+ editor.focus({ preventScroll: true });
21726
+ if (start !== null && end !== null) {
21727
+ editor.setSelectionRange(start + prefix.length, end + prefix.length);
21728
+ }
21729
+ return true;
21730
+ }
21731
+ function prependContentEditable(editor, prefix) {
21732
+ if (editor.getAttribute("contenteditable") !== "true") return false;
21733
+ const document2 = editor.ownerDocument;
21734
+ const selection = document2.getSelection();
21735
+ if (!selection || typeof document2.execCommand !== "function") return false;
21736
+ const range = document2.createRange();
21737
+ range.selectNodeContents(editor);
21738
+ range.collapse(true);
21739
+ editor.focus({ preventScroll: true });
21740
+ selection.removeAllRanges();
21741
+ selection.addRange(range);
21742
+ return document2.execCommand("insertText", false, prefix);
21743
+ }
21744
+ function prependEditor(editor, prefix) {
21745
+ return prependTextarea(editor, prefix) || prependContentEditable(editor, prefix);
21746
+ }
21747
+ function routeRendererHarnessCommandSelection(editor, command, execute) {
21748
+ if (command.argumentMode === "none") {
21749
+ execute();
21750
+ return true;
21751
+ }
21752
+ return editor !== null && prependEditor(editor, `${command.invocation} `);
21753
+ }
21754
+
21515
21755
  // src/codex-locale-adapter.ts
21516
21756
  var GET_LOCALE_OVERRIDE_URL = "vscode://codex/get-setting";
21517
21757
  var GET_LOCALE_INFO_URL = "vscode://codex/locale-info";
@@ -21534,7 +21774,7 @@ ${error51.stderrTail}`] : []
21534
21774
  }
21535
21775
  return canonicalLocale(ownerWindow.navigator.language);
21536
21776
  }
21537
- function abortError() {
21777
+ function abortError2() {
21538
21778
  return new DOMException("The operation was aborted", "AbortError");
21539
21779
  }
21540
21780
  function parseLocaleOverride(value) {
@@ -21564,7 +21804,7 @@ ${error51.stderrTail}`] : []
21564
21804
  if (typeof bridge?.sendMessageFromView !== "function") {
21565
21805
  return Promise.reject(new Error("Codex locale bridge is unavailable"));
21566
21806
  }
21567
- if (signal?.aborted) return Promise.reject(abortError());
21807
+ if (signal?.aborted) return Promise.reject(abortError2());
21568
21808
  const requestId = ownerWindow.crypto.randomUUID();
21569
21809
  return new Promise((resolve, reject) => {
21570
21810
  let settled = false;
@@ -21579,7 +21819,7 @@ ${error51.stderrTail}`] : []
21579
21819
  cleanup();
21580
21820
  operation();
21581
21821
  };
21582
- const onAbort = () => settle(() => reject(abortError()));
21822
+ const onAbort = () => settle(() => reject(abortError2()));
21583
21823
  const onMessage = (event) => {
21584
21824
  const message2 = event.data;
21585
21825
  if (!isRecord7(message2) || message2.type !== "fetch-response") return;
@@ -21646,12 +21886,12 @@ ${error51.stderrTail}`] : []
21646
21886
  if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {
21647
21887
  throw new Error("Codex locale request timeout must be positive");
21648
21888
  }
21649
- if (options.signal?.aborted) throw abortError();
21889
+ if (options.signal?.aborted) throw abortError2();
21650
21890
  const [overrideResult, localeInfoResult] = await Promise.allSettled([
21651
21891
  readLocaleOverride(ownerWindow, options.signal, timeoutMs),
21652
21892
  readLocaleInfo(ownerWindow, options.signal, timeoutMs)
21653
21893
  ]);
21654
- if (options.signal?.aborted) throw abortError();
21894
+ if (options.signal?.aborted) throw abortError2();
21655
21895
  const navigatorLocale = firstNavigatorLocale(ownerWindow);
21656
21896
  const overrideKnown = overrideResult.status === "fulfilled";
21657
21897
  const localeOverride = overrideKnown ? overrideResult.value.value : void 0;
@@ -21794,6 +22034,343 @@ ${error51.stderrTail}`] : []
21794
22034
  }
21795
22035
  };
21796
22036
 
22037
+ // src/settings/deepseek-session-import-page.ts
22038
+ var SESSION_IMPORT_HARNESSES = KNOWN_RENDERER_AGENTS.filter(
22039
+ (agent) => agent !== "codex"
22040
+ );
22041
+ function shortSessionId(value) {
22042
+ return value.length <= 18 ? value : `${value.slice(0, 10)}\u2026${value.slice(-6)}`;
22043
+ }
22044
+ function createStatus(document2, message, error51 = false) {
22045
+ const status = document2.createElement("div");
22046
+ status.className = error51 ? "settings-session-import-status is-error" : "settings-session-import-status";
22047
+ status.setAttribute("role", error51 ? "alert" : "status");
22048
+ status.append(createRendererSettingsIcon(error51 ? "alert" : "download", 18));
22049
+ const copy = document2.createElement("span");
22050
+ copy.textContent = message;
22051
+ status.append(copy);
22052
+ return status;
22053
+ }
22054
+ function createAccessibleText(document2, message) {
22055
+ const text = document2.createElement("span");
22056
+ text.className = "settings-visually-hidden";
22057
+ text.textContent = message;
22058
+ return text;
22059
+ }
22060
+ function createDeepSeekSessionImportSettingsPage(messages, getClient, openImportedThread) {
22061
+ return Object.freeze({
22062
+ id: "session-import",
22063
+ label: messages.pageLabels["session-import"],
22064
+ icon: "download",
22065
+ mount(context) {
22066
+ const document2 = context.content.ownerDocument;
22067
+ const header = document2.createElement("div");
22068
+ header.className = "settings-session-import-header";
22069
+ const heading = document2.createElement("h2");
22070
+ heading.className = "settings-section-label";
22071
+ heading.textContent = messages.pageLabels["session-import"];
22072
+ const refresh = document2.createElement("button");
22073
+ refresh.type = "button";
22074
+ refresh.className = "settings-command-button settings-command-button--secondary";
22075
+ refresh.dataset.sessionImportAction = "refresh";
22076
+ const setRefreshLabel = (loading) => {
22077
+ refresh.replaceChildren(
22078
+ createRendererSettingsIcon("refresh", 15),
22079
+ loading ? messages.sessionImportRefreshing : messages.sessionImportRefresh
22080
+ );
22081
+ };
22082
+ setRefreshLabel(false);
22083
+ header.append(heading, refresh);
22084
+ const harness = document2.createElement("div");
22085
+ harness.className = "settings-session-import-harness";
22086
+ const harnessLabel = document2.createElement("span");
22087
+ harnessLabel.textContent = messages.sessionImportHarness;
22088
+ const harnessOptions = document2.createElement("div");
22089
+ harnessOptions.className = "settings-session-import-harness__options";
22090
+ harnessOptions.dataset.sessionImportHarness = "selector";
22091
+ harnessOptions.setAttribute("role", "group");
22092
+ harnessOptions.setAttribute("aria-label", messages.sessionImportHarness);
22093
+ for (const agent of SESSION_IMPORT_HARNESSES) {
22094
+ const option = document2.createElement("button");
22095
+ option.type = "button";
22096
+ option.className = "settings-session-import-harness__option";
22097
+ option.dataset.sessionImportHarnessOption = agent;
22098
+ option.textContent = RENDERER_AGENT_LABELS[agent];
22099
+ option.disabled = agent !== "deepseek-harness";
22100
+ option.setAttribute("aria-pressed", agent === "deepseek-harness" ? "true" : "false");
22101
+ harnessOptions.append(option);
22102
+ }
22103
+ harness.append(harnessLabel, harnessOptions);
22104
+ const description = document2.createElement("p");
22105
+ description.className = "settings-page-description";
22106
+ description.textContent = messages.sessionImportDescription;
22107
+ const availabilityNote = document2.createElement("p");
22108
+ availabilityNote.className = "settings-page-description settings-session-import-availability-note";
22109
+ availabilityNote.textContent = messages.sessionImportAvailabilityNote;
22110
+ const content = document2.createElement("section");
22111
+ content.className = "settings-session-import-content";
22112
+ context.content.append(header, harness, description, availabilityNote, content);
22113
+ let candidates = [];
22114
+ let importingId = null;
22115
+ let actions = [];
22116
+ const updateImportActions = () => {
22117
+ for (const { button, candidate } of actions) {
22118
+ const importing = importingId === candidate.nativeSessionId;
22119
+ button.disabled = candidate.running;
22120
+ button.setAttribute(
22121
+ "aria-disabled",
22122
+ candidate.running || importingId !== null ? "true" : "false"
22123
+ );
22124
+ button.setAttribute("aria-busy", importing ? "true" : "false");
22125
+ button.replaceChildren(
22126
+ createRendererSettingsIcon("download", 15),
22127
+ importing ? messages.sessionImportImporting : messages.sessionImportAction
22128
+ );
22129
+ }
22130
+ };
22131
+ const renderUnavailable = (focus = false) => {
22132
+ candidates = [];
22133
+ actions = [];
22134
+ const status = createStatus(document2, messages.sessionImportUnavailable);
22135
+ content.replaceChildren(status);
22136
+ if (focus) {
22137
+ status.tabIndex = -1;
22138
+ status.focus();
22139
+ }
22140
+ };
22141
+ const renderFailure = (error51, operation = "list") => {
22142
+ if (error51 instanceof RendererDeepSeekSessionUnavailableError) {
22143
+ renderUnavailable(operation === "import");
22144
+ return;
22145
+ }
22146
+ actions = [];
22147
+ const status = createStatus(
22148
+ document2,
22149
+ operation === "import" ? messages.sessionImportFailed : messages.sessionImportLoadFailed,
22150
+ true
22151
+ );
22152
+ content.replaceChildren(status);
22153
+ if (operation === "import") {
22154
+ status.tabIndex = -1;
22155
+ status.focus();
22156
+ }
22157
+ };
22158
+ const renderOpenRecovery = (candidate, threadId) => {
22159
+ actions = [];
22160
+ refresh.disabled = false;
22161
+ const recovery = document2.createElement("section");
22162
+ recovery.className = "settings-session-import-recovery";
22163
+ recovery.setAttribute("role", "region");
22164
+ recovery.setAttribute("aria-label", messages.sessionImportImported);
22165
+ recovery.tabIndex = -1;
22166
+ const recoveryCopy = document2.createElement("div");
22167
+ recoveryCopy.className = "settings-session-import-recovery__copy";
22168
+ const title = document2.createElement("strong");
22169
+ title.textContent = messages.sessionImportImported;
22170
+ const explanation = document2.createElement("p");
22171
+ explanation.textContent = messages.sessionImportOpenFailed;
22172
+ recoveryCopy.append(title, explanation);
22173
+ const path = document2.createElement("div");
22174
+ path.className = "settings-session-import-recovery__path";
22175
+ const cwd = document2.createElement("code");
22176
+ cwd.textContent = candidate.cwd;
22177
+ cwd.title = candidate.cwd;
22178
+ const copyPath = document2.createElement("button");
22179
+ copyPath.type = "button";
22180
+ copyPath.className = "settings-command-button settings-command-button--secondary";
22181
+ copyPath.dataset.sessionImportAction = "copy-project-path";
22182
+ const setCopyLabel = (label) => {
22183
+ copyPath.replaceChildren(createRendererSettingsIcon("copy", 15), label);
22184
+ };
22185
+ const showCopyFeedback = (label) => {
22186
+ setCopyLabel(label);
22187
+ document2.defaultView?.setTimeout(
22188
+ () => setCopyLabel(messages.sessionImportCopyProjectPath),
22189
+ 2e3
22190
+ );
22191
+ };
22192
+ setCopyLabel(messages.sessionImportCopyProjectPath);
22193
+ copyPath.addEventListener("click", () => {
22194
+ const clipboard = document2.defaultView?.navigator.clipboard;
22195
+ if (!clipboard) {
22196
+ showCopyFeedback(messages.sessionImportPathCopyFailed);
22197
+ return;
22198
+ }
22199
+ void clipboard.writeText(candidate.cwd).then(
22200
+ () => showCopyFeedback(messages.sessionImportPathCopied),
22201
+ () => showCopyFeedback(messages.sessionImportPathCopyFailed)
22202
+ );
22203
+ });
22204
+ path.append(cwd, copyPath);
22205
+ const retry = document2.createElement("button");
22206
+ retry.type = "button";
22207
+ retry.className = "settings-command-button";
22208
+ retry.dataset.sessionImportAction = "retry-open";
22209
+ const setRetrying = (pending) => {
22210
+ retry.disabled = pending;
22211
+ refresh.disabled = pending;
22212
+ retry.setAttribute("aria-busy", pending ? "true" : "false");
22213
+ retry.replaceChildren(
22214
+ createRendererSettingsIcon("refresh", 15),
22215
+ pending ? messages.sessionImportRetrying : messages.sessionImportRetryOpen
22216
+ );
22217
+ };
22218
+ setRetrying(false);
22219
+ retry.addEventListener("click", () => {
22220
+ if (retry.disabled) return;
22221
+ setRetrying(true);
22222
+ void context.runLatest((signal) => openImportedThread(threadId, signal), {
22223
+ success() {
22224
+ setRetrying(false);
22225
+ },
22226
+ failure() {
22227
+ renderOpenRecovery(candidate, threadId);
22228
+ }
22229
+ });
22230
+ });
22231
+ recovery.append(recoveryCopy, path, retry);
22232
+ content.replaceChildren(recovery);
22233
+ recovery.focus();
22234
+ };
22235
+ const renderCandidates = () => {
22236
+ actions = [];
22237
+ content.replaceChildren();
22238
+ if (candidates.length === 0) {
22239
+ content.append(createStatus(document2, messages.sessionImportEmpty));
22240
+ return;
22241
+ }
22242
+ const list = document2.createElement("div");
22243
+ list.className = "settings-session-import-list";
22244
+ for (const candidate of candidates) {
22245
+ const row = document2.createElement("article");
22246
+ row.className = "settings-session-import-row";
22247
+ row.dataset.sessionImportId = candidate.nativeSessionId;
22248
+ const copy = document2.createElement("div");
22249
+ copy.className = "settings-session-import-row__copy";
22250
+ const title = document2.createElement("strong");
22251
+ title.textContent = candidate.title ?? messages.sessionImportUntitled;
22252
+ const metadata = document2.createElement("span");
22253
+ metadata.textContent = `${messages.sessionImportUpdatedAt}: ${new Intl.DateTimeFormat(
22254
+ messages.locale === "zh-CN" ? "zh-CN" : "en",
22255
+ { dateStyle: "medium", timeStyle: "short" }
22256
+ ).format(new Date(candidate.updatedAt))}`;
22257
+ const cwd = document2.createElement("code");
22258
+ cwd.className = "settings-session-import-row__cwd";
22259
+ cwd.textContent = candidate.cwd;
22260
+ cwd.title = candidate.cwd;
22261
+ const identity = document2.createElement("span");
22262
+ identity.textContent = `${messages.sessionImportSessionId}: ${shortSessionId(candidate.nativeSessionId)}`;
22263
+ identity.title = candidate.nativeSessionId;
22264
+ identity.setAttribute("aria-hidden", "true");
22265
+ copy.append(
22266
+ title,
22267
+ metadata,
22268
+ cwd,
22269
+ identity,
22270
+ createAccessibleText(
22271
+ document2,
22272
+ `${messages.sessionImportSessionId}: ${candidate.nativeSessionId}`
22273
+ )
22274
+ );
22275
+ const actionArea = document2.createElement("div");
22276
+ actionArea.className = "settings-session-import-row__action";
22277
+ if (candidate.running) {
22278
+ const running = document2.createElement("span");
22279
+ running.className = "settings-session-import-running";
22280
+ running.textContent = messages.sessionImportRunning;
22281
+ running.title = messages.sessionImportRunningHint;
22282
+ running.setAttribute("aria-hidden", "true");
22283
+ actionArea.append(
22284
+ running,
22285
+ createAccessibleText(
22286
+ document2,
22287
+ `${messages.sessionImportRunning}: ${messages.sessionImportRunningHint}`
22288
+ )
22289
+ );
22290
+ }
22291
+ const action = document2.createElement("button");
22292
+ action.type = "button";
22293
+ action.className = "settings-command-button";
22294
+ action.dataset.sessionImportAction = "import";
22295
+ action.addEventListener("click", () => {
22296
+ if (candidate.running || importingId !== null) return;
22297
+ const client = getClient();
22298
+ if (!client) {
22299
+ renderUnavailable(true);
22300
+ return;
22301
+ }
22302
+ importingId = candidate.nativeSessionId;
22303
+ refresh.disabled = true;
22304
+ updateImportActions();
22305
+ let committedThreadId = null;
22306
+ void context.runLatest(
22307
+ async (signal) => {
22308
+ const result = await client.importDeepSeekModernSession({
22309
+ nativeSessionId: candidate.nativeSessionId
22310
+ });
22311
+ committedThreadId = result.threadId;
22312
+ await openImportedThread(result.threadId, signal);
22313
+ },
22314
+ {
22315
+ success() {
22316
+ importingId = null;
22317
+ refresh.disabled = false;
22318
+ updateImportActions();
22319
+ },
22320
+ failure(error51) {
22321
+ importingId = null;
22322
+ refresh.disabled = false;
22323
+ if (committedThreadId) {
22324
+ renderOpenRecovery(candidate, committedThreadId);
22325
+ } else {
22326
+ renderFailure(error51, "import");
22327
+ }
22328
+ }
22329
+ }
22330
+ );
22331
+ });
22332
+ actions.push({ button: action, candidate });
22333
+ actionArea.append(action);
22334
+ row.append(copy, actionArea);
22335
+ list.append(row);
22336
+ }
22337
+ content.append(list);
22338
+ updateImportActions();
22339
+ };
22340
+ const load = () => {
22341
+ if (importingId !== null) return;
22342
+ const client = getClient();
22343
+ if (!client) {
22344
+ refresh.disabled = false;
22345
+ setRefreshLabel(false);
22346
+ renderUnavailable();
22347
+ return;
22348
+ }
22349
+ refresh.disabled = true;
22350
+ setRefreshLabel(true);
22351
+ content.replaceChildren(createStatus(document2, messages.sessionImportRefreshing));
22352
+ void context.runLatest(() => client.listDeepSeekModernSessions({}), {
22353
+ success(result) {
22354
+ candidates = result.candidates;
22355
+ refresh.disabled = false;
22356
+ setRefreshLabel(false);
22357
+ renderCandidates();
22358
+ },
22359
+ failure(error51) {
22360
+ candidates = [];
22361
+ refresh.disabled = false;
22362
+ setRefreshLabel(false);
22363
+ renderFailure(error51);
22364
+ }
22365
+ });
22366
+ };
22367
+ refresh.addEventListener("click", load);
22368
+ load();
22369
+ return void 0;
22370
+ }
22371
+ });
22372
+ }
22373
+
21797
22374
  // src/settings/release-notes.ts
21798
22375
  var HEADING_PATTERN = /^(#{1,6})[ \t]+(.+?)\s*$/u;
21799
22376
  var BLOCKQUOTE_PATTERN = /^>[ \t]?(.*?)\s*$/u;
@@ -22448,21 +23025,28 @@ ${error51.stderrTail}`] : []
22448
23025
  }
22449
23026
  });
22450
23027
  }
22451
- function createDefaultRendererSettingsPages(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null) {
23028
+ function createDefaultRendererSettingsPages(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null, getSessionImportClient = () => null, openImportedThread = () => Promise.reject(new Error("Imported Thread navigation is unavailable"))) {
22452
23029
  return Object.freeze([
22453
23030
  createConnectionsSettingsPage(messages, getDiagnostics),
23031
+ createDeepSeekSessionImportSettingsPage(messages, getSessionImportClient, openImportedThread),
22454
23032
  updatesPage(messages, getUpdateClient),
22455
23033
  aboutPage(messages)
22456
23034
  ]);
22457
23035
  }
22458
- function createDefaultRendererSettingsRegistry(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null) {
23036
+ function createDefaultRendererSettingsRegistry(messages = DEFAULT_RENDERER_SETTINGS_MESSAGES, getUpdateClient = () => null, getDiagnostics = () => null, getSessionImportClient = () => null, openImportedThread) {
22459
23037
  return createRendererSettingsPageRegistry(
22460
- createDefaultRendererSettingsPages(messages, getUpdateClient, getDiagnostics)
23038
+ createDefaultRendererSettingsPages(
23039
+ messages,
23040
+ getUpdateClient,
23041
+ getDiagnostics,
23042
+ getSessionImportClient,
23043
+ openImportedThread
23044
+ )
22461
23045
  );
22462
23046
  }
22463
23047
 
22464
23048
  // src/settings/shell.css
22465
- var shell_default = ':host {\n --settings-bg: #181818;\n --settings-sidebar: #1c1c1c;\n --settings-panel: transparent;\n --settings-text: #f5f5f5;\n --settings-muted: #a1a1a1;\n --settings-border: rgb(255 255 255 / 10%);\n --settings-divider: rgb(255 255 255 / 10%);\n --settings-hover: rgb(255 255 255 / 6%);\n --settings-active: rgb(51 156 255 / 12%);\n --settings-focus: #339cff;\n color: var(--settings-text);\n color-scheme: dark;\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: 0 24px 64px rgb(0 0 0 / 38%);\n}\n\n.codexhost-settings-dialog::backdrop {\n background: rgb(0 0 0 / 52%);\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: #777;\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 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-nav-star-link {\n margin-top: 0;\n color: var(--settings-text);\n text-decoration: none;\n}\n\n.settings-nav-star-link .codexhost-settings-icon {\n color: #f5c542;\n}\n\n.settings-nav-star-link:hover {\n color: #fff4bd;\n background: rgb(245 197 66 / 8%);\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: rgb(255 255 255 / 7%);\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: rgb(255 255 255 / 9%);\n border: 1px solid rgb(255 255 255 / 6%);\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: rgb(255 255 255 / 16%);\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-connections-layout,\n.settings-connection-list,\n.settings-connection-rows {\n min-width: 0;\n}\n\n.settings-connections-layout {\n display: grid;\n grid-template-columns: minmax(0, 1.55fr) minmax(280px, 0.85fr);\n align-items: start;\n gap: 18px;\n}\n\n.settings-connection-list,\n.settings-connection-inspector {\n overflow: hidden;\n background: rgb(255 255 255 / 2%);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n}\n\n.settings-connection-host-strip {\n display: grid;\n grid-template-columns: 30px minmax(0, 1fr) 30px;\n align-items: center;\n min-width: 0;\n gap: 6px;\n padding: 12px;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-host-scroll {\n display: none;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 34px;\n padding: 0;\n color: var(--settings-muted);\n background: rgb(0 0 0 / 18%);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\n cursor: pointer;\n}\n\n.settings-connection-host-strip[data-connection-host-overflow="true"]\n .settings-connection-host-scroll {\n display: inline-flex;\n}\n\n.settings-connection-host-strip:not([data-connection-host-overflow="true"]) {\n grid-template-columns: minmax(0, 1fr);\n}\n\n.settings-connection-host-scroll:hover:not(:disabled) {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-connection-host-scroll:disabled {\n cursor: default;\n opacity: 0.35;\n}\n\n.settings-connection-host-scroll:focus-visible,\n.settings-connection-host-tab: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-host-tabs {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 6px;\n overflow-x: auto;\n overflow-y: hidden;\n overscroll-behavior-x: contain;\n scrollbar-width: none;\n scroll-behavior: smooth;\n scroll-snap-type: x proximity;\n touch-action: pan-x;\n}\n\n.settings-connection-host-tabs::-webkit-scrollbar {\n display: none;\n}\n\n.settings-connection-host-tab {\n display: inline-flex;\n align-items: center;\n height: 34px;\n min-width: max-content;\n flex: none;\n padding: 0 11px;\n color: var(--settings-muted);\n font: inherit;\n font-size: 12px;\n line-height: 18px;\n white-space: nowrap;\n background: rgb(0 0 0 / 18%);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\n cursor: pointer;\n scroll-snap-align: start;\n}\n\n.settings-connection-host-tab:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-connection-host-tab[aria-selected="true"] {\n color: #e8f3ff;\n font-weight: 600;\n background: var(--settings-active);\n border-color: rgb(51 156 255 / 50%);\n}\n\n.settings-connection-table-header,\n.settings-connection-row {\n display: grid;\n grid-template-columns: minmax(160px, 1fr) minmax(92px, auto) 108px;\n align-items: center;\n min-width: 0;\n gap: 14px;\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: rgb(255 255 255 / 2%);\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-row {\n min-height: 64px;\n padding: 10px 12px;\n cursor: pointer;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-row:last-child {\n border-bottom: 0;\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: #d4d8de;\n font-size: 10px;\n font-weight: 700;\n background: rgb(255 255 255 / 6%);\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-row__status {\n display: inline-flex;\n align-items: center;\n width: fit-content;\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-row__group-toggle {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n color: var(--settings-muted);\n background: transparent;\n border: 0;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.settings-connection-row__group-toggle:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\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-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: rgb(0 0 0 / 18%);\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: #e3e5e8;\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: rgb(0 0 0 / 28%);\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: rgb(255 255 255 / 3%);\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-panel {\n display: grid;\n max-width: 720px;\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-copy p,\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: 2px 0;\n color: #f5c542;\n font-size: 14px;\n font-weight: 600;\n line-height: 22px;\n}\n\n.settings-about-repository {\n display: grid;\n gap: 10px;\n padding-top: 18px;\n border-top: 1px solid var(--settings-divider);\n}\n\n.settings-about-repository-link {\n display: flex;\n align-items: center;\n width: fit-content;\n min-width: 0;\n max-width: 100%;\n gap: 8px;\n color: #7cb8ff;\n font-size: 13px;\n font-weight: 600;\n text-decoration: none;\n}\n\n.settings-about-repository-link:hover {\n text-decoration: underline;\n}\n\n.settings-about-repository-link code {\n min-width: 0;\n overflow: hidden;\n color: var(--settings-muted);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 11px;\n font-weight: 400;\n text-overflow: ellipsis;\n white-space: nowrap;\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.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"] .codexhost-settings-icon,\n.settings-update-panel[data-update-state="downloading"] .codexhost-settings-icon,\n.settings-update-panel[data-update-state="installing"] .codexhost-settings-icon,\n.settings-update-panel[data-update-state="restarting"] .codexhost-settings-icon {\n color: #4aa3f0;\n}\n\n.settings-update-panel[data-update-state="current"] .codexhost-settings-icon {\n color: #4ade80;\n}\n\n.settings-update-panel[data-update-state="failed"] .codexhost-settings-icon,\n.settings-update-panel[data-update-state="error"] .codexhost-settings-icon {\n color: #ef4444;\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: rgb(255 255 255 / 4%);\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: rgb(255 255 255 / 8%);\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: rgb(0 0 0 / 28%);\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-text);\n background: transparent;\n border-color: var(--settings-border);\n}\n\n.settings-command-button:hover,\n.settings-update-link:hover {\n filter: brightness(1.08);\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-nav-star-link {\n margin-top: 0;\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-connections-layout {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .settings-connection-inspector {\n position: static;\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="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 }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n scroll-behavior: auto !important;\n }\n}\n';
23049
+ var shell_default = ':host {\n --settings-bg: #181818;\n --settings-sidebar: #1c1c1c;\n --settings-panel: transparent;\n --settings-text: #f5f5f5;\n --settings-muted: #a1a1a1;\n --settings-border: rgb(255 255 255 / 10%);\n --settings-divider: rgb(255 255 255 / 10%);\n --settings-hover: rgb(255 255 255 / 6%);\n --settings-active: rgb(51 156 255 / 12%);\n --settings-focus: #339cff;\n color: var(--settings-text);\n color-scheme: dark;\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.settings-visually-hidden {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\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: 0 24px 64px rgb(0 0 0 / 38%);\n}\n\n.codexhost-settings-dialog::backdrop {\n background: rgb(0 0 0 / 52%);\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: #777;\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 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-nav-star-link {\n margin-top: 0;\n color: var(--settings-text);\n text-decoration: none;\n}\n\n.settings-nav-star-link .codexhost-settings-icon {\n color: #f5c542;\n}\n\n.settings-nav-star-link:hover {\n color: #fff4bd;\n background: rgb(245 197 66 / 8%);\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 margin: 0;\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: rgb(255 255 255 / 7%);\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: rgb(255 255 255 / 9%);\n border: 1px solid rgb(255 255 255 / 6%);\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-session-import-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 24px;\n}\n\n.settings-session-import-header .settings-section-label {\n min-width: 0;\n}\n\n.settings-session-import-harness {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 12px;\n margin: -12px 0 16px;\n color: var(--settings-muted);\n font-size: 13px;\n}\n\n.settings-session-import-harness > span {\n flex: none;\n}\n\n.settings-session-import-harness__options {\n display: flex;\n align-items: center;\n min-width: 0;\n flex: 1;\n gap: 6px;\n overflow-x: auto;\n overflow-y: hidden;\n scrollbar-width: none;\n}\n\n.settings-session-import-harness__options::-webkit-scrollbar {\n display: none;\n}\n\n.settings-session-import-harness__option {\n min-height: 32px;\n flex: none;\n padding: 6px 10px;\n color: var(--settings-muted);\n font: inherit;\n font-size: 12px;\n white-space: nowrap;\n background: rgb(255 255 255 / 4%);\n border: 1px solid var(--settings-border);\n border-radius: 6px;\n cursor: pointer;\n}\n\n.settings-session-import-harness__option[aria-pressed="true"] {\n color: #e8f3ff;\n background: var(--settings-active);\n border-color: rgb(51 156 255 / 50%);\n}\n\n.settings-session-import-harness__option:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n}\n\n.settings-session-import-harness__option:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 2px;\n}\n\n.settings-session-import-harness + .settings-page-description {\n margin-top: 0;\n margin-bottom: 4px;\n}\n\n.settings-session-import-availability-note {\n margin-top: 0;\n}\n\n.settings-session-import-content,\n.settings-session-import-list {\n display: grid;\n gap: 10px;\n}\n\n.settings-session-import-status {\n display: flex;\n align-items: center;\n min-height: 64px;\n gap: 12px;\n padding: 16px;\n color: var(--settings-muted);\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\n}\n\n.settings-session-import-status.is-error {\n color: #ef4444;\n}\n\n.settings-session-import-recovery {\n display: grid;\n justify-items: start;\n gap: 14px;\n padding: 16px;\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\n}\n\n.settings-session-import-recovery:focus-visible {\n outline: 2px solid var(--settings-focus);\n outline-offset: 2px;\n}\n\n.settings-session-import-recovery__copy {\n display: grid;\n gap: 4px;\n}\n\n.settings-session-import-recovery__copy strong {\n color: var(--settings-text);\n font-size: 14px;\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: stretch;\n width: 100%;\n min-width: 0;\n overflow: hidden;\n border: 1px solid var(--settings-border);\n border-radius: 6px;\n}\n\n.settings-session-import-recovery__path code {\n min-width: 0;\n flex: 1;\n padding: 8px 10px;\n overflow-x: auto;\n color: var(--settings-text);\n font-size: 12px;\n line-height: 20px;\n white-space: nowrap;\n}\n\n.settings-session-import-recovery__path .settings-command-button {\n min-height: 0;\n flex: none;\n border-width: 0 0 0 1px;\n border-radius: 0;\n}\n\n.settings-session-import-row {\n display: grid;\n grid-template-columns: minmax(0, 1fr) auto;\n align-items: center;\n gap: 20px;\n min-width: 0;\n padding: 16px;\n background: var(--settings-panel);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\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 overflow: hidden;\n color: var(--settings-text);\n font-size: 14px;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-session-import-row__copy span,\n.settings-session-import-row__cwd {\n overflow: hidden;\n color: var(--settings-muted);\n font-size: 12px;\n line-height: 18px;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.settings-session-import-row__cwd {\n display: block;\n min-width: 0;\n background: transparent;\n}\n\n.settings-session-import-row__action {\n display: flex;\n align-items: flex-end;\n flex-direction: column;\n gap: 8px;\n}\n\n.settings-session-import-running {\n color: var(--settings-muted);\n font-size: 12px;\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: rgb(255 255 255 / 16%);\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-connections-layout,\n.settings-connection-list,\n.settings-connection-rows {\n min-width: 0;\n}\n\n.settings-connections-layout {\n display: grid;\n grid-template-columns: minmax(0, 1.55fr) minmax(280px, 0.85fr);\n align-items: start;\n gap: 18px;\n}\n\n.settings-connection-list,\n.settings-connection-inspector {\n overflow: hidden;\n background: rgb(255 255 255 / 2%);\n border: 1px solid var(--settings-border);\n border-radius: 12px;\n}\n\n.settings-connection-host-strip {\n display: grid;\n grid-template-columns: 30px minmax(0, 1fr) 30px;\n align-items: center;\n min-width: 0;\n gap: 6px;\n padding: 12px;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-host-scroll {\n display: none;\n align-items: center;\n justify-content: center;\n width: 30px;\n height: 34px;\n padding: 0;\n color: var(--settings-muted);\n background: rgb(0 0 0 / 18%);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\n cursor: pointer;\n}\n\n.settings-connection-host-strip[data-connection-host-overflow="true"]\n .settings-connection-host-scroll {\n display: inline-flex;\n}\n\n.settings-connection-host-strip:not([data-connection-host-overflow="true"]) {\n grid-template-columns: minmax(0, 1fr);\n}\n\n.settings-connection-host-scroll:hover:not(:disabled) {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-connection-host-scroll:disabled {\n cursor: default;\n opacity: 0.35;\n}\n\n.settings-connection-host-scroll:focus-visible,\n.settings-connection-host-tab: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-host-tabs {\n display: flex;\n align-items: center;\n min-width: 0;\n gap: 6px;\n overflow-x: auto;\n overflow-y: hidden;\n overscroll-behavior-x: contain;\n scrollbar-width: none;\n scroll-behavior: smooth;\n scroll-snap-type: x proximity;\n touch-action: pan-x;\n}\n\n.settings-connection-host-tabs::-webkit-scrollbar {\n display: none;\n}\n\n.settings-connection-host-tab {\n display: inline-flex;\n align-items: center;\n height: 34px;\n min-width: max-content;\n flex: none;\n padding: 0 11px;\n color: var(--settings-muted);\n font: inherit;\n font-size: 12px;\n line-height: 18px;\n white-space: nowrap;\n background: rgb(0 0 0 / 18%);\n border: 1px solid var(--settings-border);\n border-radius: 8px;\n cursor: pointer;\n scroll-snap-align: start;\n}\n\n.settings-connection-host-tab:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\n}\n\n.settings-connection-host-tab[aria-selected="true"] {\n color: #e8f3ff;\n font-weight: 600;\n background: var(--settings-active);\n border-color: rgb(51 156 255 / 50%);\n}\n\n.settings-connection-table-header,\n.settings-connection-row {\n display: grid;\n grid-template-columns: minmax(160px, 1fr) minmax(92px, auto) 108px;\n align-items: center;\n min-width: 0;\n gap: 14px;\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: rgb(255 255 255 / 2%);\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-row {\n min-height: 64px;\n padding: 10px 12px;\n cursor: pointer;\n border-bottom: 1px solid var(--settings-divider);\n}\n\n.settings-connection-row:last-child {\n border-bottom: 0;\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: #d4d8de;\n font-size: 10px;\n font-weight: 700;\n background: rgb(255 255 255 / 6%);\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-row__status {\n display: inline-flex;\n align-items: center;\n width: fit-content;\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-row__group-toggle {\n display: inline-flex;\n flex: none;\n align-items: center;\n justify-content: center;\n width: 26px;\n height: 26px;\n color: var(--settings-muted);\n background: transparent;\n border: 0;\n border-radius: 6px;\n cursor: pointer;\n}\n\n.settings-connection-row__group-toggle:hover {\n color: var(--settings-text);\n background: var(--settings-hover);\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-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: rgb(0 0 0 / 18%);\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: #e3e5e8;\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: rgb(0 0 0 / 28%);\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: rgb(255 255 255 / 3%);\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-panel {\n display: grid;\n max-width: 720px;\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-copy p,\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: 2px 0;\n color: #f5c542;\n font-size: 14px;\n font-weight: 600;\n line-height: 22px;\n}\n\n.settings-about-repository {\n display: grid;\n gap: 10px;\n padding-top: 18px;\n border-top: 1px solid var(--settings-divider);\n}\n\n.settings-about-repository-link {\n display: flex;\n align-items: center;\n width: fit-content;\n min-width: 0;\n max-width: 100%;\n gap: 8px;\n color: #7cb8ff;\n font-size: 13px;\n font-weight: 600;\n text-decoration: none;\n}\n\n.settings-about-repository-link:hover {\n text-decoration: underline;\n}\n\n.settings-about-repository-link code {\n min-width: 0;\n overflow: hidden;\n color: var(--settings-muted);\n font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;\n font-size: 11px;\n font-weight: 400;\n text-overflow: ellipsis;\n white-space: nowrap;\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.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"] .codexhost-settings-icon,\n.settings-update-panel[data-update-state="downloading"] .codexhost-settings-icon,\n.settings-update-panel[data-update-state="installing"] .codexhost-settings-icon,\n.settings-update-panel[data-update-state="restarting"] .codexhost-settings-icon {\n color: #4aa3f0;\n}\n\n.settings-update-panel[data-update-state="current"] .codexhost-settings-icon {\n color: #4ade80;\n}\n\n.settings-update-panel[data-update-state="failed"] .codexhost-settings-icon,\n.settings-update-panel[data-update-state="error"] .codexhost-settings-icon {\n color: #ef4444;\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: rgb(255 255 255 / 4%);\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: rgb(255 255 255 / 8%);\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: rgb(0 0 0 / 28%);\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-text);\n background: transparent;\n border-color: var(--settings-border);\n}\n\n.settings-command-button:hover,\n.settings-update-link:hover {\n filter: brightness(1.08);\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.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-session-import-row {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .settings-session-import-row__action {\n align-items: flex-start;\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-nav-star-link {\n margin-top: 0;\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-connections-layout {\n grid-template-columns: minmax(0, 1fr);\n }\n\n .settings-connection-inspector {\n position: static;\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="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 }\n}\n\n@media (prefers-reduced-motion: reduce) {\n *,\n *::before,\n *::after {\n scroll-behavior: auto !important;\n }\n}\n';
22466
23050
 
22467
23051
  // src/settings/shell.ts
22468
23052
  var SETTINGS_SHELL_ATTRIBUTE = "data-codexhost-settings-shell";
@@ -22929,7 +23513,15 @@ ${error51.stderrTail}`] : []
22929
23513
  const definitions = createDefaultRendererSettingsPages(
22930
23514
  messages,
22931
23515
  options.getUpdateClient ?? (() => null),
22932
- options.getConnectionDiagnostics ?? (() => null)
23516
+ options.getConnectionDiagnostics ?? (() => null),
23517
+ options.getSessionImportClient ?? (() => null),
23518
+ async (threadId, signal) => {
23519
+ if (!options.openImportedThread) {
23520
+ throw new Error("Imported Thread navigation is unavailable");
23521
+ }
23522
+ await options.openImportedThread(threadId, signal);
23523
+ if (!disposed && !signal.aborted) shell?.close();
23524
+ }
22933
23525
  );
22934
23526
  const nextShell = installRendererSettingsShell(definitions, messages, ownerWindow.document);
22935
23527
  const nextTrigger = installRendererSettingsHeaderTrigger({
@@ -23364,6 +23956,17 @@ ${error51.stderrTail}`] : []
23364
23956
  const settingsLifecycle = installRendererSettingsLifecycle(window, {
23365
23957
  getUpdateClient: () => modelControl,
23366
23958
  getConnectionDiagnostics: () => connectionDiagnostics,
23959
+ getSessionImportClient: () => {
23960
+ const client = modelClientForHost("local");
23961
+ const list = client?.listDeepSeekModernSessions;
23962
+ const importSession = client?.importDeepSeekModernSession;
23963
+ if (!list || !importSession) return null;
23964
+ return {
23965
+ listDeepSeekModernSessions: (input) => list(input),
23966
+ importDeepSeekModernSession: (input) => importSession(input)
23967
+ };
23968
+ },
23969
+ openImportedThread: (threadId, signal) => openRendererThread(threadId, { hostId: "local", signal }),
23367
23970
  onLocaleChange() {
23368
23971
  for (const mounted of mountedByComposer.values()) renderMounted(mounted);
23369
23972
  }
@@ -23387,6 +23990,9 @@ ${error51.stderrTail}`] : []
23387
23990
  omp: void 0,
23388
23991
  antigravity: void 0
23389
23992
  },
23993
+ webUi: Object.fromEntries(
23994
+ externalAgents.map((agent) => [agent, false])
23995
+ ),
23390
23996
  requestGeneration: 0,
23391
23997
  request: null,
23392
23998
  retryTimer: null,
@@ -23491,6 +24097,17 @@ ${error51.stderrTail}`] : []
23491
24097
  mounted.control.harnessCommands.setExecuting(null);
23492
24098
  }
23493
24099
  };
24100
+ const selectCommand = (mounted, command) => {
24101
+ const threadId = threadIdFromComposerModelTarget(mounted.modelTarget);
24102
+ if (!threadId || !modelControl || controller.get(mounted.composer).agent === "codex") return;
24103
+ const editor = mounted.composer.querySelector(EDITOR_SELECTOR);
24104
+ if (routeRendererHarnessCommandSelection(editor, command, () => {
24105
+ void executeCommand(mounted, command);
24106
+ })) {
24107
+ return;
24108
+ }
24109
+ console.error("codexhost Harness command could not claim the current Composer editor");
24110
+ };
23494
24111
  const applyThreadUsageUpdate = (update) => {
23495
24112
  for (const mounted of mountedByComposer.values()) {
23496
24113
  if (threadIdFromComposerModelTarget(mounted.modelTarget) !== update.threadId) continue;
@@ -24346,12 +24963,14 @@ ${error51.stderrTail}`] : []
24346
24963
  agentsToInspect.map(async (agent) => {
24347
24964
  let status = "error";
24348
24965
  let nextError;
24966
+ let webUiAvailable = false;
24349
24967
  try {
24350
24968
  const inspection = await client.inspectHarness({
24351
24969
  harnessId: externalHarnessIds[agent],
24352
24970
  refresh
24353
24971
  });
24354
24972
  status = inspection.status === "ready" ? "ready" : inspection.status;
24973
+ webUiAvailable = hostId === "local" && inspection.status === "ready" && inspection.webUi?.open === true;
24355
24974
  if (inspection.status !== "ready") {
24356
24975
  const error51 = inspection.error;
24357
24976
  nextError = {
@@ -24377,6 +24996,7 @@ ${error51.stderrTail}`] : []
24377
24996
  const previousStatus = state.availability[agent];
24378
24997
  state.errors[agent] = nextError;
24379
24998
  state.availability = { ...state.availability, [agent]: status };
24999
+ state.webUi = { ...state.webUi, [agent]: webUiAvailable };
24380
25000
  if (hostId !== activeAvailabilityHostId) {
24381
25001
  publishConnectionStatus();
24382
25002
  return;
@@ -24481,7 +25101,8 @@ ${error51.stderrTail}`] : []
24481
25101
  agents: externalAgents.map((agent) => ({
24482
25102
  agent,
24483
25103
  availability: state.availability[agent] ?? "checking",
24484
- error: state.errors[agent] ?? null
25104
+ error: state.errors[agent] ?? null,
25105
+ ...state.webUi[agent] ? { webUiAvailable: true } : {}
24485
25106
  }))
24486
25107
  };
24487
25108
  })
@@ -24493,6 +25114,21 @@ ${error51.stderrTail}`] : []
24493
25114
  (hostId) => refreshHarnessAvailabilityForHost(hostId, true, false, true)
24494
25115
  );
24495
25116
  },
25117
+ async openWebUi(hostId, agent) {
25118
+ const state = hostHarnessAvailabilityState(hostId);
25119
+ const client = hostId === "local" ? modelClientForHost(hostId) : null;
25120
+ if (state.availability[agent] !== "ready" || state.webUi[agent] !== true || !client?.openHarnessWebUi) {
25121
+ throw new Error("Harness Web UI is unavailable");
25122
+ }
25123
+ try {
25124
+ await client.openHarnessWebUi({ harnessId: externalHarnessIds[agent] });
25125
+ } catch (error51) {
25126
+ state.webUi = { ...state.webUi, [agent]: false };
25127
+ publishConnectionStatus();
25128
+ void refreshHarnessAvailabilityForHost(hostId, true, false, true).catch(() => void 0);
25129
+ throw error51;
25130
+ }
25131
+ },
24496
25132
  subscribe(listener) {
24497
25133
  connectionListeners.add(listener);
24498
25134
  return () => connectionListeners.delete(listener);
@@ -24543,7 +25179,7 @@ ${error51.stderrTail}`] : []
24543
25179
  },
24544
25180
  (command) => {
24545
25181
  const mounted2 = mountedByComposer.get(composer);
24546
- if (mounted2) void executeCommand(mounted2, command);
25182
+ if (mounted2) selectCommand(mounted2, command);
24547
25183
  }
24548
25184
  );
24549
25185
  const mounted = {
@@ -24998,7 +25634,14 @@ ${error51.stderrTail}`] : []
24998
25634
  // src/production-entry.ts
24999
25635
  var configuration = window.__codexhostProductionConfigV1;
25000
25636
  delete window.__codexhostProductionConfigV1;
25001
- installRendererBinding(DEFAULT_RENDERER_AGENTS, configuration?.defaultAgent ?? "codex");
25637
+ var install = () => {
25638
+ installRendererBinding(DEFAULT_RENDERER_AGENTS, configuration?.defaultAgent ?? "codex");
25639
+ };
25640
+ if (document.documentElement && document.body) {
25641
+ install();
25642
+ } else {
25643
+ window.addEventListener("DOMContentLoaded", install, { once: true });
25644
+ }
25002
25645
  })();
25003
25646
  /*! Bundled license information:
25004
25647