@tutti-os/agent-gui 0.0.63 → 0.0.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/dist/agent-conversation/index.d.ts +2 -2
  2. package/dist/agent-conversation/index.js +7 -7
  3. package/dist/agent-env/index.js +2 -1
  4. package/dist/agent-env/index.js.map +1 -1
  5. package/dist/agent-message-center/index.js +9 -9
  6. package/dist/{agentGuiNodeTypes-CC52zXAV.d.ts → agentGuiNodeTypes-CCjzXdTe.d.ts} +4 -1
  7. package/dist/app/renderer/agentactivity.css +38 -4
  8. package/dist/app/renderer/assets/icons/agents/agent-colorful.png +0 -0
  9. package/dist/app/renderer/assets/icons/agents/cursor-colorful.png +0 -0
  10. package/dist/app/renderer/assets/icons/agents/cursor-flat-filled.svg +3 -0
  11. package/dist/app/renderer/assets/icons/agents/cursor-rounded.png +0 -0
  12. package/dist/{chunk-IIVHPXAB.js → chunk-2IMBPRKV.js} +1 -1
  13. package/dist/chunk-2IMBPRKV.js.map +1 -0
  14. package/dist/{chunk-4UTWOSHP.js → chunk-3NSUJ7OF.js} +5 -1
  15. package/dist/chunk-3NSUJ7OF.js.map +1 -0
  16. package/dist/{chunk-SGXYVGQT.js → chunk-52VZ54WH.js} +5 -5
  17. package/dist/{chunk-CVSCZ3CK.js → chunk-76GTKO4Q.js} +7 -2
  18. package/dist/chunk-76GTKO4Q.js.map +1 -0
  19. package/dist/{chunk-G6UO6JVM.js → chunk-C465B7WK.js} +2 -2
  20. package/dist/{chunk-22L4VWUR.js → chunk-CKCUEHBW.js} +3 -1
  21. package/dist/chunk-CKCUEHBW.js.map +1 -0
  22. package/dist/{chunk-FRCIPTUD.js → chunk-ERWDRI3F.js} +8 -18
  23. package/dist/chunk-ERWDRI3F.js.map +1 -0
  24. package/dist/{chunk-6MUKWI6Z.js → chunk-F6GDUU4X.js} +167 -113
  25. package/dist/chunk-F6GDUU4X.js.map +1 -0
  26. package/dist/{chunk-FQQDBBNI.js → chunk-FLTLZGIN.js} +3 -3
  27. package/dist/{chunk-5WB3NGIN.js → chunk-FUJ73PTH.js} +29 -2
  28. package/dist/chunk-FUJ73PTH.js.map +1 -0
  29. package/dist/{chunk-RO6KQD3J.js → chunk-IIXCU2UU.js} +2 -2
  30. package/dist/{chunk-CA25GD5Q.js → chunk-MQ6RKXXW.js} +34 -4
  31. package/dist/chunk-MQ6RKXXW.js.map +1 -0
  32. package/dist/{chunk-NZN43XT5.js → chunk-PVVM7MZZ.js} +8 -6
  33. package/dist/chunk-PVVM7MZZ.js.map +1 -0
  34. package/dist/{chunk-V4JGVBUN.js → chunk-R2NGSPQS.js} +32 -1
  35. package/dist/chunk-R2NGSPQS.js.map +1 -0
  36. package/dist/{chunk-QC642RAG.js → chunk-RDRKIMAC.js} +15 -8
  37. package/dist/chunk-RDRKIMAC.js.map +1 -0
  38. package/dist/{chunk-ZUVEBW5T.js → chunk-TFPKI4XJ.js} +2 -2
  39. package/dist/{chunk-SW6JCJCO.js → chunk-TT2YJNEP.js} +3 -3
  40. package/dist/{chunk-K4UUEG7X.js → chunk-YFTQK2G4.js} +113 -34
  41. package/dist/chunk-YFTQK2G4.js.map +1 -0
  42. package/dist/{chunk-3KS22CG2.js → chunk-YUMHFZ5A.js} +3 -3
  43. package/dist/{chunk-7P6CUYQT.js → chunk-ZTZ6STJZ.js} +2 -2
  44. package/dist/context-mention-palette/index.js +8 -8
  45. package/dist/cursor-flat-filled-CL7N3BTZ.svg +3 -0
  46. package/dist/i18n/index.d.ts +33 -3
  47. package/dist/i18n/index.js +2 -2
  48. package/dist/index.d.ts +7 -5
  49. package/dist/index.js +666 -214
  50. package/dist/index.js.map +1 -1
  51. package/dist/queued-prompt-runtime.d.ts +2 -2
  52. package/dist/{types-DSc2ta3s.d.ts → types-BAPEle8b.d.ts} +3 -3
  53. package/dist/workbench/contribution.d.ts +10 -3
  54. package/dist/workbench/contribution.js +10 -8
  55. package/dist/workbench/index.d.ts +4 -2
  56. package/dist/workbench/index.js +11 -11
  57. package/dist/workbench/launch.d.ts +1 -1
  58. package/dist/workbench/launch.js +3 -3
  59. package/dist/workbench/providerCatalog.d.ts +2 -2
  60. package/dist/workbench/providerCatalog.js +1 -1
  61. package/dist/workbench/sessionTitle.d.ts +1 -1
  62. package/dist/workbench/sessionTitle.js +3 -3
  63. package/dist/workbench/state.d.ts +1 -1
  64. package/dist/workbench/state.js +3 -3
  65. package/dist/workbench/types.d.ts +3 -2
  66. package/dist/workbench/types.js +1 -1
  67. package/dist/workspace-agent-generated-files.js +3 -3
  68. package/package.json +12 -12
  69. package/dist/chunk-22L4VWUR.js.map +0 -1
  70. package/dist/chunk-4UTWOSHP.js.map +0 -1
  71. package/dist/chunk-5WB3NGIN.js.map +0 -1
  72. package/dist/chunk-6MUKWI6Z.js.map +0 -1
  73. package/dist/chunk-CA25GD5Q.js.map +0 -1
  74. package/dist/chunk-CVSCZ3CK.js.map +0 -1
  75. package/dist/chunk-FRCIPTUD.js.map +0 -1
  76. package/dist/chunk-IIVHPXAB.js.map +0 -1
  77. package/dist/chunk-K4UUEG7X.js.map +0 -1
  78. package/dist/chunk-NZN43XT5.js.map +0 -1
  79. package/dist/chunk-QC642RAG.js.map +0 -1
  80. package/dist/chunk-V4JGVBUN.js.map +0 -1
  81. /package/dist/{chunk-SGXYVGQT.js.map → chunk-52VZ54WH.js.map} +0 -0
  82. /package/dist/{chunk-G6UO6JVM.js.map → chunk-C465B7WK.js.map} +0 -0
  83. /package/dist/{chunk-FQQDBBNI.js.map → chunk-FLTLZGIN.js.map} +0 -0
  84. /package/dist/{chunk-RO6KQD3J.js.map → chunk-IIXCU2UU.js.map} +0 -0
  85. /package/dist/{chunk-ZUVEBW5T.js.map → chunk-TFPKI4XJ.js.map} +0 -0
  86. /package/dist/{chunk-SW6JCJCO.js.map → chunk-TT2YJNEP.js.map} +0 -0
  87. /package/dist/{chunk-3KS22CG2.js.map → chunk-YUMHFZ5A.js.map} +0 -0
  88. /package/dist/{chunk-7P6CUYQT.js.map → chunk-ZTZ6STJZ.js.map} +0 -0
package/dist/index.js CHANGED
@@ -7,9 +7,10 @@ import {
7
7
  clampAgentGUIConversationRailWidthPx,
8
8
  resolveAgentGUIConversationRailMaxWidthPx,
9
9
  resolveAgentGUIExpandedWindowFrame,
10
+ resolveAgentGuiSessionProviderIconUrl,
10
11
  resolveNextAgentGUIConversationRailWidthPx,
11
12
  shouldAutoCollapseAgentGUIConversationRail
12
- } from "./chunk-5WB3NGIN.js";
13
+ } from "./chunk-FUJ73PTH.js";
13
14
  import {
14
15
  agentGUIDefaultTargetProviders,
15
16
  agentGUIProviderTargetRefsEqual,
@@ -20,11 +21,11 @@ import {
20
21
  localAgentGUIProviderTargetId,
21
22
  normalizeAgentGUIProviderTargets,
22
23
  resolveAgentGUIProviderTarget
23
- } from "./chunk-4UTWOSHP.js";
24
+ } from "./chunk-3NSUJ7OF.js";
24
25
  import {
25
26
  AgentInteractivePromptSurface,
26
27
  approvalOptionDisplayLabel
27
- } from "./chunk-QC642RAG.js";
28
+ } from "./chunk-RDRKIMAC.js";
28
29
  import {
29
30
  PLAN_IMPLEMENTATION_ACTION_FEEDBACK,
30
31
  PLAN_IMPLEMENTATION_ACTION_IMPLEMENT,
@@ -43,7 +44,7 @@ import {
43
44
  resolveAgentGUIExplicitConversationTitle,
44
45
  resolveAgentGUIProviderDisplayLabel,
45
46
  resolveAgentGUIProviderIdentity
46
- } from "./chunk-CVSCZ3CK.js";
47
+ } from "./chunk-76GTKO4Q.js";
47
48
  import {
48
49
  AgentConversationFlow,
49
50
  Button,
@@ -64,14 +65,14 @@ import {
64
65
  skillTriggerForPrefix,
65
66
  toLocalShortDateTime,
66
67
  useProjectedAgentConversation
67
- } from "./chunk-6MUKWI6Z.js";
68
+ } from "./chunk-F6GDUU4X.js";
68
69
  import {
69
70
  AgentMessageMarkdown,
70
71
  AgentTargetPresentationProvider,
71
72
  ZoomableImage,
72
73
  cn,
73
74
  resolveWorkspaceLinkAction
74
- } from "./chunk-SW6JCJCO.js";
75
+ } from "./chunk-TT2YJNEP.js";
75
76
  import {
76
77
  openAgentEnvPanel
77
78
  } from "./chunk-PSLAWU25.js";
@@ -82,7 +83,7 @@ import {
82
83
  DEFAULT_AGENT_MENTION_FILTER,
83
84
  agentMentionItemKey,
84
85
  preloadAgentMentionBrowse
85
- } from "./chunk-SGXYVGQT.js";
86
+ } from "./chunk-52VZ54WH.js";
86
87
  import {
87
88
  WORKSPACE_AGENT_ACTIVITY_RUNTIME_SESSION_ORIGIN,
88
89
  buildWorkspaceAgentActivityListViewModel,
@@ -92,10 +93,10 @@ import {
92
93
  isWorkspaceAgentUntitledTask,
93
94
  mergeWorkspaceAgentActivityDurableAndOverlayMessages,
94
95
  selectWorkspaceAgentActivityOverlayMessages
95
- } from "./chunk-7P6CUYQT.js";
96
+ } from "./chunk-ZTZ6STJZ.js";
96
97
  import {
97
98
  Spinner
98
- } from "./chunk-ZUVEBW5T.js";
99
+ } from "./chunk-TFPKI4XJ.js";
99
100
  import {
100
101
  resolveWorkspaceAgentSessionSortTimeUnixMs
101
102
  } from "./chunk-IBIMGLCD.js";
@@ -106,7 +107,7 @@ import {
106
107
  mentionItemToAttrs,
107
108
  normalizeAgentSessionMentionTitle,
108
109
  parseMentionItemFromHref
109
- } from "./chunk-FQQDBBNI.js";
110
+ } from "./chunk-FLTLZGIN.js";
110
111
  import "./chunk-Y35GDLP2.js";
111
112
  import "./chunk-LUGELG5V.js";
112
113
  import {
@@ -119,7 +120,6 @@ import {
119
120
  getAgentCustomMentionKind,
120
121
  getOptionalAgentActivityRuntime,
121
122
  getOptionalAgentHostApi,
122
- normalizeManagedAgentProvider,
123
123
  registerAgentCustomMentionKind,
124
124
  resetAgentActivityRuntimeForTests,
125
125
  resetAgentCustomMentionKindsForTests,
@@ -129,7 +129,7 @@ import {
129
129
  useAgentHostApi,
130
130
  useOptionalAgentActivityRuntime,
131
131
  useOptionalAgentHostApi
132
- } from "./chunk-FRCIPTUD.js";
132
+ } from "./chunk-ERWDRI3F.js";
133
133
  import "./chunk-TYGL25EL.js";
134
134
  import {
135
135
  AgentGuiI18nProvider,
@@ -137,10 +137,14 @@ import {
137
137
  agentGuiI18nResources,
138
138
  translate,
139
139
  useTranslation
140
- } from "./chunk-RO6KQD3J.js";
140
+ } from "./chunk-IIXCU2UU.js";
141
141
  import "./chunk-PJP5BUU6.js";
142
- import "./chunk-V4JGVBUN.js";
143
- import "./chunk-CA25GD5Q.js";
142
+ import {
143
+ agentColorfulUrl,
144
+ cursorColorfulUrl,
145
+ normalizeManagedAgentProvider
146
+ } from "./chunk-R2NGSPQS.js";
147
+ import "./chunk-MQ6RKXXW.js";
144
148
  import {
145
149
  AGENT_CONTEXT_MENTION_PROVIDER_IDS
146
150
  } from "./chunk-JM24HADP.js";
@@ -2256,6 +2260,7 @@ import {
2256
2260
  var AGENT_PROVIDERS = [
2257
2261
  "claude-code",
2258
2262
  "codex",
2263
+ "cursor",
2259
2264
  "nexight",
2260
2265
  "opencode",
2261
2266
  "gemini",
@@ -2298,6 +2303,7 @@ var DEFAULT_AGENT_SETTINGS = {
2298
2303
  customModelEnabledByProvider: {
2299
2304
  "claude-code": false,
2300
2305
  codex: false,
2306
+ cursor: false,
2301
2307
  nexight: false,
2302
2308
  opencode: false,
2303
2309
  gemini: false,
@@ -2307,6 +2313,7 @@ var DEFAULT_AGENT_SETTINGS = {
2307
2313
  customModelByProvider: {
2308
2314
  "claude-code": "",
2309
2315
  codex: "",
2316
+ cursor: "",
2310
2317
  nexight: "",
2311
2318
  opencode: "",
2312
2319
  gemini: "",
@@ -2316,6 +2323,7 @@ var DEFAULT_AGENT_SETTINGS = {
2316
2323
  customModelOptionsByProvider: {
2317
2324
  "claude-code": [],
2318
2325
  codex: [],
2326
+ cursor: [],
2319
2327
  nexight: [],
2320
2328
  opencode: [],
2321
2329
  gemini: [],
@@ -6478,6 +6486,46 @@ function reasoningConfigOptionIdForProvider(provider) {
6478
6486
  function speedConfigOptionIdForProvider(provider) {
6479
6487
  return provider === "codex" ? "service_tier" : "fast";
6480
6488
  }
6489
+ function liveModelOptionValuesFromRuntimeContext(runtimeContext) {
6490
+ const configOptions = runtimeContext?.configOptions;
6491
+ if (!Array.isArray(configOptions)) {
6492
+ return [];
6493
+ }
6494
+ for (const optionRaw of configOptions) {
6495
+ if (!optionRaw || typeof optionRaw !== "object") {
6496
+ continue;
6497
+ }
6498
+ const option = optionRaw;
6499
+ if (normalizeConfigOptionValue(option.id) !== "model") {
6500
+ continue;
6501
+ }
6502
+ const entries = option.options;
6503
+ if (!Array.isArray(entries)) {
6504
+ return [];
6505
+ }
6506
+ const values = [];
6507
+ for (const entryRaw of entries) {
6508
+ if (!entryRaw || typeof entryRaw !== "object") {
6509
+ continue;
6510
+ }
6511
+ const value = normalizeConfigOptionValue(
6512
+ entryRaw.value
6513
+ );
6514
+ if (value) {
6515
+ values.push(value);
6516
+ }
6517
+ }
6518
+ return values;
6519
+ }
6520
+ return [];
6521
+ }
6522
+ function composerOptionsMissingLiveModelValues(options, liveValues) {
6523
+ if (!options || liveValues.length === 0) {
6524
+ return false;
6525
+ }
6526
+ const known = new Set(options.models.map((option) => option.value));
6527
+ return liveValues.some((value) => !known.has(value));
6528
+ }
6481
6529
  function resolveEffectiveComposerSettings(input) {
6482
6530
  return {
6483
6531
  model: normalizeOptionalText(input.settings.model) ?? null,
@@ -8221,7 +8269,7 @@ function arePermissionConfigsEqual(left, right) {
8221
8269
  );
8222
8270
  }
8223
8271
  function areComposerSettingsVMsEqual(left, right) {
8224
- return sameComposerSettings(left.sessionSettings, right.sessionSettings) && areComposerSettingsDraftsEqual(left.draftSettings, right.draftSettings) && left.supportsModel === right.supportsModel && left.supportsReasoningEffort === right.supportsReasoningEffort && left.supportsSpeed === right.supportsSpeed && (left.supportsPermissionMode ?? false) === (right.supportsPermissionMode ?? false) && left.supportsPlanMode === right.supportsPlanMode && (left.supportsBrowser ?? false) === (right.supportsBrowser ?? false) && (left.supportsComputerUse ?? false) === (right.supportsComputerUse ?? false) && left.isSettingsLoading === right.isSettingsLoading && Boolean(left.isModelOptionsLoading) === Boolean(right.isModelOptionsLoading) && left.modelUnavailable === right.modelUnavailable && left.reasoningUnavailable === right.reasoningUnavailable && left.speedUnavailable === right.speedUnavailable && (left.permissionModeUnavailable ?? false) === (right.permissionModeUnavailable ?? false) && (left.planExclusiveWithPermissionMode ?? false) === (right.planExclusiveWithPermissionMode ?? false) && (left.selectedModelValue ?? null) === (right.selectedModelValue ?? null) && (left.selectedReasoningEffortValue ?? null) === (right.selectedReasoningEffortValue ?? null) && (left.selectedSpeedValue ?? null) === (right.selectedSpeedValue ?? null) && (left.selectedPermissionModeValue ?? null) === (right.selectedPermissionModeValue ?? null) && arePermissionConfigsEqual(left.permissionConfig, right.permissionConfig) && (left.selectedProjectPath ?? null) === (right.selectedProjectPath ?? null) && Boolean(left.projectLocked) === Boolean(right.projectLocked) && areComposerSettingOptionListsEqual(
8272
+ return sameComposerSettings(left.sessionSettings, right.sessionSettings) && areComposerSettingsDraftsEqual(left.draftSettings, right.draftSettings) && left.supportsModel === right.supportsModel && left.supportsReasoningEffort === right.supportsReasoningEffort && left.supportsSpeed === right.supportsSpeed && (left.supportsPermissionMode ?? false) === (right.supportsPermissionMode ?? false) && left.supportsPlanMode === right.supportsPlanMode && (left.supportsBrowser ?? false) === (right.supportsBrowser ?? false) && (left.supportsComputerUse ?? false) === (right.supportsComputerUse ?? false) && left.isSettingsLoading === right.isSettingsLoading && Boolean(left.isModelOptionsLoading) === Boolean(right.isModelOptionsLoading) && left.modelUnavailable === right.modelUnavailable && left.reasoningUnavailable === right.reasoningUnavailable && left.speedUnavailable === right.speedUnavailable && (left.permissionModeUnavailable ?? false) === (right.permissionModeUnavailable ?? false) && (left.planExclusiveWithPermissionMode ?? false) === (right.planExclusiveWithPermissionMode ?? false) && (left.selectedModelValue ?? null) === (right.selectedModelValue ?? null) && (left.selectedReasoningEffortValue ?? null) === (right.selectedReasoningEffortValue ?? null) && (left.selectedSpeedValue ?? null) === (right.selectedSpeedValue ?? null) && (left.selectedPermissionModeValue ?? null) === (right.selectedPermissionModeValue ?? null) && arePermissionConfigsEqual(left.permissionConfig, right.permissionConfig) && (left.selectedProjectPath ?? null) === (right.selectedProjectPath ?? null) && Boolean(left.projectLocked) === Boolean(right.projectLocked) && Boolean(left.modelListCollapsedToLatest) === Boolean(right.modelListCollapsedToLatest) && areComposerSettingOptionListsEqual(
8225
8273
  left.availableModels,
8226
8274
  right.availableModels
8227
8275
  ) && areComposerSettingOptionListsEqual(
@@ -8782,6 +8830,16 @@ function normalizedPositiveNumber2(value) {
8782
8830
  function timelineItemTime(item) {
8783
8831
  return item.occurredAtUnixMs ?? item.createdAtUnixMs ?? 0;
8784
8832
  }
8833
+ var emptyComingSoonProviders = [];
8834
+ function applyComingSoonProviderTargets(targets, comingSoonProviders) {
8835
+ if (comingSoonProviders.length === 0) {
8836
+ return targets;
8837
+ }
8838
+ const comingSoon = new Set(comingSoonProviders);
8839
+ return targets.map(
8840
+ (target) => comingSoon.has(target.provider) && target.disabled !== true ? { ...target, disabled: true } : target
8841
+ );
8842
+ }
8785
8843
  function useAgentGUINodeController({
8786
8844
  nodeId,
8787
8845
  workspaceId,
@@ -8791,6 +8849,7 @@ function useAgentGUINodeController({
8791
8849
  data,
8792
8850
  providerTargets,
8793
8851
  providerTargetsLoading = false,
8852
+ comingSoonProviders,
8794
8853
  providerReadinessGates = null,
8795
8854
  defaultProviderTargetId = null,
8796
8855
  openSessionRequest = null,
@@ -8804,25 +8863,36 @@ function useAgentGUINodeController({
8804
8863
  const agentQueuedPromptRuntime = useAgentQueuedPromptRuntime();
8805
8864
  const agentHostApi = useAgentHostApi();
8806
8865
  const agentActivitySnapshot = useAgentActivitySnapshot(workspaceId);
8866
+ const normalizedComingSoonProviders = useMemo4(
8867
+ () => comingSoonProviders && comingSoonProviders.length > 0 ? [...comingSoonProviders] : emptyComingSoonProviders,
8868
+ [comingSoonProviders]
8869
+ );
8807
8870
  const normalizedExplicitProviderTargets = useMemo4(
8808
- () => normalizeAgentGUIProviderTargets(providerTargets, {
8809
- includeDisabledPlaceholders: true,
8810
- useStaticCatalog: false
8811
- }),
8812
- [providerTargets]
8871
+ () => applyComingSoonProviderTargets(
8872
+ normalizeAgentGUIProviderTargets(providerTargets, {
8873
+ includeDisabledPlaceholders: true,
8874
+ useStaticCatalog: false
8875
+ }),
8876
+ normalizedComingSoonProviders
8877
+ ),
8878
+ [normalizedComingSoonProviders, providerTargets]
8813
8879
  );
8814
8880
  const normalizedProviderTargets = useMemo4(() => {
8815
8881
  if (providerTargetsLoading) {
8816
8882
  return [];
8817
8883
  }
8818
8884
  if (providerTargets === void 0 || normalizedExplicitProviderTargets.length === 0) {
8819
- return normalizeAgentGUIProviderTargets(null, {
8820
- includeDisabledPlaceholders: true
8821
- });
8885
+ return applyComingSoonProviderTargets(
8886
+ normalizeAgentGUIProviderTargets(null, {
8887
+ includeDisabledPlaceholders: true
8888
+ }),
8889
+ normalizedComingSoonProviders
8890
+ );
8822
8891
  }
8823
8892
  return normalizedExplicitProviderTargets;
8824
8893
  }, [
8825
8894
  normalizedExplicitProviderTargets,
8895
+ normalizedComingSoonProviders,
8826
8896
  providerTargets,
8827
8897
  providerTargetsLoading
8828
8898
  ]);
@@ -9014,6 +9084,8 @@ function useAgentGUINodeController({
9014
9084
  const [isDeletingProjectConversations, setIsDeletingProjectConversations] = useState4(false);
9015
9085
  const updatingSessionSettingsIdsRef = useRef4({});
9016
9086
  const queuedComposerSettingsUpdatesRef = useRef4({});
9087
+ const pendingActivationComposerSettingsPatchRef = useRef4({});
9088
+ const flushQueuedComposerSettingsUpdateRef = useRef4(null);
9017
9089
  const [pendingDeleteConversation, setPendingDeleteConversation] = useState4(null);
9018
9090
  const [
9019
9091
  pendingDeleteProjectConversations,
@@ -9290,6 +9362,7 @@ function useAgentGUINodeController({
9290
9362
  transientConversation
9291
9363
  );
9292
9364
  const startingConversationIdRef = useRef4(null);
9365
+ const pendingHomeErrorRef = useRef4(null);
9293
9366
  const activatedConversationIdsRef = useRef4(/* @__PURE__ */ new Set());
9294
9367
  const failedNewConversationIdsRef = useRef4(/* @__PURE__ */ new Set());
9295
9368
  const lastActiveModelByProviderRef = useRef4({});
@@ -10859,6 +10932,35 @@ function useAgentGUINodeController({
10859
10932
  supports.permission,
10860
10933
  supports.reasoning
10861
10934
  ]);
10935
+ const liveModelOptionValuesKey = useMemo4(
10936
+ () => liveModelOptionValuesFromRuntimeContext(activeSessionRuntimeContext).join(
10937
+ "\0"
10938
+ ),
10939
+ [activeSessionRuntimeContext]
10940
+ );
10941
+ const liveModelRefreshRequestedKeyRef = useRef4(null);
10942
+ useEffect4(() => {
10943
+ if (previewMode || liveModelOptionValuesKey === "") {
10944
+ return;
10945
+ }
10946
+ const liveValues = liveModelOptionValuesKey.split("\0");
10947
+ if (!composerOptionsMissingLiveModelValues(
10948
+ providerComposerOptions,
10949
+ liveValues
10950
+ )) {
10951
+ return;
10952
+ }
10953
+ if (liveModelRefreshRequestedKeyRef.current === liveModelOptionValuesKey) {
10954
+ return;
10955
+ }
10956
+ liveModelRefreshRequestedKeyRef.current = liveModelOptionValuesKey;
10957
+ loadDraftComposerOptions({ force: true });
10958
+ }, [
10959
+ liveModelOptionValuesKey,
10960
+ loadDraftComposerOptions,
10961
+ previewMode,
10962
+ providerComposerOptions
10963
+ ]);
10862
10964
  useEffect4(() => {
10863
10965
  if (previewMode) {
10864
10966
  return void 0;
@@ -11426,7 +11528,9 @@ function useAgentGUINodeController({
11426
11528
  return;
11427
11529
  }
11428
11530
  if (!activeConversationId) {
11429
- setDetailError(null);
11531
+ const pendingHomeError = pendingHomeErrorRef.current;
11532
+ pendingHomeErrorRef.current = null;
11533
+ setDetailError(pendingHomeError ?? null);
11430
11534
  return;
11431
11535
  }
11432
11536
  if (failedNewConversationIdsRef.current.has(activeConversationId)) {
@@ -11674,6 +11778,17 @@ function useAgentGUINodeController({
11674
11778
  workspaceId,
11675
11779
  fields: { mode: "new" }
11676
11780
  });
11781
+ setTransientConversation(optimisticConversation);
11782
+ setDraftBySessionId((current) => ({
11783
+ ...current,
11784
+ [agentSessionId]: emptyAgentComposerDraft()
11785
+ }));
11786
+ isComposerHomeRef.current = false;
11787
+ setIsComposerHome(false);
11788
+ activeConversationIdRef.current = agentSessionId;
11789
+ setActiveConversationId(agentSessionId);
11790
+ setIntent({ tag: "active", id: agentSessionId });
11791
+ persistActiveConversation(agentSessionId);
11677
11792
  reportAgentSubmitTraceDiagnostic({
11678
11793
  event: "activation.requested",
11679
11794
  runtime: agentActivityRuntime,
@@ -11730,6 +11845,7 @@ function useAgentGUINodeController({
11730
11845
  }
11731
11846
  if (activationFailed) {
11732
11847
  failedNewConversationIdsRef.current.add(agentSessionId);
11848
+ delete pendingActivationComposerSettingsPatchRef.current[agentSessionId];
11733
11849
  resetAgentSessionViewDetailMessages(sessionViewRef(agentSessionId));
11734
11850
  setAgentSessionViewOverlayMessages(
11735
11851
  sessionViewRef(agentSessionId),
@@ -11738,15 +11854,25 @@ function useAgentGUINodeController({
11738
11854
  if (startingConversationIdRef.current === agentSessionId) {
11739
11855
  startingConversationIdRef.current = null;
11740
11856
  }
11741
- if (isMountedRef.current && activeConversationIdRef.current === null && isComposerHomeRef.current) {
11857
+ const shouldRevertToHome = isMountedRef.current && (isCurrentConversation(agentSessionId) || activeConversationIdRef.current === null && isComposerHomeRef.current);
11858
+ if (shouldRevertToHome) {
11859
+ const homeErrorMessage = result.error?.message?.trim() || "Session activation failed.";
11860
+ if (isCurrentConversation(agentSessionId)) {
11861
+ pendingHomeErrorRef.current = homeErrorMessage;
11862
+ isComposerHomeRef.current = true;
11863
+ setIsComposerHome(true);
11864
+ activeConversationIdRef.current = null;
11865
+ setActiveConversationId(null);
11866
+ setIntent({ tag: "home" });
11867
+ persistActiveConversation(null);
11868
+ setTransientConversation(null);
11869
+ }
11742
11870
  setIsLoadingMessages(false);
11743
11871
  setAgentSessionViewMessagesLoading(
11744
11872
  sessionViewRef(agentSessionId),
11745
11873
  false
11746
11874
  );
11747
- setDetailError(
11748
- result.error?.message?.trim() || "Session activation failed."
11749
- );
11875
+ setDetailError(homeErrorMessage);
11750
11876
  }
11751
11877
  return;
11752
11878
  }
@@ -11768,6 +11894,7 @@ function useAgentGUINodeController({
11768
11894
  const isPendingCreatedConversation = startingConversationIdRef.current === agentSessionId;
11769
11895
  if (!isMountedRef.current) {
11770
11896
  void activation.unactivate(conversation2.id);
11897
+ delete pendingActivationComposerSettingsPatchRef.current[conversation2.id];
11771
11898
  if (isPendingCreatedConversation) {
11772
11899
  startingConversationIdRef.current = null;
11773
11900
  }
@@ -11778,12 +11905,32 @@ function useAgentGUINodeController({
11778
11905
  if (isPendingCreatedConversation) {
11779
11906
  startingConversationIdRef.current = null;
11780
11907
  }
11908
+ resetAgentSessionViewDetailMessages(
11909
+ sessionViewRef(conversation2.id)
11910
+ );
11911
+ setAgentSessionViewOverlayMessages(
11912
+ sessionViewRef(conversation2.id),
11913
+ []
11914
+ );
11915
+ if (transientConversationRef.current?.id === conversation2.id) {
11916
+ setTransientConversation(null);
11917
+ }
11918
+ delete pendingActivationComposerSettingsPatchRef.current[conversation2.id];
11781
11919
  return;
11782
11920
  }
11783
11921
  if (isPendingCreatedConversation) {
11784
11922
  startingConversationIdRef.current = null;
11785
11923
  }
11786
11924
  activatedConversationIdsRef.current.add(conversation2.id);
11925
+ const pendingComposerSettingsPatch = pendingActivationComposerSettingsPatchRef.current[conversation2.id];
11926
+ if (pendingComposerSettingsPatch) {
11927
+ delete pendingActivationComposerSettingsPatchRef.current[conversation2.id];
11928
+ markSessionSettingsRequestState(conversation2.id, true);
11929
+ flushQueuedComposerSettingsUpdateRef.current?.({
11930
+ agentSessionId: conversation2.id,
11931
+ sessionSettingsPatch: pendingComposerSettingsPatch
11932
+ });
11933
+ }
11787
11934
  setTransientConversation(conversation2);
11788
11935
  if (conversationListQuery) {
11789
11936
  const createdAgentTargetId = normalizeOptionalText2(conversation2.agentTargetId) ?? targetData.agentTargetId;
@@ -11855,7 +12002,8 @@ function useAgentGUINodeController({
11855
12002
  conversationId: pendingCreateAgentSessionId ?? agentSessionId
11856
12003
  });
11857
12004
  }
11858
- const shouldShowErrorOnHome = startingConversationIdRef.current === agentSessionId || activeConversationIdRef.current === null;
12005
+ delete pendingActivationComposerSettingsPatchRef.current[agentSessionId];
12006
+ const shouldShowErrorOnHome = isCurrentConversation(agentSessionId) || activeConversationIdRef.current === null && isComposerHomeRef.current;
11859
12007
  const submitTrace = submitTraceBySessionIdRef.current[agentSessionId];
11860
12008
  if (submitTrace) {
11861
12009
  const nextTraces = { ...submitTraceBySessionIdRef.current };
@@ -11908,6 +12056,15 @@ function useAgentGUINodeController({
11908
12056
  if (startingConversationIdRef.current === agentSessionId) {
11909
12057
  startingConversationIdRef.current = null;
11910
12058
  }
12059
+ if (isCurrentConversation(agentSessionId)) {
12060
+ pendingHomeErrorRef.current = message;
12061
+ isComposerHomeRef.current = true;
12062
+ setIsComposerHome(true);
12063
+ activeConversationIdRef.current = null;
12064
+ setActiveConversationId(null);
12065
+ setIntent({ tag: "home" });
12066
+ persistActiveConversation(null);
12067
+ }
11911
12068
  if (transientConversationRef.current?.id === agentSessionId) {
11912
12069
  setTransientConversation(null);
11913
12070
  }
@@ -11938,6 +12095,7 @@ function useAgentGUINodeController({
11938
12095
  conversationListQuery,
11939
12096
  isCurrentConversation,
11940
12097
  agentActivityRuntime,
12098
+ markSessionSettingsRequestState,
11941
12099
  pendingCreateOwnerKey,
11942
12100
  recordLocalMessages,
11943
12101
  unactivateIfStale,
@@ -12682,8 +12840,7 @@ function useAgentGUINodeController({
12682
12840
  return;
12683
12841
  }
12684
12842
  const activeTurnId = activeSessionState?.turnLifecycle?.activeTurnId?.trim() ?? "";
12685
- const canSteerActiveTurn = activeTurnId !== "" || activeSessionState?.submitAvailability?.reason === "active_turn";
12686
- if (!canSteerActiveTurn) {
12843
+ if (activeTurnId === "") {
12687
12844
  return;
12688
12845
  }
12689
12846
  const displayPromptText = displayPrompt && displayPrompt.trim() ? displayPrompt : void 0;
@@ -13031,6 +13188,7 @@ function useAgentGUINodeController({
13031
13188
  sessionViewRef
13032
13189
  ]
13033
13190
  );
13191
+ flushQueuedComposerSettingsUpdateRef.current = flushQueuedComposerSettingsUpdate;
13034
13192
  const updateComposerSettings = useCallback4(
13035
13193
  (nextSettings) => {
13036
13194
  const supportedNextSettings = {
@@ -13107,6 +13265,7 @@ function useAgentGUINodeController({
13107
13265
  return;
13108
13266
  }
13109
13267
  const activeSessionState2 = getAgentSessionView(sessionViewRef(agentSessionId))?.controlState ?? null;
13268
+ const isPreActivationSession = activeSessionState2 === null && activation.stateFor(agentSessionId) === "activating";
13110
13269
  const sessionSettings2 = cloneComposerSettings(
13111
13270
  activeSessionState2?.settings ?? null
13112
13271
  );
@@ -13145,9 +13304,9 @@ function useAgentGUINodeController({
13145
13304
  if (nextComputerUse !== void 0 && nextComputerUse !== currentComputerUse) {
13146
13305
  sessionSettingsPatch.computerUse = nextComputerUse;
13147
13306
  }
13148
- if (nextPermission !== void 0 && nextPermission && nextPermission !== currentPermission && activeSessionState2 !== null) {
13307
+ if (nextPermission !== void 0 && nextPermission && nextPermission !== currentPermission && (activeSessionState2 !== null || isPreActivationSession)) {
13149
13308
  sessionSettingsPatch.permissionModeId = normalizePermissionModeId(nextPermission);
13150
- const turnPhase = activeSessionState2.turnLifecycle?.phase;
13309
+ const turnPhase = activeSessionState2?.turnLifecycle?.phase;
13151
13310
  const isTurnInFlight = turnPhase === "running" || turnPhase === "submitted";
13152
13311
  if (dataRef.current.provider === "codex" && isTurnInFlight) {
13153
13312
  onShowMessageRef.current?.(
@@ -13156,22 +13315,33 @@ function useAgentGUINodeController({
13156
13315
  );
13157
13316
  }
13158
13317
  }
13159
- if (Object.keys(sessionSettingsPatch).length > 0 && activeSessionState2 !== null) {
13318
+ if (Object.keys(sessionSettingsPatch).length > 0 && (activeSessionState2 !== null || isPreActivationSession)) {
13160
13319
  updateAgentSessionViewControlState(
13161
13320
  sessionViewRef(agentSessionId),
13162
- (existing) => existing ? {
13163
- ...existing,
13164
- permissionModeId: sessionSettingsPatch.permissionModeId ?? existing.permissionModeId,
13165
- runtimeContext: mergeRuntimeContextComposerSettings(
13166
- dataRef.current.provider,
13167
- existing.runtimeContext,
13168
- sessionSettingsPatch
13169
- ),
13170
- settings: {
13171
- ...existing.settings ?? {},
13172
- ...sessionSettingsPatch
13173
- }
13174
- } : existing
13321
+ (existing) => {
13322
+ const base = existing ?? {
13323
+ workspaceId,
13324
+ agentSessionId,
13325
+ provider: dataRef.current.provider,
13326
+ status: "working",
13327
+ updatedAtUnixMs: Date.now(),
13328
+ settings: {}
13329
+ };
13330
+ const nextState = {
13331
+ ...base,
13332
+ permissionModeId: sessionSettingsPatch.permissionModeId ?? base.permissionModeId,
13333
+ runtimeContext: mergeRuntimeContextComposerSettings(
13334
+ dataRef.current.provider,
13335
+ base.runtimeContext,
13336
+ sessionSettingsPatch
13337
+ ),
13338
+ settings: {
13339
+ ...base.settings ?? {},
13340
+ ...sessionSettingsPatch
13341
+ }
13342
+ };
13343
+ return nextState;
13344
+ }
13175
13345
  );
13176
13346
  void onRememberComposerDefaultsRef.current?.({
13177
13347
  agentTargetId: normalizeOptionalText2(dataRef.current.agentTargetId),
@@ -13213,7 +13383,16 @@ function useAgentGUINodeController({
13213
13383
  (current) => nodeDataFromComposerSettings(current, nextNodeDefaults)
13214
13384
  );
13215
13385
  }
13216
- if (updatingSessionSettingsIdsRef.current[agentSessionId]) {
13386
+ if (isPreActivationSession) {
13387
+ const pendingPatch = pendingActivationComposerSettingsPatchRef.current[agentSessionId];
13388
+ pendingActivationComposerSettingsPatchRef.current = {
13389
+ ...pendingActivationComposerSettingsPatchRef.current,
13390
+ [agentSessionId]: {
13391
+ ...pendingPatch ?? {},
13392
+ ...sessionSettingsPatch
13393
+ }
13394
+ };
13395
+ } else if (updatingSessionSettingsIdsRef.current[agentSessionId]) {
13217
13396
  const queuedUpdate = queuedComposerSettingsUpdatesRef.current[agentSessionId];
13218
13397
  queuedComposerSettingsUpdatesRef.current[agentSessionId] = {
13219
13398
  sessionSettingsPatch: {
@@ -13232,6 +13411,7 @@ function useAgentGUINodeController({
13232
13411
  }
13233
13412
  },
13234
13413
  [
13414
+ activation,
13235
13415
  defaultReasoningEffort,
13236
13416
  activeTimelineItems,
13237
13417
  flushQueuedComposerSettingsUpdate,
@@ -13399,21 +13579,20 @@ function useAgentGUINodeController({
13399
13579
  if (!normalizedPath || !remove) {
13400
13580
  return;
13401
13581
  }
13402
- const previousProjects = userProjectsRef.current;
13403
13582
  setListError(null);
13404
- setUserProjectsSnapshot(
13405
- previousProjects.filter((project) => project.path !== normalizedPath)
13406
- );
13407
13583
  const handleRemoveError = (error) => {
13408
13584
  const message = getAgentGUIErrorMessage(error);
13409
- setUserProjectsSnapshot(previousProjects);
13410
13585
  setListError(message);
13411
13586
  toast.error(message);
13412
13587
  };
13413
13588
  try {
13414
- void Promise.resolve(remove({ path: normalizedPath })).catch(
13415
- handleRemoveError
13416
- );
13589
+ void Promise.resolve(remove({ path: normalizedPath })).then(() => {
13590
+ setUserProjectsSnapshot(
13591
+ userProjectsRef.current.filter(
13592
+ (project) => project.path !== normalizedPath
13593
+ )
13594
+ );
13595
+ }).catch(handleRemoveError);
13417
13596
  } catch (error) {
13418
13597
  handleRemoveError(error);
13419
13598
  }
@@ -13967,10 +14146,10 @@ function useAgentGUINodeController({
13967
14146
  null
13968
14147
  );
13969
14148
  const visibleConversations = useMemo4(() => {
13970
- const source = isLoadingConversations ? mergeVisibleConversations(
14149
+ const source = mergeVisibleConversations(
13971
14150
  conversations,
13972
14151
  transientConversationRef.current
13973
- ) : conversations;
14152
+ );
13974
14153
  const mapped = source.map((conversation2) => {
13975
14154
  const withRuntime = mergeConversationSummaryWithRuntimeSession({
13976
14155
  conversation: conversation2,
@@ -13993,7 +14172,6 @@ function useAgentGUINodeController({
13993
14172
  }, [
13994
14173
  agentActivityDisplayStatuses,
13995
14174
  conversations,
13996
- isLoadingConversations,
13997
14175
  isNoProjectPath,
13998
14176
  stableRuntimeSyncStateBySessionId,
13999
14177
  transientConversation,
@@ -14281,8 +14459,10 @@ function useAgentGUINodeController({
14281
14459
  )
14282
14460
  });
14283
14461
  const draftSettings = activeConversationId ? sessionSettings ?? defaultConversationDraftSettings : homeComposerSettings;
14284
- const liveConfigModel = activeConversationId !== null ? configOptionCurrentValue(activeSessionRuntimeContext, ["model"]) : null;
14285
- const draftModel = liveConfigModel ?? normalizeOptionalText2(draftSettings.model);
14462
+ const persistedDraftModel = normalizeOptionalText2(draftSettings.model);
14463
+ const usesPlaceholderDraftModel = persistedDraftModel === null || persistedDraftModel === "default";
14464
+ const liveConfigModel = activeConversationId !== null && usesPlaceholderDraftModel ? configOptionCurrentValue(activeSessionRuntimeContext, ["model"]) : null;
14465
+ const draftModel = usesPlaceholderDraftModel ? liveConfigModel ?? persistedDraftModel : persistedDraftModel;
14286
14466
  const draftReasoningEffort = normalizeOptionalText2(
14287
14467
  draftSettings.reasoningEffort
14288
14468
  );
@@ -14343,7 +14523,11 @@ function useAgentGUINodeController({
14343
14523
  return {
14344
14524
  auth: hasProviderSessionNotFoundError ? null : authState !== "" ? { message: authMessageFromRuntime ?? authState } : isAuthError ? { message: normalizedError } : null,
14345
14525
  approval: pendingApproval,
14346
- recovery: activeLiveState === "activating" ? {
14526
+ recovery: activeLiveState === "activating" && // Suppress the "reconnecting" banner during a first-message create:
14527
+ // the user just submitted and is already seeing their optimistic
14528
+ // message, so an activation-in-flight state on the conversation they
14529
+ // just entered is not a recovery event.
14530
+ startingConversationIdRef.current !== activeConversationId ? {
14347
14531
  kind: "activating",
14348
14532
  // i18n-check-ignore: Legacy recovery fallback copy; localized presentation should move to view labels.
14349
14533
  message: "Reconnecting to the live agent session\u2026"
@@ -14359,6 +14543,7 @@ function useAgentGUINodeController({
14359
14543
  activationError,
14360
14544
  activationErrorCode,
14361
14545
  activeLiveState,
14546
+ activeConversationId,
14362
14547
  activeConversationResumeUnavailable,
14363
14548
  activeSessionState,
14364
14549
  hasProviderSessionNotFoundError,
@@ -14519,6 +14704,9 @@ function useAgentGUINodeController({
14519
14704
  permissionConfig,
14520
14705
  selectedProjectPath: activeConversationId !== null ? activeConversation?.cwd ?? null : selectedProjectPath,
14521
14706
  projectLocked: activeConversationId !== null,
14707
+ // Cursor's live list spans many vendors with several versions each;
14708
+ // collapse it to the latest release per model family.
14709
+ modelListCollapsedToLatest: composerTargetData.provider === "cursor",
14522
14710
  availableModels: composerSupport.model && hasOptionsSource && activeSessionModelSelection !== null ? activeSessionModelSelection.options : [],
14523
14711
  availableReasoningEfforts: composerSupport.reasoning && hasOptionsSource && activeSessionReasoningSelection !== null ? activeSessionReasoningSelection.options : [],
14524
14712
  availableSpeeds: composerSupport.speed && hasOptionsSource && activeSessionSpeedSelection !== null ? activeSessionSpeedSelection.options : [],
@@ -14892,6 +15080,7 @@ function useAgentGUINodeController({
14892
15080
  selectedProviderTarget: effectiveSelectedProviderTarget,
14893
15081
  providerTargets: normalizedProviderTargets,
14894
15082
  providerTargetsLoading,
15083
+ comingSoonProviders: normalizedComingSoonProviders,
14895
15084
  conversationFilter,
14896
15085
  conversations: visibleConversations,
14897
15086
  userProjects,
@@ -14962,6 +15151,7 @@ function useAgentGUINodeController({
14962
15151
  controllerActions,
14963
15152
  data,
14964
15153
  effectiveSelectedProviderTarget,
15154
+ normalizedComingSoonProviders,
14965
15155
  normalizedProviderTargets,
14966
15156
  providerReadinessGate,
14967
15157
  providerTargetsLoading,
@@ -15186,7 +15376,7 @@ function normalizeInteractiveQuestions(value) {
15186
15376
 
15187
15377
  // agent-gui/agentGuiNode/AgentGUINodeView.tsx
15188
15378
  import {
15189
- Fragment as Fragment7,
15379
+ Fragment as Fragment8,
15190
15380
  memo,
15191
15381
  useCallback as useCallback10,
15192
15382
  useEffect as useEffect13,
@@ -15287,6 +15477,7 @@ import { BareIconButton, ScrollArea } from "@tutti-os/ui-system/components";
15287
15477
  import {
15288
15478
  CreateChatIcon,
15289
15479
  FolderIcon as FolderIcon2,
15480
+ FolderOpenLinedIcon,
15290
15481
  MoreHorizontalIcon
15291
15482
  } from "@tutti-os/ui-system/icons";
15292
15483
 
@@ -16594,6 +16785,10 @@ var CLAUDE_CODE_FALLBACK_COMMANDS = [
16594
16785
  ...ACP_FALLBACK_COMMANDS,
16595
16786
  { name: REVIEW_COMMAND }
16596
16787
  ];
16788
+ var CURSOR_FALLBACK_COMMANDS = [
16789
+ { name: "compact" },
16790
+ { name: "goal" }
16791
+ ];
16597
16792
  var CLAUDE_CODE_SLASH_PALETTE_COMMANDS = /* @__PURE__ */ new Set([
16598
16793
  "compact",
16599
16794
  "context",
@@ -16626,13 +16821,18 @@ var PROVIDER_SLASH_POLICY = {
16626
16821
  immediateCommands: /* @__PURE__ */ new Set(["compact", "context", "usage"]),
16627
16822
  reviewPickerCommands: /* @__PURE__ */ new Set([REVIEW_COMMAND]),
16628
16823
  fallbackCommands: CLAUDE_CODE_FALLBACK_COMMANDS
16824
+ },
16825
+ cursor: {
16826
+ immediateCommands: /* @__PURE__ */ new Set(),
16827
+ reviewPickerCommands: /* @__PURE__ */ new Set(),
16828
+ fallbackCommands: CURSOR_FALLBACK_COMMANDS
16629
16829
  }
16630
16830
  };
16631
16831
  function providerSlashPolicy(provider) {
16632
- return provider === "codex" || provider === "claude-code" ? PROVIDER_SLASH_POLICY[provider] : void 0;
16832
+ return provider === "codex" || provider === "claude-code" || provider === "cursor" ? PROVIDER_SLASH_POLICY[provider] : void 0;
16633
16833
  }
16634
16834
  function isACPProvider(provider) {
16635
- return provider === "codex" || provider === "claude-code";
16835
+ return provider === "codex" || provider === "claude-code" || provider === "cursor";
16636
16836
  }
16637
16837
  function resolveSlashCommandsForProvider({
16638
16838
  provider,
@@ -17474,6 +17674,7 @@ function AgentQueuedPromptPanel({
17474
17674
 
17475
17675
  // agent-gui/agentGuiNode/AgentComposerSettingsMenus.tsx
17476
17676
  import {
17677
+ Fragment as Fragment4,
17477
17678
  cloneElement,
17478
17679
  useEffect as useEffect8,
17479
17680
  useMemo as useMemo5,
@@ -17522,6 +17723,119 @@ function resolvePermissionModeControlsDisabled(options) {
17522
17723
  return options.isSendingTurn || options.isSubmittingPrompt || options.showStopButton;
17523
17724
  }
17524
17725
 
17726
+ // agent-gui/agentGuiNode/model/modelFamilies.ts
17727
+ var modelVariantTokens = /* @__PURE__ */ new Set([
17728
+ "codex",
17729
+ "code",
17730
+ "thinking",
17731
+ "preview",
17732
+ "exp",
17733
+ "experimental",
17734
+ "latest",
17735
+ "fast",
17736
+ "turbo",
17737
+ "minimal",
17738
+ "low",
17739
+ "medium",
17740
+ "high",
17741
+ "xhigh",
17742
+ "max"
17743
+ ]);
17744
+ function normalizedModelName(option) {
17745
+ return (option.label.trim() || option.value).replace(/\[.*\]$/u, "").trim().toLowerCase();
17746
+ }
17747
+ function parseModelFamily(option) {
17748
+ const source = normalizedModelName(option);
17749
+ if (!source) {
17750
+ return null;
17751
+ }
17752
+ const tokens = source.split("-").filter((token) => token !== "");
17753
+ const familyTokens = [];
17754
+ const version = [];
17755
+ for (const token of tokens) {
17756
+ if (/\d/u.test(token)) {
17757
+ for (const segment of token.match(/\d+/gu) ?? []) {
17758
+ version.push(Number.parseInt(segment, 10));
17759
+ }
17760
+ continue;
17761
+ }
17762
+ if (modelVariantTokens.has(token)) {
17763
+ continue;
17764
+ }
17765
+ familyTokens.push(token);
17766
+ }
17767
+ if (familyTokens.length === 0 || version.length === 0) {
17768
+ return null;
17769
+ }
17770
+ return { family: familyTokens.join("-"), version };
17771
+ }
17772
+ function modelVendorLabel(option) {
17773
+ if (!parseModelFamily(option)) {
17774
+ return null;
17775
+ }
17776
+ const vendor = normalizedModelName(option).split("-", 1)[0] ?? "";
17777
+ if (!vendor) {
17778
+ return null;
17779
+ }
17780
+ return vendor.length <= 3 ? vendor.toUpperCase() : vendor.charAt(0).toUpperCase() + vendor.slice(1);
17781
+ }
17782
+ function compareVersions(left, right) {
17783
+ const length = Math.max(left.length, right.length);
17784
+ for (let index = 0; index < length; index += 1) {
17785
+ const difference = (left[index] ?? 0) - (right[index] ?? 0);
17786
+ if (difference !== 0) {
17787
+ return difference;
17788
+ }
17789
+ }
17790
+ return 0;
17791
+ }
17792
+ function collapseModelOptionsToLatest(options) {
17793
+ const slots = [];
17794
+ const slotByFamily = /* @__PURE__ */ new Map();
17795
+ for (const option of options) {
17796
+ const parsed = parseModelFamily(option);
17797
+ if (!parsed) {
17798
+ slots.push(option);
17799
+ continue;
17800
+ }
17801
+ const slot = slotByFamily.get(parsed.family);
17802
+ if (!slot) {
17803
+ const next = {
17804
+ family: parsed.family,
17805
+ option,
17806
+ version: parsed.version
17807
+ };
17808
+ slotByFamily.set(parsed.family, next);
17809
+ slots.push(next);
17810
+ continue;
17811
+ }
17812
+ if (compareVersions(parsed.version, slot.version) > 0) {
17813
+ slot.option = option;
17814
+ slot.version = parsed.version;
17815
+ }
17816
+ }
17817
+ return slots.map((slot) => "family" in slot ? slot.option : slot);
17818
+ }
17819
+ function groupModelOptionsByVendor(options) {
17820
+ const groups = [];
17821
+ const groupByLabel = /* @__PURE__ */ new Map();
17822
+ for (const option of options) {
17823
+ const label = modelVendorLabel(option);
17824
+ let group = groupByLabel.get(label);
17825
+ if (!group) {
17826
+ group = { label, options: [] };
17827
+ groupByLabel.set(label, group);
17828
+ if (label === null) {
17829
+ groups.unshift(group);
17830
+ } else {
17831
+ groups.push(group);
17832
+ }
17833
+ }
17834
+ group.options.push(option);
17835
+ }
17836
+ return groups;
17837
+ }
17838
+
17525
17839
  // agent-gui/agentGuiNode/model/composerSettingsMenuModel.ts
17526
17840
  function buildComposerModelMenuModel(composerSettings, labels) {
17527
17841
  const modelItems = modelOptionsWithSelectedValue(composerSettings);
@@ -17548,14 +17862,18 @@ function buildComposerModelMenuModel(composerSettings, labels) {
17548
17862
  combinedLabel: modelLabel === reasoningLabel ? modelLabel : `${modelLabel} ${reasoningLabel}`.trim(),
17549
17863
  showCombined: modelLabel === reasoningLabel || reasoningLabel.length === 0
17550
17864
  },
17551
- model: {
17552
- show: showModel,
17553
- selectedValue: selectedModelValue,
17554
- selectedLabel: modelLabel,
17555
- options: modelItems.map(
17865
+ model: (() => {
17866
+ const options = modelItems.map(
17556
17867
  (option) => modelMenuOptionFromSettingOption(option, labels)
17557
- )
17558
- },
17868
+ );
17869
+ return {
17870
+ show: showModel,
17871
+ selectedValue: selectedModelValue,
17872
+ selectedLabel: modelLabel,
17873
+ options,
17874
+ groups: showModel && composerSettings.modelListCollapsedToLatest ? groupModelOptionsByVendor(options) : []
17875
+ };
17876
+ })(),
17559
17877
  reasoning: {
17560
17878
  show: showReasoning,
17561
17879
  selectedValue: selectedReasoningValue,
@@ -17819,8 +18137,9 @@ function selectedComposerSpeedValue(composerSettings) {
17819
18137
  return composerSettings.selectedSpeedValue ?? composerSettings.draftSettings.speed ?? null;
17820
18138
  }
17821
18139
  function modelOptionsWithSelectedValue(composerSettings) {
18140
+ const models = composerSettings.modelListCollapsedToLatest ? collapseModelOptionsToLatest(composerSettings.availableModels) : composerSettings.availableModels;
17822
18141
  return optionsWithSelectedValue(
17823
- composerSettings.availableModels,
18142
+ models,
17824
18143
  selectedComposerModelValue(composerSettings)
17825
18144
  );
17826
18145
  }
@@ -17844,7 +18163,7 @@ function optionsWithSelectedValue(options, selectedValue) {
17844
18163
  }
17845
18164
 
17846
18165
  // agent-gui/agentGuiNode/AgentComposerSettingsMenus.tsx
17847
- import { Fragment as Fragment4, jsx as jsx23, jsxs as jsxs11 } from "react/jsx-runtime";
18166
+ import { Fragment as Fragment5, jsx as jsx23, jsxs as jsxs11 } from "react/jsx-runtime";
17848
18167
  function basenameProjectPath(path) {
17849
18168
  const normalized = path.trim().replaceAll("\\", "/").replace(/\/+$/, "");
17850
18169
  return normalized.split("/").filter(Boolean).at(-1) ?? path;
@@ -18218,7 +18537,7 @@ function AgentModelReasoningDropdown({
18218
18537
  strokeWidth: 2.5
18219
18538
  }
18220
18539
  ) : null,
18221
- menu.trigger.showCombined ? /* @__PURE__ */ jsx23("span", { className: "min-w-0 truncate", children: menu.trigger.combinedLabel }) : /* @__PURE__ */ jsxs11(Fragment4, { children: [
18540
+ menu.trigger.showCombined ? /* @__PURE__ */ jsx23("span", { className: "min-w-0 truncate", children: menu.trigger.combinedLabel }) : /* @__PURE__ */ jsxs11(Fragment5, { children: [
18222
18541
  /* @__PURE__ */ jsx23("span", { className: "min-w-0 truncate", children: menu.trigger.modelLabel }),
18223
18542
  /* @__PURE__ */ jsx23("span", { className: "shrink-0", children: menu.trigger.reasoningLabel })
18224
18543
  ] })
@@ -18253,9 +18572,21 @@ function AgentModelReasoningDropdown({
18253
18572
  ),
18254
18573
  "data-agent-composer-settings-layout": "model-primary",
18255
18574
  children: [
18256
- menu.model.show ? /* @__PURE__ */ jsxs11(Fragment4, { children: [
18575
+ menu.model.show ? /* @__PURE__ */ jsxs11(Fragment5, { children: [
18257
18576
  /* @__PURE__ */ jsx23(DropdownMenuLabel2, { children: labels.modelSelectionLabel }),
18258
- /* @__PURE__ */ jsx23(
18577
+ menu.model.groups.length > 0 ? menu.model.groups.map((group, index) => /* @__PURE__ */ jsxs11(Fragment4, { children: [
18578
+ group.label !== null ? /* @__PURE__ */ jsx23(DropdownMenuLabel2, { className: "text-xs text-[var(--agent-gui-text-tertiary)]", children: group.label }) : null,
18579
+ /* @__PURE__ */ jsx23(
18580
+ ComposerMenuOptionItems,
18581
+ {
18582
+ options: group.options,
18583
+ selectedValue: menu.model.selectedValue,
18584
+ descriptionPresentation: "model-tooltip",
18585
+ tooltipsEnabled: !previewMode,
18586
+ onSelect: (value) => applySettingsChange({ model: value })
18587
+ }
18588
+ )
18589
+ ] }, group.label ?? `ungrouped-${index}`)) : /* @__PURE__ */ jsx23(
18259
18590
  ComposerMenuOptionItems,
18260
18591
  {
18261
18592
  options: menu.model.options,
@@ -18338,7 +18669,7 @@ function ComposerMenuOptionItems({
18338
18669
  tooltipsEnabled = true,
18339
18670
  onSelect
18340
18671
  }) {
18341
- return /* @__PURE__ */ jsx23(Fragment4, { children: options.map((option) => {
18672
+ return /* @__PURE__ */ jsx23(Fragment5, { children: options.map((option) => {
18342
18673
  const hasDescription = Boolean(option.description);
18343
18674
  const showInlineDescription = descriptionPresentation === "inline" && hasDescription;
18344
18675
  const showModelTooltip = descriptionPresentation === "model-tooltip";
@@ -19774,8 +20105,8 @@ function AgentRichTextContextMenuButton({
19774
20105
  }
19775
20106
 
19776
20107
  // agent-gui/agentGuiNode/AgentSlashStatusPanel.tsx
19777
- import { Fragment as Fragment5 } from "react";
19778
- import { Fragment as Fragment6, jsx as jsx25, jsxs as jsxs13 } from "react/jsx-runtime";
20108
+ import { Fragment as Fragment6 } from "react";
20109
+ import { Fragment as Fragment7, jsx as jsx25, jsxs as jsxs13 } from "react/jsx-runtime";
19779
20110
  function formatSlashStatusTokenCount(value) {
19780
20111
  if (typeof value !== "number" || !Number.isFinite(value)) {
19781
20112
  return "";
@@ -19829,13 +20160,13 @@ function AgentSlashStatusPanel({
19829
20160
  )
19830
20161
  ] }),
19831
20162
  /* @__PURE__ */ jsxs13("dl", { className: "grid grid-cols-[max-content_minmax(0,1fr)] gap-x-3 gap-y-1 font-mono text-[11px] leading-4", children: [
19832
- showSessionDetails ? /* @__PURE__ */ jsxs13(Fragment6, { children: [
20163
+ showSessionDetails ? /* @__PURE__ */ jsxs13(Fragment7, { children: [
19833
20164
  /* @__PURE__ */ jsxs13("dt", { className: "text-muted-foreground", children: [
19834
20165
  labels.slashStatusSession,
19835
20166
  ":"
19836
20167
  ] }),
19837
20168
  /* @__PURE__ */ jsx25("dd", { className: "min-w-0 truncate", children: agentSessionId }),
19838
- baseUrl ? /* @__PURE__ */ jsxs13(Fragment6, { children: [
20169
+ baseUrl ? /* @__PURE__ */ jsxs13(Fragment7, { children: [
19839
20170
  /* @__PURE__ */ jsxs13("dt", { className: "text-muted-foreground", children: [
19840
20171
  labels.slashStatusBaseUrl,
19841
20172
  ":"
@@ -19848,7 +20179,7 @@ function AgentSlashStatusPanel({
19848
20179
  ] }),
19849
20180
  /* @__PURE__ */ jsx25("dd", { className: "min-w-0", children: slashStatusContextText(status, labels) })
19850
20181
  ] }) : null,
19851
- limits.map((limit) => /* @__PURE__ */ jsxs13(Fragment5, { children: [
20182
+ limits.map((limit) => /* @__PURE__ */ jsxs13(Fragment6, { children: [
19852
20183
  /* @__PURE__ */ jsxs13("dt", { className: "text-muted-foreground", children: [
19853
20184
  limit.label,
19854
20185
  ":"
@@ -19884,7 +20215,7 @@ function AgentSlashStatusPanel({
19884
20215
  ] })
19885
20216
  ] }) })
19886
20217
  ] }, limit.id)),
19887
- limits.length === 0 && status?.limitsLoading ? /* @__PURE__ */ jsxs13(Fragment6, { children: [
20218
+ limits.length === 0 && status?.limitsLoading ? /* @__PURE__ */ jsxs13(Fragment7, { children: [
19888
20219
  /* @__PURE__ */ jsxs13("dt", { className: "text-muted-foreground", children: [
19889
20220
  labels.slashStatusLimits,
19890
20221
  ":"
@@ -20270,18 +20601,19 @@ import { createPortal as createPortal2 } from "react-dom";
20270
20601
  import { jsx as jsx27 } from "react/jsx-runtime";
20271
20602
  var COMPOSER_MENU_GAP_PX = 8;
20272
20603
  var COMPOSER_MENU_VIEWPORT_PADDING_PX = 8;
20604
+ var COMPOSER_MENU_TOP_SAFE_AREA_PX = DESKTOP_WINDOW_TOP_MARGIN;
20273
20605
  var COMPOSER_MENU_MIN_HEIGHT_PX = 280;
20606
+ var COMPOSER_MENU_WINDOW_FRAME_SELECTOR = "[data-workbench-window-id], [data-workspace-node-window-root='true']";
20607
+ function resolveComposerMenuWindowFrame(anchor) {
20608
+ return anchor.closest(COMPOSER_MENU_WINDOW_FRAME_SELECTOR);
20609
+ }
20274
20610
  function resolveComposerMenuPortalTarget(anchor) {
20275
- return anchor.closest('[data-slot="viewport-menu-boundary"]') ?? anchor.closest(
20276
- "[data-workbench-window-id], [data-workspace-node-window-root='true']"
20277
- ) ?? document.body;
20611
+ return anchor.closest('[data-slot="viewport-menu-boundary"]') ?? resolveComposerMenuWindowFrame(anchor) ?? document.body;
20278
20612
  }
20279
20613
  function resolveComposerMenuZIndex(anchor) {
20280
20614
  let current = anchor;
20281
20615
  while (current) {
20282
- if (current.matches(
20283
- "[data-workbench-window-id], [data-workspace-node-window-root='true']"
20284
- )) {
20616
+ if (current.matches(COMPOSER_MENU_WINDOW_FRAME_SELECTOR)) {
20285
20617
  const windowZIndex = Number.parseInt(
20286
20618
  window.getComputedStyle(current).zIndex,
20287
20619
  10
@@ -20294,6 +20626,17 @@ function resolveComposerMenuZIndex(anchor) {
20294
20626
  }
20295
20627
  return "var(--z-popover)";
20296
20628
  }
20629
+ function resolveComposerMenuTopSafeArea(anchor) {
20630
+ const windowFrame = resolveComposerMenuWindowFrame(anchor);
20631
+ if (!windowFrame) {
20632
+ return COMPOSER_MENU_TOP_SAFE_AREA_PX;
20633
+ }
20634
+ const header = windowFrame.querySelector(
20635
+ '[data-workspace-node-window-header="true"]'
20636
+ );
20637
+ const localFloor = (header ?? windowFrame).getBoundingClientRect()[header ? "bottom" : "top"];
20638
+ return Math.max(COMPOSER_MENU_TOP_SAFE_AREA_PX, localFloor);
20639
+ }
20297
20640
  function computeComposerAnchoredMenuFrame(anchor, maxHeight) {
20298
20641
  const rect = anchor.getBoundingClientRect();
20299
20642
  const viewportWidth = window.innerWidth;
@@ -20309,11 +20652,13 @@ function computeComposerAnchoredMenuFrame(anchor, maxHeight) {
20309
20652
  viewportWidth - COMPOSER_MENU_VIEWPORT_PADDING_PX - width
20310
20653
  )
20311
20654
  );
20312
- const availableAbove = rect.top - COMPOSER_MENU_GAP_PX - COMPOSER_MENU_VIEWPORT_PADDING_PX;
20313
- const height = availableAbove >= maxHeight ? maxHeight : Math.max(
20314
- COMPOSER_MENU_MIN_HEIGHT_PX,
20315
- Math.min(maxHeight, availableAbove)
20655
+ const topSafeArea = resolveComposerMenuTopSafeArea(anchor);
20656
+ const availableAbove = rect.top - COMPOSER_MENU_GAP_PX - topSafeArea;
20657
+ const minHeight = Math.max(
20658
+ 0,
20659
+ Math.min(COMPOSER_MENU_MIN_HEIGHT_PX, availableAbove)
20316
20660
  );
20661
+ const height = availableAbove >= maxHeight ? maxHeight : Math.max(minHeight, Math.min(maxHeight, availableAbove));
20317
20662
  return {
20318
20663
  bottom: Math.max(
20319
20664
  COMPOSER_MENU_VIEWPORT_PADDING_PX,
@@ -20321,9 +20666,10 @@ function computeComposerAnchoredMenuFrame(anchor, maxHeight) {
20321
20666
  ),
20322
20667
  height,
20323
20668
  left,
20669
+ minHeight,
20324
20670
  portalTarget: resolveComposerMenuPortalTarget(anchor),
20325
20671
  top: Math.max(
20326
- COMPOSER_MENU_VIEWPORT_PADDING_PX,
20672
+ topSafeArea,
20327
20673
  Math.min(
20328
20674
  rect.top - COMPOSER_MENU_GAP_PX - height,
20329
20675
  viewportHeight - COMPOSER_MENU_VIEWPORT_PADDING_PX - height
@@ -20334,7 +20680,7 @@ function computeComposerAnchoredMenuFrame(anchor, maxHeight) {
20334
20680
  };
20335
20681
  }
20336
20682
  function sameComposerAnchoredMenuFrame(left, right) {
20337
- return left !== null && left.portalTarget === right.portalTarget && left.zIndex === right.zIndex && Math.abs(left.left - right.left) < 0.5 && Math.abs(left.top - right.top) < 0.5 && Math.abs(left.bottom - right.bottom) < 0.5 && Math.abs(left.width - right.width) < 0.5 && Math.abs(left.height - right.height) < 0.5;
20683
+ return left !== null && left.portalTarget === right.portalTarget && left.zIndex === right.zIndex && Math.abs(left.left - right.left) < 0.5 && Math.abs(left.top - right.top) < 0.5 && Math.abs(left.bottom - right.bottom) < 0.5 && Math.abs(left.width - right.width) < 0.5 && Math.abs(left.height - right.height) < 0.5 && Math.abs(left.minHeight - right.minHeight) < 0.5;
20338
20684
  }
20339
20685
  function useComposerAnchoredMenuFrame({
20340
20686
  anchorRef,
@@ -20469,7 +20815,7 @@ var ComposerFloatingMenuSurface = forwardRef4(function ComposerFloatingMenuSurfa
20469
20815
  return {
20470
20816
  ...baseStyle,
20471
20817
  top: `${frame?.top ?? 0}px`,
20472
- minHeight: `${COMPOSER_MENU_MIN_HEIGHT_PX}px`,
20818
+ minHeight: `${frame?.minHeight ?? COMPOSER_MENU_MIN_HEIGHT_PX}px`,
20473
20819
  height: `${frame?.height ?? maxHeight}px`,
20474
20820
  maxHeight: `${maxHeight}px`
20475
20821
  };
@@ -20754,6 +21100,9 @@ function resolveComposerProviderIconUrl(provider) {
20754
21100
  return MANAGED_AGENT_ICON_URLS[normalizeManagedAgentProvider(provider)] ?? MANAGED_AGENT_ICON_FALLBACK_URL;
20755
21101
  }
20756
21102
  function resolveComposerProviderTargetIconUrl(target) {
21103
+ if (normalizeManagedAgentProvider(target.provider) === "cursor") {
21104
+ return cursorColorfulUrl;
21105
+ }
20757
21106
  return target.iconUrl ?? resolveComposerProviderIconUrl(target.provider);
20758
21107
  }
20759
21108
  function resolveMentionPalettePortalTarget(anchor) {
@@ -24021,15 +24370,7 @@ function AttentionGlyph() {
24021
24370
 
24022
24371
  // agent-gui/agentGuiNode/AgentGUINodeView.tsx
24023
24372
  import { createRichTextMentionHref as createRichTextMentionHref2 } from "@tutti-os/ui-rich-text/core";
24024
-
24025
- // app/renderer/assets/icons/agents/claudecode-flat-filled.svg
24026
- var claudecode_flat_filled_default = "./claudecode-flat-filled-NHO4JCVK.svg";
24027
-
24028
- // app/renderer/assets/icons/agents/codex-flat-filled.svg
24029
- var codex_flat_filled_default = "./codex-flat-filled-WYHCF5VR.svg";
24030
-
24031
- // agent-gui/agentGuiNode/AgentGUINodeView.tsx
24032
- import { Fragment as Fragment8, jsx as jsx31, jsxs as jsxs17 } from "react/jsx-runtime";
24373
+ import { Fragment as Fragment9, jsx as jsx31, jsxs as jsxs17 } from "react/jsx-runtime";
24033
24374
  var AGENT_GUI_STICK_TO_BOTTOM_THRESHOLD_PX = 24;
24034
24375
  var AGENT_GUI_TOP_HISTORY_PREFETCH_THRESHOLD_PX = 240;
24035
24376
  var AGENT_GUI_TOP_MASK_SCROLL_EPSILON_PX = 1;
@@ -24051,16 +24392,18 @@ function resolveAgentGUIHeroIconUrl(provider) {
24051
24392
  }
24052
24393
  function agentGUIProviderIconPresentation(provider, iconUrl) {
24053
24394
  const normalizedProvider = normalizeManagedAgentProvider(provider);
24395
+ const providerRailIconUrl = MANAGED_AGENT_PROVIDER_RAIL_ICON_URLS[normalizedProvider] ?? null;
24054
24396
  return {
24055
24397
  provider: normalizedProvider,
24056
- iconUrl: iconUrl?.trim() || resolveAgentGUIHeroIconUrl(normalizedProvider)
24398
+ iconUrl: (normalizedProvider === "cursor" ? providerRailIconUrl : null) || iconUrl?.trim() || resolveAgentGUIHeroIconUrl(normalizedProvider)
24057
24399
  };
24058
24400
  }
24059
24401
  function agentGUIProviderRailIconPresentation(provider, iconUrl) {
24060
24402
  const normalizedProvider = normalizeManagedAgentProvider(provider);
24403
+ const providerRailIconUrl = MANAGED_AGENT_PROVIDER_RAIL_ICON_URLS[normalizedProvider] ?? null;
24061
24404
  return {
24062
24405
  provider: normalizedProvider,
24063
- iconUrl: iconUrl?.trim() || MANAGED_AGENT_PROVIDER_RAIL_ICON_URLS[normalizedProvider] || resolveAgentGUIHeroIconUrl(normalizedProvider)
24406
+ iconUrl: (normalizedProvider === "cursor" ? providerRailIconUrl : null) || iconUrl?.trim() || providerRailIconUrl || resolveAgentGUIHeroIconUrl(normalizedProvider)
24064
24407
  };
24065
24408
  }
24066
24409
  function shouldEmphasizeEmptyHeroProvider(label) {
@@ -24294,6 +24637,7 @@ function AgentGUINodeView({
24294
24637
  slashStatusLimitsLoading = false,
24295
24638
  railConfigProvider,
24296
24639
  railSlashStatusLimits,
24640
+ onAgentConfigMenuOpen,
24297
24641
  previewMode = false,
24298
24642
  onAgentProviderLogin,
24299
24643
  actions,
@@ -24678,6 +25022,7 @@ function AgentGUINodeView({
24678
25022
  onUpdateConversationFilter: actions.updateConversationFilter,
24679
25023
  onSelectConversationFilterTarget: actions.selectConversationFilterTarget,
24680
25024
  onOpenAgentEnvSetup: openAgentEnvSetup,
25025
+ onAgentConfigMenuOpen,
24681
25026
  onRetryOpenclawGateway: retryOpenclawGateway,
24682
25027
  onSelectConversation: selectConversation,
24683
25028
  onToggleConversationPinned: toggleConversationPinned,
@@ -24699,6 +25044,7 @@ function AgentGUINodeView({
24699
25044
  conversationRailCollapsed,
24700
25045
  createConversationDisabled,
24701
25046
  labels,
25047
+ onAgentConfigMenuOpen,
24702
25048
  openAgentEnvSetup,
24703
25049
  openConversationWindow,
24704
25050
  openProjectFiles,
@@ -24782,6 +25128,7 @@ function AgentGUINodeView({
24782
25128
  selectedProviderTarget: viewModel.selectedProviderTarget,
24783
25129
  providerTargets: viewModel.providerTargets,
24784
25130
  providerTargetsLoading: viewModel.providerTargetsLoading,
25131
+ comingSoonProviders: viewModel.comingSoonProviders,
24785
25132
  onSelectConversationFilterTarget: actions.selectConversationFilterTarget,
24786
25133
  onUpdateConversationFilter: actions.updateConversationFilter
24787
25134
  }
@@ -26412,6 +26759,17 @@ function AgentGUIAllProviderGridIcon({
26412
26759
  }
26413
26760
  );
26414
26761
  }
26762
+ function AgentGUIUnifiedProviderIcon() {
26763
+ return /* @__PURE__ */ jsx31("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.providerRailAvatar, children: /* @__PURE__ */ jsx31(
26764
+ "img",
26765
+ {
26766
+ alt: "",
26767
+ className: AgentGUINode_styles_default.providerRailAvatarImage,
26768
+ draggable: false,
26769
+ src: agentColorfulUrl
26770
+ }
26771
+ ) });
26772
+ }
26415
26773
  function AgentGUILaunchpadIconGrid({
26416
26774
  activeProvider,
26417
26775
  icons
@@ -26455,7 +26813,7 @@ function EmptyHeroTitle({
26455
26813
  }) {
26456
26814
  const providerStart = providerLabel ? label.indexOf(providerLabel) : -1;
26457
26815
  if (!shouldEmphasizeEmptyHeroProvider(label) || providerStart < 0) {
26458
- return /* @__PURE__ */ jsx31(Fragment8, { children: label });
26816
+ return /* @__PURE__ */ jsx31(Fragment9, { children: label });
26459
26817
  }
26460
26818
  const providerEnd = providerStart + providerLabel.length;
26461
26819
  const selectedProviderTargetId = selectedProviderTarget?.targetId ?? `local:${selectedProviderTarget?.provider ?? ""}`;
@@ -26464,7 +26822,7 @@ function EmptyHeroTitle({
26464
26822
  );
26465
26823
  const canSwitchProvider = enabledProviderTargets.length > 1 && selectedProviderTarget && onProviderSelect;
26466
26824
  const providerName = label.slice(providerStart, providerEnd);
26467
- return /* @__PURE__ */ jsxs17(Fragment8, { children: [
26825
+ return /* @__PURE__ */ jsxs17(Fragment9, { children: [
26468
26826
  label.slice(0, providerStart),
26469
26827
  canSwitchProvider ? /* @__PURE__ */ jsxs17(
26470
26828
  Select3,
@@ -26510,7 +26868,7 @@ function EmptyHeroTitle({
26510
26868
  alt: "",
26511
26869
  "aria-hidden": "true",
26512
26870
  className: "size-4 shrink-0 rounded-[4px]",
26513
- src: agentGUIProviderIconPresentation(
26871
+ src: agentGUIProviderRailIconPresentation(
26514
26872
  target.provider,
26515
26873
  target.iconUrl
26516
26874
  ).iconUrl
@@ -26682,7 +27040,7 @@ function syncAgentGUIConversationRailStore(store, next) {
26682
27040
  Object.assign(store, next);
26683
27041
  }
26684
27042
  function agentGUIConversationRailStoreSnapshotsEqual(current, next) {
26685
- return current.activeConversationId === next.activeConversationId && current.pendingDeleteConversationId === next.pendingDeleteConversationId && current.isLoadingConversations === next.isLoadingConversations && current.isDeletingConversation === next.isDeletingConversation && current.isDeletingProjectConversations === next.isDeletingProjectConversations && current.labels === next.labels && current.workspaceUserProjectI18n === next.workspaceUserProjectI18n && current.uiLanguage === next.uiLanguage && current.previewMode === next.previewMode && current.createConversationDisabled === next.createConversationDisabled && current.openclawGateway === next.openclawGateway && current.isCollapsed === next.isCollapsed && current.railConfigProvider === next.railConfigProvider && current.slashStatusLimits === next.slashStatusLimits && current.selectedProviderTarget === next.selectedProviderTarget && current.providerTargets === next.providerTargets && current.providerTargetsLoading === next.providerTargetsLoading && current.conversationFilter === next.conversationFilter && current.sectionAgentTargetFallbackId === next.sectionAgentTargetFallbackId && current.onUpdateConversationFilter === next.onUpdateConversationFilter && current.onSelectConversationFilterTarget === next.onSelectConversationFilterTarget && current.onCreateConversation === next.onCreateConversation && current.onOpenAgentEnvSetup === next.onOpenAgentEnvSetup && current.onRetryOpenclawGateway === next.onRetryOpenclawGateway && current.onSelectConversation === next.onSelectConversation && current.onToggleConversationPinned === next.onToggleConversationPinned && current.onOpenProjectFiles === next.onOpenProjectFiles && current.onOpenConversationWindow === next.onOpenConversationWindow && current.selectProjectDirectory === next.selectProjectDirectory && current.onRemoveProject === next.onRemoveProject && current.onConfirmDeleteProjectConversations === next.onConfirmDeleteProjectConversations && current.onRequestDeleteConversation === next.onRequestDeleteConversation && current.onCancelDeleteConversation === next.onCancelDeleteConversation && current.onConfirmDeleteConversation === next.onConfirmDeleteConversation;
27043
+ return current.activeConversationId === next.activeConversationId && current.pendingDeleteConversationId === next.pendingDeleteConversationId && current.isLoadingConversations === next.isLoadingConversations && current.isDeletingConversation === next.isDeletingConversation && current.isDeletingProjectConversations === next.isDeletingProjectConversations && current.labels === next.labels && current.workspaceUserProjectI18n === next.workspaceUserProjectI18n && current.uiLanguage === next.uiLanguage && current.previewMode === next.previewMode && current.createConversationDisabled === next.createConversationDisabled && current.openclawGateway === next.openclawGateway && current.isCollapsed === next.isCollapsed && current.railConfigProvider === next.railConfigProvider && current.slashStatusLimits === next.slashStatusLimits && current.selectedProviderTarget === next.selectedProviderTarget && current.providerTargets === next.providerTargets && current.providerTargetsLoading === next.providerTargetsLoading && current.conversationFilter === next.conversationFilter && current.sectionAgentTargetFallbackId === next.sectionAgentTargetFallbackId && current.onUpdateConversationFilter === next.onUpdateConversationFilter && current.onSelectConversationFilterTarget === next.onSelectConversationFilterTarget && current.onCreateConversation === next.onCreateConversation && current.onOpenAgentEnvSetup === next.onOpenAgentEnvSetup && current.onAgentConfigMenuOpen === next.onAgentConfigMenuOpen && current.onRetryOpenclawGateway === next.onRetryOpenclawGateway && current.onSelectConversation === next.onSelectConversation && current.onToggleConversationPinned === next.onToggleConversationPinned && current.onOpenProjectFiles === next.onOpenProjectFiles && current.onOpenConversationWindow === next.onOpenConversationWindow && current.selectProjectDirectory === next.selectProjectDirectory && current.onRemoveProject === next.onRemoveProject && current.onConfirmDeleteProjectConversations === next.onConfirmDeleteProjectConversations && current.onRequestDeleteConversation === next.onRequestDeleteConversation && current.onCancelDeleteConversation === next.onCancelDeleteConversation && current.onConfirmDeleteConversation === next.onConfirmDeleteConversation;
26686
27044
  }
26687
27045
  var AgentGUIConversationRailStorePane = memo(
26688
27046
  function AgentGUIConversationRailStorePane2({
@@ -26806,17 +27164,19 @@ function stabilizeConversationSectionItems(previous, next) {
26806
27164
  });
26807
27165
  return changed ? stable : previous;
26808
27166
  }
26809
- function updateConversationSectionsFromSummaries(previous, conversations) {
27167
+ function updateConversationSectionsFromSummaries(previous, conversations, options) {
26810
27168
  if (!previous || conversations.length === 0) {
26811
27169
  return previous;
26812
27170
  }
26813
27171
  const summariesById = new Map(
26814
27172
  conversations.map((conversation) => [conversation.id, conversation])
26815
27173
  );
27174
+ const seenIds = /* @__PURE__ */ new Set();
26816
27175
  let changed = false;
26817
27176
  const nextSections = previous.map((section) => {
26818
27177
  let sectionChanged = false;
26819
27178
  const items = section.items.map((item) => {
27179
+ seenIds.add(item.id);
26820
27180
  const summary = summariesById.get(item.id);
26821
27181
  if (!summary) {
26822
27182
  return item;
@@ -26840,7 +27200,35 @@ function updateConversationSectionsFromSummaries(previous, conversations) {
26840
27200
  items
26841
27201
  };
26842
27202
  });
26843
- return changed ? nextSections : previous;
27203
+ const newConversations = conversations.filter(
27204
+ (conversation) => !seenIds.has(conversation.id) && (conversation.pinnedAtUnixMs ?? 0) <= 0
27205
+ );
27206
+ if (newConversations.length === 0) {
27207
+ return changed ? nextSections : previous;
27208
+ }
27209
+ const sectionsWithInsertions = [...nextSections];
27210
+ for (const conversation of newConversations) {
27211
+ const targetSectionId = conversation.project ? `project:${normalizeConversationProjectPath(conversation.project.path)}` : "conversations";
27212
+ const targetIndex = sectionsWithInsertions.findIndex(
27213
+ (section) => section.id === targetSectionId
27214
+ );
27215
+ const target = targetIndex !== -1 ? sectionsWithInsertions[targetIndex] : void 0;
27216
+ if (targetIndex !== -1 && target) {
27217
+ sectionsWithInsertions[targetIndex] = {
27218
+ ...target,
27219
+ items: [conversation, ...target.items]
27220
+ };
27221
+ continue;
27222
+ }
27223
+ sectionsWithInsertions.push({
27224
+ id: targetSectionId,
27225
+ kind: conversation.project ? "project" : "conversations",
27226
+ label: conversation.project?.label ?? options.sectionConversationsLabel,
27227
+ project: conversation.project ?? null,
27228
+ items: [conversation]
27229
+ });
27230
+ }
27231
+ return sectionsWithInsertions;
26844
27232
  }
26845
27233
  function projectRuntimeSectionsToConversationSections(input) {
26846
27234
  const pinned = [];
@@ -26909,6 +27297,7 @@ function conversationProjectsRenderEqual2(left, right) {
26909
27297
  var agentGUIProviderRailOrder = [
26910
27298
  "codex",
26911
27299
  "claude-code",
27300
+ "cursor",
26912
27301
  "nexight",
26913
27302
  "hermes",
26914
27303
  "openclaw",
@@ -26917,6 +27306,7 @@ var agentGUIProviderRailOrder = [
26917
27306
  var agentGUIProviderRailDefaultProviders = [
26918
27307
  "codex",
26919
27308
  "claude-code",
27309
+ "cursor",
26920
27310
  "nexight",
26921
27311
  "hermes",
26922
27312
  "openclaw"
@@ -26934,19 +27324,12 @@ function agentGUILaunchpadIconPresentations() {
26934
27324
  return [
26935
27325
  agentGUIProviderRailIconPresentation("codex"),
26936
27326
  agentGUIProviderRailIconPresentation("claude-code"),
26937
- agentGUIProviderRailIconPresentation("tutti"),
26938
- agentGUIProviderRailIconPresentation("hermes")
27327
+ agentGUIProviderRailIconPresentation("cursor"),
27328
+ agentGUIProviderRailIconPresentation("tutti")
26939
27329
  ];
26940
27330
  }
26941
27331
  function agentGUIConversationProviderIconUrl(provider) {
26942
- switch (normalizeManagedAgentProvider(provider)) {
26943
- case "claude-code":
26944
- return claudecode_flat_filled_default;
26945
- case "codex":
26946
- return codex_flat_filled_default;
26947
- default:
26948
- return null;
26949
- }
27332
+ return resolveAgentGuiSessionProviderIconUrl(provider);
26950
27333
  }
26951
27334
  function agentGUIProviderRailLabel(provider, targetLabel, labels) {
26952
27335
  if (provider === "nexight" && targetLabel === "Tutti Agent") {
@@ -26966,10 +27349,11 @@ function agentGUIProviderRailLabel(provider, targetLabel, labels) {
26966
27349
  function agentGUIProviderTargetMatchesConversationFilter(target, filter) {
26967
27350
  return filter.kind === "agentTarget" && (target.agentTargetId?.trim() ?? "") === filter.agentTargetId;
26968
27351
  }
26969
- function agentGUIProviderRailTargets(providerTargets, providerTargetsLoading) {
27352
+ function agentGUIProviderRailTargets(providerTargets, providerTargetsLoading, comingSoonProviders) {
26970
27353
  if (providerTargetsLoading) {
26971
27354
  return [];
26972
27355
  }
27356
+ const comingSoon = new Set(comingSoonProviders);
26973
27357
  const source = providerTargets.length > 0 && !agentGUIProviderRailTargetsAreFullLocalFallback(providerTargets) ? providerTargets : [];
26974
27358
  const seenProviders = new Set(source.map((target) => target.provider));
26975
27359
  const missingDefaultProviders = agentGUIProviderRailDefaultProviders.filter(
@@ -26981,7 +27365,7 @@ function agentGUIProviderRailTargets(providerTargets, providerTargetsLoading) {
26981
27365
  return [
26982
27366
  ...source,
26983
27367
  ...missingDefaultProviders.map(
26984
- (provider) => agentGUIProviderRailDisabledProviders.has(provider) ? createDisabledPlaceholderAgentGUIProviderTarget(provider) : createLocalAgentGUIProviderTarget(provider)
27368
+ (provider) => agentGUIProviderRailDisabledProviders.has(provider) || comingSoon.has(provider) ? createDisabledPlaceholderAgentGUIProviderTarget(provider) : createLocalAgentGUIProviderTarget(provider)
26985
27369
  )
26986
27370
  ];
26987
27371
  }
@@ -27001,13 +27385,18 @@ var AgentGUIProviderRail = memo(function AgentGUIProviderRail2({
27001
27385
  selectedProviderTarget,
27002
27386
  providerTargets,
27003
27387
  providerTargetsLoading,
27388
+ comingSoonProviders,
27004
27389
  onSelectConversationFilterTarget,
27005
27390
  onUpdateConversationFilter
27006
27391
  }) {
27007
27392
  "use memo";
27008
27393
  const railProviderTargets = useMemo10(
27009
- () => agentGUIProviderRailTargets(providerTargets, providerTargetsLoading),
27010
- [providerTargets, providerTargetsLoading]
27394
+ () => agentGUIProviderRailTargets(
27395
+ providerTargets,
27396
+ providerTargetsLoading,
27397
+ comingSoonProviders
27398
+ ),
27399
+ [comingSoonProviders, providerTargets, providerTargetsLoading]
27011
27400
  );
27012
27401
  const providerTiles = useMemo10(() => {
27013
27402
  const targets = [...railProviderTargets];
@@ -27028,10 +27417,6 @@ var AgentGUIProviderRail = memo(function AgentGUIProviderRail2({
27028
27417
  ) ?? 0);
27029
27418
  });
27030
27419
  }, [railProviderTargets]);
27031
- const launchpadIconPresentations = useMemo10(
27032
- () => agentGUILaunchpadIconPresentations(),
27033
- []
27034
- );
27035
27420
  const selectedProviderTargetIsPlaceholder = selectedProviderTarget?.disabled === true;
27036
27421
  const allTileSelected = conversationFilter.kind === "all" && !selectedProviderTargetIsPlaceholder;
27037
27422
  const selectAllProviders = useCallback10(() => {
@@ -27068,7 +27453,7 @@ var AgentGUIProviderRail = memo(function AgentGUIProviderRail2({
27068
27453
  "aria-label": labels.providerSwitchLabel,
27069
27454
  "aria-busy": providerTargetsLoading,
27070
27455
  children: [
27071
- /* @__PURE__ */ jsx31(
27456
+ /* @__PURE__ */ jsxs17(
27072
27457
  "button",
27073
27458
  {
27074
27459
  type: "button",
@@ -27079,7 +27464,10 @@ var AgentGUIProviderRail = memo(function AgentGUIProviderRail2({
27079
27464
  "data-selected": allTileSelected ? "true" : "false",
27080
27465
  disabled: previewMode,
27081
27466
  onClick: selectAllProviders,
27082
- children: /* @__PURE__ */ jsx31(AgentGUIAllProviderGridIcon, { icons: launchpadIconPresentations })
27467
+ children: [
27468
+ /* @__PURE__ */ jsx31(AgentGUIUnifiedProviderIcon, {}),
27469
+ /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.providerRailTileLabel, children: labels.conversationFilterAll })
27470
+ ]
27083
27471
  }
27084
27472
  ),
27085
27473
  /* @__PURE__ */ jsx31("span", { "aria-hidden": "true", className: AgentGUINode_styles_default.providerRailSeparator }),
@@ -27261,9 +27649,11 @@ function useAgentGUIConversationRail({
27261
27649
  return;
27262
27650
  }
27263
27651
  setRuntimeRailSections(
27264
- (current) => updateConversationSectionsFromSummaries(current, conversations)
27652
+ (current) => updateConversationSectionsFromSummaries(current, conversations, {
27653
+ sectionConversationsLabel: labels.sectionConversations
27654
+ })
27265
27655
  );
27266
- }, [conversations, runtimeSectionsEnabled]);
27656
+ }, [conversations, labels.sectionConversations, runtimeSectionsEnabled]);
27267
27657
  const loadMoreSectionConversations = useCallback10(
27268
27658
  (section) => {
27269
27659
  if (!runtimeListSessionSectionPage || previewMode || conversationQuery.trim()) {
@@ -27399,6 +27789,7 @@ var AgentGUIConversationRailPane = memo(
27399
27789
  sectionAgentTargetFallbackId,
27400
27790
  onCreateConversation,
27401
27791
  onOpenAgentEnvSetup,
27792
+ onAgentConfigMenuOpen,
27402
27793
  onRetryOpenclawGateway,
27403
27794
  onSelectConversation,
27404
27795
  onToggleConversationPinned,
@@ -27637,7 +28028,7 @@ var AgentGUIConversationRailPane = memo(
27637
28028
  const projectConversationCount = normalizedProjectPath ? projectConversationCountsByPath.get(normalizedProjectPath) ?? 0 : 0;
27638
28029
  const sectionPageState = sectionPageStates.get(section.id);
27639
28030
  const sectionHasMore = !conversationQuery.trim() && section.kind !== "pinned" && sectionPageState?.hasMore === true;
27640
- return /* @__PURE__ */ jsxs17(Fragment7, { children: [
28031
+ return /* @__PURE__ */ jsxs17(Fragment8, { children: [
27641
28032
  showProjectRailHeader ? /* @__PURE__ */ jsx31(
27642
28033
  AgentGUIProjectRailHeader,
27643
28034
  {
@@ -27682,69 +28073,98 @@ var AgentGUIConversationRailPane = memo(
27682
28073
  })
27683
28074
  }
27684
28075
  ),
27685
- railConfigProvider ? /* @__PURE__ */ jsx31("div", { className: "shrink-0 px-2 py-1.5", children: /* @__PURE__ */ jsxs17(Popover, { children: [
27686
- /* @__PURE__ */ jsx31(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs17(
27687
- Button,
27688
- {
27689
- type: "button",
27690
- variant: "ghost",
27691
- className: "flex w-full items-center justify-start gap-2 text-[13px] text-[var(--text-secondary)] hover:text-[var(--text-primary)]",
27692
- title: labels.agentConfig,
27693
- disabled: previewMode,
27694
- children: [
27695
- /* @__PURE__ */ jsx31(
27696
- EnvironmentLinedIcon,
27697
- {
27698
- "aria-hidden": "true",
27699
- width: 16,
27700
- height: 16
27701
- }
27702
- ),
27703
- /* @__PURE__ */ jsx31("span", { children: labels.agentConfig })
27704
- ]
27705
- }
27706
- ) }),
27707
- /* @__PURE__ */ jsx31(
27708
- PopoverContent,
27709
- {
27710
- side: "top",
27711
- align: "start",
27712
- className: "w-[300px] max-w-[calc(100vw-32px)] gap-3 text-xs",
27713
- "data-testid": "agent-gui-config-menu",
27714
- children: /* @__PURE__ */ jsxs17("div", { className: "flex min-w-0 flex-col gap-3", children: [
27715
- slashStatusLimits.length > 0 ? /* @__PURE__ */ jsxs17(Fragment8, { children: [
27716
- /* @__PURE__ */ jsxs17("div", { className: "flex min-w-0 flex-col gap-2", children: [
27717
- /* @__PURE__ */ jsx31("span", { className: "text-[13px] font-semibold leading-4", children: labels.slashStatusLimits }),
27718
- slashStatusLimits.map((limit) => /* @__PURE__ */ jsx31(
27719
- AgentUsageMeter,
28076
+ railConfigProvider ? /* @__PURE__ */ jsx31("div", { className: "shrink-0 px-2 py-1.5", children: slashStatusLimits.length > 0 ? /* @__PURE__ */ jsxs17(
28077
+ Popover,
28078
+ {
28079
+ onOpenChange: (open) => {
28080
+ if (open) {
28081
+ onAgentConfigMenuOpen?.();
28082
+ }
28083
+ },
28084
+ children: [
28085
+ /* @__PURE__ */ jsx31(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs17(
28086
+ Button,
28087
+ {
28088
+ type: "button",
28089
+ variant: "ghost",
28090
+ className: "flex w-full items-center justify-start gap-2 text-[13px] text-[var(--text-secondary)] hover:text-[var(--text-primary)]",
28091
+ title: labels.agentConfig,
28092
+ disabled: previewMode,
28093
+ children: [
28094
+ /* @__PURE__ */ jsx31(
28095
+ EnvironmentLinedIcon,
27720
28096
  {
27721
- label: limit.label,
27722
- value: `${limit.value}${limit.reset ? ` (${limit.reset})` : ""}`,
27723
- percent: typeof limit.percentRemaining === "number" && Number.isFinite(limit.percentRemaining) ? limit.percentRemaining : null
27724
- },
27725
- limit.id
27726
- ))
27727
- ] }),
27728
- /* @__PURE__ */ jsx31("span", { className: "h-px bg-[var(--border-1)]" })
27729
- ] }) : null,
27730
- /* @__PURE__ */ jsxs17(
27731
- "button",
27732
- {
27733
- type: "button",
27734
- "data-testid": "agent-gui-config-env-setup",
27735
- className: "nodrag -mx-1 flex w-[calc(100%+0.5rem)] items-center gap-2 rounded-[6px] px-2 py-1 text-[13px] text-[var(--text-primary)] transition-colors hover:bg-[var(--transparency-hover)] hover:text-[var(--text-primary)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--border-focus)] disabled:text-[var(--text-tertiary)] [-webkit-app-region:no-drag]",
27736
- disabled: previewMode,
27737
- onClick: () => onOpenAgentEnvSetup(),
27738
- children: [
27739
- /* @__PURE__ */ jsx31(Wrench, { "aria-hidden": "true", size: 16, strokeWidth: 1.8 }),
27740
- /* @__PURE__ */ jsx31("span", { children: labels.agentEnvSetup })
27741
- ]
27742
- }
27743
- )
27744
- ] })
27745
- }
27746
- )
27747
- ] }) }) : null,
28097
+ "aria-hidden": "true",
28098
+ width: 16,
28099
+ height: 16
28100
+ }
28101
+ ),
28102
+ /* @__PURE__ */ jsx31("span", { children: labels.agentConfig })
28103
+ ]
28104
+ }
28105
+ ) }),
28106
+ /* @__PURE__ */ jsx31(
28107
+ PopoverContent,
28108
+ {
28109
+ side: "top",
28110
+ align: "start",
28111
+ className: "w-[300px] max-w-[calc(100vw-32px)] gap-3 p-1 text-xs",
28112
+ "data-testid": "agent-gui-config-menu",
28113
+ children: /* @__PURE__ */ jsxs17("div", { className: "flex min-w-0 flex-col gap-3", children: [
28114
+ /* @__PURE__ */ jsxs17("div", { className: "flex min-w-0 flex-col gap-2 p-2", children: [
28115
+ /* @__PURE__ */ jsx31("span", { className: "text-[13px] font-semibold leading-4", children: labels.slashStatusLimits }),
28116
+ slashStatusLimits.map((limit) => /* @__PURE__ */ jsx31(
28117
+ AgentUsageMeter,
28118
+ {
28119
+ label: limit.label,
28120
+ value: `${limit.value}${limit.reset ? ` (${limit.reset})` : ""}`,
28121
+ percent: typeof limit.percentRemaining === "number" && Number.isFinite(limit.percentRemaining) ? limit.percentRemaining : null
28122
+ },
28123
+ limit.id
28124
+ ))
28125
+ ] }),
28126
+ /* @__PURE__ */ jsx31("div", { className: "px-2", children: /* @__PURE__ */ jsx31("span", { className: "block h-px bg-[var(--border-1)]" }) }),
28127
+ /* @__PURE__ */ jsxs17(
28128
+ "button",
28129
+ {
28130
+ type: "button",
28131
+ "data-testid": "agent-gui-config-env-setup",
28132
+ className: "nodrag flex h-7 w-full items-center gap-2 rounded-[6px] px-2 text-[13px] text-[var(--text-primary)] transition-colors hover:bg-[var(--transparency-hover)] hover:text-[var(--text-primary)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--border-focus)] disabled:text-[var(--text-tertiary)] [-webkit-app-region:no-drag]",
28133
+ disabled: previewMode,
28134
+ onClick: () => onOpenAgentEnvSetup(),
28135
+ children: [
28136
+ /* @__PURE__ */ jsx31(Wrench, { "aria-hidden": "true", size: 16, strokeWidth: 1.8 }),
28137
+ /* @__PURE__ */ jsx31("span", { children: labels.agentEnvSetup })
28138
+ ]
28139
+ }
28140
+ )
28141
+ ] })
28142
+ }
28143
+ )
28144
+ ]
28145
+ }
28146
+ ) : /* @__PURE__ */ jsxs17(
28147
+ Button,
28148
+ {
28149
+ type: "button",
28150
+ variant: "ghost",
28151
+ className: "flex w-full items-center justify-start gap-2 text-[13px] text-[var(--text-secondary)] hover:text-[var(--text-primary)]",
28152
+ title: labels.agentEnvSetup,
28153
+ disabled: previewMode,
28154
+ onClick: () => onOpenAgentEnvSetup(),
28155
+ children: [
28156
+ /* @__PURE__ */ jsx31(
28157
+ EnvironmentLinedIcon,
28158
+ {
28159
+ "aria-hidden": "true",
28160
+ width: 16,
28161
+ height: 16
28162
+ }
28163
+ ),
28164
+ /* @__PURE__ */ jsx31("span", { children: labels.agentEnvSetup })
28165
+ ]
28166
+ }
28167
+ ) }) : null,
27748
28168
  /* @__PURE__ */ jsx31(
27749
28169
  ConfirmationDialog,
27750
28170
  {
@@ -27892,12 +28312,18 @@ var AgentGUIConversationRailSection = memo(
27892
28312
  }
27893
28313
  ),
27894
28314
  /* @__PURE__ */ jsxs17("span", { className: AgentGUINode_styles_default.conversationSectionLabel, children: [
27895
- /* @__PURE__ */ jsx31(
28315
+ isSectionCollapsed ? /* @__PURE__ */ jsx31(
27896
28316
  FolderIcon2,
27897
28317
  {
27898
28318
  "aria-hidden": "true",
27899
28319
  className: AgentGUINode_styles_default.conversationSectionLabelIcon
27900
28320
  }
28321
+ ) : /* @__PURE__ */ jsx31(
28322
+ FolderOpenLinedIcon,
28323
+ {
28324
+ "aria-hidden": "true",
28325
+ className: AgentGUINode_styles_default.conversationSectionLabelIcon
28326
+ }
27901
28327
  ),
27902
28328
  /* @__PURE__ */ jsx31("span", { children: section.label })
27903
28329
  ] })
@@ -28261,7 +28687,7 @@ var AgentGUIConversationRailItem = memo(
28261
28687
  },
28262
28688
  children: /* @__PURE__ */ jsx31("span", { className: AgentGUINode_styles_default.conversationDeleteConfirmText, children: labels.deleteSessionConfirm })
28263
28689
  }
28264
- ) : /* @__PURE__ */ jsxs17(Fragment8, { children: [
28690
+ ) : /* @__PURE__ */ jsxs17(Fragment9, { children: [
28265
28691
  onOpenConversationWindow ? /* @__PURE__ */ jsx31(
28266
28692
  BareIconButton,
28267
28693
  {
@@ -28422,7 +28848,7 @@ var AgentGUIConversationTimelinePane = memo(
28422
28848
  labels
28423
28849
  }) {
28424
28850
  "use memo";
28425
- return /* @__PURE__ */ jsxs17(Fragment8, { children: [
28851
+ return /* @__PURE__ */ jsxs17(Fragment9, { children: [
28426
28852
  isLoadingOlderMessages && !isLoading ? /* @__PURE__ */ jsx31(
28427
28853
  "div",
28428
28854
  {
@@ -28605,12 +29031,10 @@ function appendDockProbeUsageLines(probe, lines, isLoadingUsage, t) {
28605
29031
  }
28606
29032
  const quotas = probe.usage?.quotas ?? [];
28607
29033
  if (quotas.length === 0) {
28608
- if (probe.usage) {
28609
- lines.push({
28610
- label: t("agentHost.workspaceAgentProbeDetailQuota"),
28611
- primary: t("agentHost.workspaceAgentProbeUsageUnsupported")
28612
- });
28613
- }
29034
+ lines.push({
29035
+ label: t("agentHost.workspaceAgentProbeDetailQuota"),
29036
+ primary: t("agentHost.workspaceAgentProbeUsageUnsupported")
29037
+ });
28614
29038
  return;
28615
29039
  }
28616
29040
  const rows = buildCompactDisplayQuotas(quotas, t);
@@ -28645,7 +29069,7 @@ import {
28645
29069
  useState as useState13
28646
29070
  } from "react";
28647
29071
  import { createPortal as createPortal4 } from "react-dom";
28648
- import { Fragment as Fragment9, jsx as jsx32, jsxs as jsxs18 } from "react/jsx-runtime";
29072
+ import { Fragment as Fragment10, jsx as jsx32, jsxs as jsxs18 } from "react/jsx-runtime";
28649
29073
  var POPOVER_MIN_VIEWPORT_INSET_PX = 16;
28650
29074
  var POPOVER_DEFAULT_WIDTH_PX = 260;
28651
29075
  function dockAgentProbeLineKey(line) {
@@ -28655,9 +29079,9 @@ function renderDockAgentProbeLine(line) {
28655
29079
  if (typeof line === "string") {
28656
29080
  return line;
28657
29081
  }
28658
- return /* @__PURE__ */ jsxs18(Fragment9, { children: [
29082
+ return /* @__PURE__ */ jsxs18(Fragment10, { children: [
28659
29083
  line.primary,
28660
- line.secondary ? /* @__PURE__ */ jsxs18(Fragment9, { children: [
29084
+ line.secondary ? /* @__PURE__ */ jsxs18(Fragment10, { children: [
28661
29085
  " ",
28662
29086
  /* @__PURE__ */ jsx32("span", { className: "desktop-dock-popup__agent-status-secondary", children: line.secondary })
28663
29087
  ] }) : null
@@ -28825,6 +29249,16 @@ var AGENT_HOST_MANAGED_TOOLCHAIN_AGENTS = [
28825
29249
  runtimeManaged: true,
28826
29250
  helperProvider: "codex"
28827
29251
  },
29252
+ {
29253
+ id: "cursor",
29254
+ // i18n-check-ignore: Provider brand name.
29255
+ label: "Cursor",
29256
+ toolIds: ["cursor-cli"],
29257
+ agentIds: ["cursor"],
29258
+ runtimeManaged: true,
29259
+ helperProvider: "cursor",
29260
+ aliases: ["cursor cli", "cursor agent", "cursor-agent"]
29261
+ },
28828
29262
  {
28829
29263
  id: "tutti",
28830
29264
  // i18n-check-ignore: Provider brand name.
@@ -29131,7 +29565,7 @@ function agentGuiStateEquals(left, right) {
29131
29565
  return left === right || left.provider === right.provider && (left.agentTargetId ?? null) === (right.agentTargetId ?? null) && (left.providerTargetId ?? null) === (right.providerTargetId ?? null) && agentGUIProviderTargetRefsEqual(
29132
29566
  left.providerTargetRef,
29133
29567
  right.providerTargetRef
29134
- ) && left.lastActiveAgentSessionId === right.lastActiveAgentSessionId && left.conversationRailWidthPx === right.conversationRailWidthPx && left.conversationRailCollapsed === right.conversationRailCollapsed && (left.composerOverrides?.model ?? null) === (right.composerOverrides?.model ?? null) && (left.composerOverrides?.reasoningEffort ?? null) === (right.composerOverrides?.reasoningEffort ?? null) && (left.composerOverrides?.planMode ?? null) === (right.composerOverrides?.planMode ?? null) && (left.composerOverrides?.permissionModeId ?? null) === (right.composerOverrides?.permissionModeId ?? null) && composerOverridesByProviderEqual(
29568
+ ) && left.lastActiveAgentSessionId === right.lastActiveAgentSessionId && (left.lastActiveConversationTitle ?? null) === (right.lastActiveConversationTitle ?? null) && left.conversationRailWidthPx === right.conversationRailWidthPx && left.conversationRailCollapsed === right.conversationRailCollapsed && (left.composerOverrides?.model ?? null) === (right.composerOverrides?.model ?? null) && (left.composerOverrides?.reasoningEffort ?? null) === (right.composerOverrides?.reasoningEffort ?? null) && (left.composerOverrides?.planMode ?? null) === (right.composerOverrides?.planMode ?? null) && (left.composerOverrides?.permissionModeId ?? null) === (right.composerOverrides?.permissionModeId ?? null) && composerOverridesByProviderEqual(
29135
29569
  left.composerOverridesByProvider,
29136
29570
  right.composerOverridesByProvider
29137
29571
  ) && composerOverridesByAgentTargetIdEqual(
@@ -29169,7 +29603,7 @@ function composerOverridesByAgentTargetIdEqual(left, right) {
29169
29603
  return true;
29170
29604
  }
29171
29605
  function areAgentGUINodePropsEqual(previous, next) {
29172
- return previous.nodeId === next.nodeId && previous.workspaceId === next.workspaceId && previous.currentUserId === next.currentUserId && previous.workspacePath === next.workspacePath && previous.workspaceFileReferenceAdapter === next.workspaceFileReferenceAdapter && previous.resolveDroppedFileReferences === next.resolveDroppedFileReferences && previous.selectProjectDirectory === next.selectProjectDirectory && previous.referenceSourceAggregator === next.referenceSourceAggregator && previous.resolveWorkspaceReferenceEntryIconUrl === next.resolveWorkspaceReferenceEntryIconUrl && previous.resolveMentionReferenceTarget === next.resolveMentionReferenceTarget && previous.resolveWorkspaceReferenceInitialTarget === next.resolveWorkspaceReferenceInitialTarget && previous.onWorkspaceFileReferencesAdded === next.onWorkspaceFileReferencesAdded && previous.agentSettings.avoidGroupingEdits === next.agentSettings.avoidGroupingEdits && previous.title === next.title && agentGuiStateEquals(previous.state, next.state) && previous.position.x === next.position.x && previous.position.y === next.position.y && previous.width === next.width && previous.height === next.height && previous.desktopSize.width === next.desktopSize.width && previous.desktopSize.height === next.desktopSize.height && previous.onLinkAction === next.onLinkAction && previous.onHandoffConversation === next.onHandoffConversation && previous.onCapabilitySettingsRequest === next.onCapabilitySettingsRequest && previous.onAgentProviderLogin === next.onAgentProviderLogin && previous.providerTargets === next.providerTargets && previous.providerTargetsLoading === next.providerTargetsLoading && previous.providerReadinessGates === next.providerReadinessGates && previous.defaultProviderTargetId === next.defaultProviderTargetId && previous.onClose === next.onClose && previous.onResize === next.onResize && previous.onUpdateNode === next.onUpdateNode && previous.onRememberComposerDefaults === next.onRememberComposerDefaults && previous.onOpenConversationWindow === next.onOpenConversationWindow && previous.isMaximized === next.isMaximized && previous.isMuted === next.isMuted && previous.onMinimize === next.onMinimize && previous.onToggleMaximize === next.onToggleMaximize && previous.onShowMessage === next.onShowMessage && previous.workspaceAgentProbes === next.workspaceAgentProbes && previous.onAgentProbeDemandChange === next.onAgentProbeDemandChange && previous.onAgentProbeRefreshRequest === next.onAgentProbeRefreshRequest && previous.managedAgentsState === next.managedAgentsState && previous.contextMentionProviders === next.contextMentionProviders && previous.workspaceAppIcons === next.workspaceAppIcons && previous.embedded === next.embedded && previous.previewMode === next.previewMode && previous.isActive === next.isActive && previous.composerFocusRequestSequence === next.composerFocusRequestSequence && previous.newConversationRequestSequence === next.newConversationRequestSequence && previous.openSessionRequest === next.openSessionRequest && previous.prefillPromptRequest === next.prefillPromptRequest;
29606
+ return previous.nodeId === next.nodeId && previous.workspaceId === next.workspaceId && previous.currentUserId === next.currentUserId && previous.workspacePath === next.workspacePath && previous.workspaceFileReferenceAdapter === next.workspaceFileReferenceAdapter && previous.resolveDroppedFileReferences === next.resolveDroppedFileReferences && previous.selectProjectDirectory === next.selectProjectDirectory && previous.referenceSourceAggregator === next.referenceSourceAggregator && previous.resolveWorkspaceReferenceEntryIconUrl === next.resolveWorkspaceReferenceEntryIconUrl && previous.resolveMentionReferenceTarget === next.resolveMentionReferenceTarget && previous.resolveWorkspaceReferenceInitialTarget === next.resolveWorkspaceReferenceInitialTarget && previous.onWorkspaceFileReferencesAdded === next.onWorkspaceFileReferencesAdded && previous.agentSettings.avoidGroupingEdits === next.agentSettings.avoidGroupingEdits && previous.title === next.title && agentGuiStateEquals(previous.state, next.state) && previous.position.x === next.position.x && previous.position.y === next.position.y && previous.width === next.width && previous.height === next.height && previous.desktopSize.width === next.desktopSize.width && previous.desktopSize.height === next.desktopSize.height && previous.onLinkAction === next.onLinkAction && previous.onHandoffConversation === next.onHandoffConversation && previous.onCapabilitySettingsRequest === next.onCapabilitySettingsRequest && previous.onAgentProviderLogin === next.onAgentProviderLogin && previous.providerTargets === next.providerTargets && previous.providerTargetsLoading === next.providerTargetsLoading && previous.comingSoonProviders === next.comingSoonProviders && previous.providerReadinessGates === next.providerReadinessGates && previous.defaultProviderTargetId === next.defaultProviderTargetId && previous.onClose === next.onClose && previous.onResize === next.onResize && previous.onUpdateNode === next.onUpdateNode && previous.onRememberComposerDefaults === next.onRememberComposerDefaults && previous.onOpenConversationWindow === next.onOpenConversationWindow && previous.isMaximized === next.isMaximized && previous.isMuted === next.isMuted && previous.onMinimize === next.onMinimize && previous.onToggleMaximize === next.onToggleMaximize && previous.onShowMessage === next.onShowMessage && previous.workspaceAgentProbes === next.workspaceAgentProbes && previous.onAgentProbeDemandChange === next.onAgentProbeDemandChange && previous.onAgentProbeRefreshRequest === next.onAgentProbeRefreshRequest && previous.managedAgentsState === next.managedAgentsState && previous.contextMentionProviders === next.contextMentionProviders && previous.workspaceAppIcons === next.workspaceAppIcons && previous.embedded === next.embedded && previous.previewMode === next.previewMode && previous.isActive === next.isActive && previous.composerFocusRequestSequence === next.composerFocusRequestSequence && previous.newConversationRequestSequence === next.newConversationRequestSequence && previous.openSessionRequest === next.openSessionRequest && previous.prefillPromptRequest === next.prefillPromptRequest;
29173
29607
  }
29174
29608
  var AgentGUINode = memo2(function AgentGUINode2({
29175
29609
  nodeId,
@@ -29198,6 +29632,7 @@ var AgentGUINode = memo2(function AgentGUINode2({
29198
29632
  onAgentProviderLogin,
29199
29633
  providerTargets,
29200
29634
  providerTargetsLoading = false,
29635
+ comingSoonProviders,
29201
29636
  providerReadinessGates = null,
29202
29637
  defaultProviderTargetId = null,
29203
29638
  onWorkspaceFileReferencesAdded,
@@ -29360,6 +29795,7 @@ var AgentGUINode = memo2(function AgentGUINode2({
29360
29795
  prefillPromptRequest,
29361
29796
  providerTargets,
29362
29797
  providerTargetsLoading,
29798
+ comingSoonProviders,
29363
29799
  providerReadinessGates,
29364
29800
  defaultProviderTargetId,
29365
29801
  previewMode,
@@ -30075,6 +30511,21 @@ var AgentGUINode = memo2(function AgentGUINode2({
30075
30511
  }
30076
30512
  onAgentProbeRefreshRequest(activeProbeProvider, `agent-gui:${nodeId}`);
30077
30513
  }, [activeProbeProvider, nodeId, onAgentProbeRefreshRequest, previewMode]);
30514
+ const handleAgentConfigMenuOpen = useCallback12(() => {
30515
+ if (previewMode || !onAgentProbeRefreshRequest) {
30516
+ return;
30517
+ }
30518
+ onAgentProbeRefreshRequest(
30519
+ railStatusProvider ?? activeProbeProvider,
30520
+ `agent-gui:${nodeId}:config`
30521
+ );
30522
+ }, [
30523
+ activeProbeProvider,
30524
+ nodeId,
30525
+ onAgentProbeRefreshRequest,
30526
+ previewMode,
30527
+ railStatusProvider
30528
+ ]);
30078
30529
  return /* @__PURE__ */ jsx33(
30079
30530
  WorkspaceNodeWindow,
30080
30531
  {
@@ -30147,6 +30598,7 @@ var AgentGUINode = memo2(function AgentGUINode2({
30147
30598
  slashStatusLimitsLoading: workspaceAgentProbes?.isLoadingUsage ?? false,
30148
30599
  railConfigProvider: railStatusProvider,
30149
30600
  railSlashStatusLimits,
30601
+ onAgentConfigMenuOpen: handleAgentConfigMenuOpen,
30150
30602
  previewMode,
30151
30603
  onLinkAction: handleLinkAction,
30152
30604
  onHandoffConversation,