@tutti-os/agent-gui 0.0.36 → 0.0.38

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 (39) hide show
  1. package/dist/{AgentMessageMarkdown-0sV8Biv3.d.ts → AgentMessageMarkdown-Cq-7DSV2.d.ts} +3 -2
  2. package/dist/agent-conversation/index.d.ts +4 -4
  3. package/dist/agent-conversation/index.js +4 -4
  4. package/dist/agent-message-center/index.d.ts +3 -2
  5. package/dist/agent-message-center/index.js +12 -5
  6. package/dist/agent-message-center/index.js.map +1 -1
  7. package/dist/{agentConversationVM-xuzmD5IL.d.ts → agentConversationVM-1QgRwvwZ.d.ts} +1 -1
  8. package/dist/app/renderer/agentactivity.css +25 -7
  9. package/dist/{chunk-CMXRLF64.js → chunk-44YASHVW.js} +90 -95
  10. package/dist/chunk-44YASHVW.js.map +1 -0
  11. package/dist/{chunk-O56P2KSZ.js → chunk-7F4M55U3.js} +53 -16
  12. package/dist/chunk-7F4M55U3.js.map +1 -0
  13. package/dist/{chunk-KFMD33UD.js → chunk-JL2WNRYC.js} +7 -7
  14. package/dist/chunk-JL2WNRYC.js.map +1 -0
  15. package/dist/{chunk-JYH2ITNL.js → chunk-L7FBT3VR.js} +4 -4
  16. package/dist/{chunk-U3D7YI47.js → chunk-MKSRP5XS.js} +8 -7
  17. package/dist/{chunk-U3D7YI47.js.map → chunk-MKSRP5XS.js.map} +1 -1
  18. package/dist/{chunk-UN4XGHLQ.js → chunk-SS5YEVAI.js} +79 -107
  19. package/dist/chunk-SS5YEVAI.js.map +1 -0
  20. package/dist/{chunk-3LEUGNCT.js → chunk-WHWZZYBV.js} +2 -2
  21. package/dist/{chunk-VPC55T7P.js → chunk-XROBPALT.js} +2 -2
  22. package/dist/context-mention-palette/index.js +5 -5
  23. package/dist/i18n/index.d.ts +6 -6
  24. package/dist/i18n/index.js +1 -1
  25. package/dist/index.d.ts +7 -5
  26. package/dist/index.js +413 -96
  27. package/dist/index.js.map +1 -1
  28. package/dist/plan-decision-ops.d.ts +2 -2
  29. package/dist/workspace-agent-generated-files.d.ts +1 -1
  30. package/dist/workspace-agent-generated-files.js +2 -2
  31. package/dist/{workspaceAgentActivityListViewModel-DwpbJGDx.d.ts → workspaceAgentActivityListViewModel-DLnMBMoh.d.ts} +3 -4
  32. package/package.json +12 -12
  33. package/dist/chunk-CMXRLF64.js.map +0 -1
  34. package/dist/chunk-KFMD33UD.js.map +0 -1
  35. package/dist/chunk-O56P2KSZ.js.map +0 -1
  36. package/dist/chunk-UN4XGHLQ.js.map +0 -1
  37. /package/dist/{chunk-JYH2ITNL.js.map → chunk-L7FBT3VR.js.map} +0 -0
  38. /package/dist/{chunk-3LEUGNCT.js.map → chunk-WHWZZYBV.js.map} +0 -0
  39. /package/dist/{chunk-VPC55T7P.js.map → chunk-XROBPALT.js.map} +0 -0
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ import {
13
13
  import {
14
14
  AgentInteractivePromptSurface,
15
15
  approvalOptionDisplayLabel
16
- } from "./chunk-JYH2ITNL.js";
16
+ } from "./chunk-L7FBT3VR.js";
17
17
  import {
18
18
  PLAN_IMPLEMENTATION_ACTION_FEEDBACK,
19
19
  PLAN_IMPLEMENTATION_ACTION_IMPLEMENT,
@@ -37,13 +37,13 @@ import {
37
37
  skillDescriptionForDisplay,
38
38
  skillTriggerForPrefix,
39
39
  useProjectedAgentConversation
40
- } from "./chunk-O56P2KSZ.js";
40
+ } from "./chunk-7F4M55U3.js";
41
41
  import {
42
42
  AgentMessageMarkdown,
43
43
  ZoomableImage,
44
44
  cn,
45
45
  resolveWorkspaceLinkAction
46
- } from "./chunk-CMXRLF64.js";
46
+ } from "./chunk-44YASHVW.js";
47
47
  import {
48
48
  AGENT_MENTION_FILTER_TAB_ORDER,
49
49
  AgentFileMentionPalette,
@@ -51,7 +51,7 @@ import {
51
51
  DEFAULT_AGENT_MENTION_FILTER,
52
52
  agentMentionItemKey,
53
53
  preloadAgentMentionBrowse
54
- } from "./chunk-U3D7YI47.js";
54
+ } from "./chunk-MKSRP5XS.js";
55
55
  import {
56
56
  WORKSPACE_AGENT_ACTIVITY_RUNTIME_SESSION_ORIGIN,
57
57
  buildWorkspaceAgentActivityListViewModel,
@@ -60,15 +60,14 @@ import {
60
60
  isWorkspaceAgentActivityRuntimeSessionOrigin,
61
61
  isWorkspaceAgentUntitledTask,
62
62
  mergeWorkspaceAgentActivityDurableAndOverlayMessages,
63
- normalizeOptionalWorkspaceAgentStatus,
64
63
  selectWorkspaceAgentActivityOverlayMessages
65
- } from "./chunk-UN4XGHLQ.js";
64
+ } from "./chunk-SS5YEVAI.js";
66
65
  import {
67
66
  MANAGED_AGENT_ICON_FALLBACK_URL,
68
67
  MANAGED_AGENT_ICON_URLS,
69
68
  Spinner,
70
69
  normalizeManagedAgentProvider
71
- } from "./chunk-3LEUGNCT.js";
70
+ } from "./chunk-WHWZZYBV.js";
72
71
  import "./chunk-MTFSQWZ6.js";
73
72
  import {
74
73
  resolveWorkspaceAgentSessionSortTimeUnixMs
@@ -79,7 +78,7 @@ import {
79
78
  mentionItemToAttrs,
80
79
  normalizeAgentSessionMentionTitle,
81
80
  parseMentionItemFromHref
82
- } from "./chunk-VPC55T7P.js";
81
+ } from "./chunk-XROBPALT.js";
83
82
  import "./chunk-Y35GDLP2.js";
84
83
  import {
85
84
  AgentActivityHostProvider,
@@ -108,12 +107,13 @@ import {
108
107
  getActiveUiLanguage,
109
108
  translate,
110
109
  useTranslation
111
- } from "./chunk-KFMD33UD.js";
110
+ } from "./chunk-JL2WNRYC.js";
112
111
  import "./chunk-LUGELG5V.js";
113
112
  import "./chunk-PJP5BUU6.js";
114
113
 
115
114
  // shared/agentActivitySnapshotProjection.ts
116
115
  import {
116
+ normalizeAgentActivityDisplayStatus,
117
117
  selectNeedsAttentionCount,
118
118
  selectNeedsAttentionItems
119
119
  } from "@tutti-os/agent-activity-core";
@@ -170,22 +170,23 @@ function agentHostPresenceFromCore(presence, index) {
170
170
  };
171
171
  }
172
172
  function agentHostSessionFromCore(session, id, presenceId) {
173
+ const displayStatus = agentActivityDisplayStatusFromSession(session);
173
174
  return {
174
175
  agentSessionId: session.agentSessionId,
175
176
  endedAtUnixMs: session.endedAtUnixMs,
176
177
  startedAtUnixMs: session.startedAtUnixMs,
177
178
  createdAtUnixMs: session.createdAtUnixMs,
178
179
  cwd: session.cwd,
179
- effectiveStatus: agentHostEffectiveStatusFromCore(session.status),
180
+ effectiveStatus: agentHostEffectiveStatusFromDisplay(displayStatus),
180
181
  id,
181
- lifecycleStatus: agentHostLifecycleStatusFromCore(session.status),
182
+ lifecycleStatus: agentHostLifecycleStatusFromDisplay(displayStatus),
182
183
  presenceId,
183
184
  pinnedAtUnixMs: session.pinnedAtUnixMs,
184
185
  provider: session.provider,
185
186
  providerSessionId: session.providerSessionId ?? session.agentSessionId,
186
187
  resumable: session.resumable ?? false,
187
188
  sessionOrigin: "WORKSPACE_AGENT_SESSION_ORIGIN_RUNTIME",
188
- status: agentHostSessionStatusFromCore(session.status),
189
+ status: agentHostSessionStatusFromDisplay(displayStatus),
189
190
  syncState: session.lastError ? {
190
191
  agentSessionId: session.agentSessionId,
191
192
  lastError: session.lastError,
@@ -194,7 +195,7 @@ function agentHostSessionFromCore(session, id, presenceId) {
194
195
  workspaceId: session.workspaceId
195
196
  } : void 0,
196
197
  title: session.title || void 0,
197
- turnPhase: agentHostTurnPhaseFromCore(session.status),
198
+ turnPhase: agentHostTurnPhaseFromDisplay(displayStatus),
198
199
  updatedAtUnixMs: session.updatedAtUnixMs ?? session.lastEventUnixMs,
199
200
  userId: session.userId?.trim() || "local",
200
201
  workspaceId: session.workspaceId
@@ -212,7 +213,7 @@ function agentHostMessageFromCore(message) {
212
213
  role: message.role,
213
214
  startedAtUnixMs: message.startedAtUnixMs,
214
215
  status: message.status ?? void 0,
215
- turnId: message.turnId ?? void 0,
216
+ turnId: message.turnId,
216
217
  version: message.version,
217
218
  workspaceId: message.workspaceId ?? ""
218
219
  };
@@ -222,6 +223,7 @@ function projectCoreSessionStatus(status) {
222
223
  }
223
224
  function agentHostSessionStatusFromCore(status) {
224
225
  switch (status) {
226
+ case "active":
225
227
  case "created":
226
228
  case "queued":
227
229
  return "ready";
@@ -233,21 +235,20 @@ function agentHostSessionStatusFromCore(status) {
233
235
  return status;
234
236
  }
235
237
  }
236
- function agentHostEffectiveStatusFromCore(status) {
237
- switch (status) {
238
- case "created":
239
- case "queued":
240
- return "ready";
241
- case "running":
242
- return "working";
243
- case "waiting":
244
- case "failed":
245
- return status;
246
- default:
247
- return "idle";
248
- }
238
+ function agentActivityDisplayStatusFromSession(session) {
239
+ return normalizeAgentActivityDisplayStatus(session.status, {
240
+ currentPhase: session.currentPhase,
241
+ turnLifecycleOutcome: session.turnLifecycle?.outcome,
242
+ turnLifecyclePhase: session.turnLifecycle?.phase
243
+ });
244
+ }
245
+ function agentHostSessionStatusFromDisplay(status) {
246
+ return status === "idle" ? "ready" : status;
247
+ }
248
+ function agentHostEffectiveStatusFromDisplay(status) {
249
+ return status === "idle" ? "ready" : status;
249
250
  }
250
- function agentHostLifecycleStatusFromCore(status) {
251
+ function agentHostLifecycleStatusFromDisplay(status) {
251
252
  switch (status) {
252
253
  case "failed":
253
254
  return "failed";
@@ -258,15 +259,12 @@ function agentHostLifecycleStatusFromCore(status) {
258
259
  return "active";
259
260
  }
260
261
  }
261
- function agentHostTurnPhaseFromCore(status) {
262
+ function agentHostTurnPhaseFromDisplay(status) {
262
263
  switch (status) {
263
- case "running":
264
264
  case "working":
265
- return "working";
266
265
  case "waiting":
267
- return "waiting";
268
266
  case "failed":
269
- return "failed";
267
+ return status;
270
268
  default:
271
269
  return "idle";
272
270
  }
@@ -2723,7 +2721,8 @@ function conversationSummaryFromAgentSession(session, options = {}) {
2723
2721
  titleFallback,
2724
2722
  status: conversationStatusFromActivity("idle"),
2725
2723
  cwd: session.cwd?.trim() ?? "",
2726
- project: projectResolver.resolve(session.cwd),
2724
+ project: resolveConversationProject(session, projectResolver),
2725
+ ...isExternalImportNoProjectSession(session) ? { projectMode: "none" } : {},
2727
2726
  pinnedAtUnixMs: session.pinnedAtUnixMs ?? null,
2728
2727
  sortTimeUnixMs: resolveWorkspaceAgentSessionSortTimeUnixMs(
2729
2728
  workspaceAgentSession
@@ -2739,7 +2738,7 @@ function applyAgentGUIConversationProjects(conversations, userProjects = [], opt
2739
2738
  options
2740
2739
  );
2741
2740
  const next = conversations.map((conversation) => {
2742
- const project = projectResolver.resolve(conversation.cwd);
2741
+ const project = conversation.projectMode === "none" ? null : projectResolver.resolve(conversation.cwd);
2743
2742
  if (isSameAgentGUIConversationProject(conversation.project, project)) {
2744
2743
  return conversation;
2745
2744
  }
@@ -2818,13 +2817,24 @@ function conversationSummaryFromActivity(activity, session, options) {
2818
2817
  titleFallback,
2819
2818
  status,
2820
2819
  cwd: session?.cwd.trim() ?? "",
2821
- project: options.projectResolver.resolve(session?.cwd),
2820
+ project: resolveConversationProject(session, options.projectResolver),
2821
+ ...isExternalImportNoProjectSession(session) ? { projectMode: "none" } : {},
2822
2822
  pinnedAtUnixMs: session?.pinnedAtUnixMs ?? null,
2823
2823
  sortTimeUnixMs: activity.sortTimeUnixMs,
2824
2824
  updatedAtUnixMs: session?.updatedAtUnixMs || activity.sortTimeUnixMs || 0,
2825
2825
  syncState: session?.syncState
2826
2826
  };
2827
2827
  }
2828
+ function resolveConversationProject(session, projectResolver) {
2829
+ if (isExternalImportNoProjectSession(session)) {
2830
+ return null;
2831
+ }
2832
+ return projectResolver.resolve(session?.cwd);
2833
+ }
2834
+ function isExternalImportNoProjectSession(session) {
2835
+ const runtimeContext = session && "runtimeContext" in session ? session.runtimeContext : void 0;
2836
+ return runtimeContext?.externalImportNoProject === true;
2837
+ }
2828
2838
  function isSameAgentGUIConversationProject(left, right) {
2829
2839
  if (!left && !right) {
2830
2840
  return true;
@@ -2925,28 +2935,32 @@ function firstUserMessageTitleFromMessages(messages) {
2925
2935
  return userMessage ? messageText(userMessage) : "";
2926
2936
  }
2927
2937
  function workspaceAgentMessagesFromTimelineItems(timelineItems) {
2928
- return timelineItems.map((item, index) => ({
2929
- id: item.id,
2930
- workspaceId: item.workspaceId,
2931
- agentSessionId: item.agentSessionId,
2932
- messageId: item.eventId || `${item.agentSessionId}:${item.id}:${index}`,
2933
- version: item.seq ?? item.id,
2934
- ...item.turnId ? { turnId: item.turnId } : {},
2935
- role: item.role ?? timelineItemRole(item) ?? item.actorType,
2936
- kind: item.itemType === "call" ? "tool_call" : item.itemType,
2937
- ...item.status ? { status: item.status } : {},
2938
- payload: {
2939
- ...item.payload,
2940
- content: item.payload?.content ?? item.content,
2941
- text: item.payload?.text ?? item.content,
2942
- callType: item.callType,
2943
- callId: item.callId,
2944
- name: item.name
2945
- },
2946
- occurredAtUnixMs: item.occurredAtUnixMs ?? item.createdAtUnixMs,
2947
- startedAtUnixMs: item.createdAtUnixMs,
2948
- completedAtUnixMs: item.occurredAtUnixMs
2949
- }));
2938
+ return timelineItems.map((item, index) => {
2939
+ const messageId = item.eventId || `${item.agentSessionId}:${item.id}:${index}`;
2940
+ const version = item.seq ?? item.id;
2941
+ return {
2942
+ id: item.id,
2943
+ workspaceId: item.workspaceId,
2944
+ agentSessionId: item.agentSessionId,
2945
+ messageId,
2946
+ version,
2947
+ turnId: item.turnId || `timeline:${messageId}`,
2948
+ role: item.role ?? timelineItemRole(item) ?? item.actorType,
2949
+ kind: item.itemType === "call" ? "tool_call" : item.itemType,
2950
+ ...item.status ? { status: item.status } : {},
2951
+ payload: {
2952
+ ...item.payload,
2953
+ content: item.payload?.content ?? item.content,
2954
+ text: item.payload?.text ?? item.content,
2955
+ callType: item.callType,
2956
+ callId: item.callId,
2957
+ name: item.name
2958
+ },
2959
+ occurredAtUnixMs: item.occurredAtUnixMs ?? item.createdAtUnixMs ?? version,
2960
+ startedAtUnixMs: item.createdAtUnixMs,
2961
+ completedAtUnixMs: item.occurredAtUnixMs
2962
+ };
2963
+ });
2950
2964
  }
2951
2965
  function messageRole(message) {
2952
2966
  const role = message.role?.trim().toLowerCase();
@@ -3354,6 +3368,120 @@ function agentPromptFileBlockToDraftFile(file, idPrefix, index) {
3354
3368
  };
3355
3369
  }
3356
3370
 
3371
+ // shared/workspaceAgentStatusNormalizer.ts
3372
+ var FAILED_STATUS_TOKENS = /* @__PURE__ */ new Set(["failed", "error"]);
3373
+ var CANCELED_STATUS_TOKENS = /* @__PURE__ */ new Set([
3374
+ "canceled",
3375
+ "cancelled",
3376
+ "interrupted"
3377
+ ]);
3378
+ var COMPLETED_STATUS_TOKENS = /* @__PURE__ */ new Set(["completed", "ended", "end"]);
3379
+ var WAITING_APPROVAL_TOKENS = /* @__PURE__ */ new Set([
3380
+ "waiting_approval",
3381
+ "awaiting_approval"
3382
+ ]);
3383
+ var WAITING_INPUT_TOKENS = /* @__PURE__ */ new Set(["waiting_input"]);
3384
+ var WAITING_STATUS_TOKENS = /* @__PURE__ */ new Set(["waiting"]);
3385
+ var WORKING_STATUS_TOKENS = /* @__PURE__ */ new Set([
3386
+ "submitted",
3387
+ "working",
3388
+ "running",
3389
+ "streaming"
3390
+ ]);
3391
+ var READY_STATUS_TOKENS = /* @__PURE__ */ new Set(["ready", "idle"]);
3392
+ function normalizeOptionalWorkspaceAgentStatus(input) {
3393
+ const lifecycleStatus = normalizeStatusToken(input.lifecycleStatus);
3394
+ const effectiveStatus = normalizeStatusToken(input.effectiveStatus);
3395
+ const sessionStatus = normalizeStatusToken(input.status);
3396
+ const turnLifecycleOutcome = normalizeStatusToken(
3397
+ input.turnLifecycle?.outcome
3398
+ );
3399
+ const turnPhase = normalizeStatusToken(
3400
+ input.turnLifecycle?.phase ?? input.turnPhase
3401
+ );
3402
+ const currentPhase = normalizeStatusToken(input.currentPhase);
3403
+ const tokens = [
3404
+ lifecycleStatus,
3405
+ effectiveStatus,
3406
+ sessionStatus,
3407
+ turnPhase,
3408
+ currentPhase
3409
+ ].filter(Boolean);
3410
+ if (tokens.length === 0) {
3411
+ return null;
3412
+ }
3413
+ if (turnPhase === "settled") {
3414
+ if (FAILED_STATUS_TOKENS.has(turnLifecycleOutcome)) {
3415
+ return { kind: "failed" };
3416
+ }
3417
+ if (CANCELED_STATUS_TOKENS.has(turnLifecycleOutcome)) {
3418
+ return { kind: "canceled" };
3419
+ }
3420
+ if (COMPLETED_STATUS_TOKENS.has(turnLifecycleOutcome)) {
3421
+ return { kind: "completed" };
3422
+ }
3423
+ if (FAILED_STATUS_TOKENS.has(sessionStatus) || FAILED_STATUS_TOKENS.has(currentPhase)) {
3424
+ return { kind: "failed" };
3425
+ }
3426
+ if (CANCELED_STATUS_TOKENS.has(sessionStatus) || CANCELED_STATUS_TOKENS.has(currentPhase)) {
3427
+ return { kind: "canceled" };
3428
+ }
3429
+ return { kind: "completed" };
3430
+ }
3431
+ if ([lifecycleStatus, effectiveStatus, sessionStatus, currentPhase].some(
3432
+ (token) => FAILED_STATUS_TOKENS.has(token)
3433
+ )) {
3434
+ return { kind: "failed" };
3435
+ }
3436
+ if ([lifecycleStatus, effectiveStatus, sessionStatus].some(
3437
+ (token) => CANCELED_STATUS_TOKENS.has(token)
3438
+ )) {
3439
+ return { kind: "canceled" };
3440
+ }
3441
+ if ([lifecycleStatus, effectiveStatus, sessionStatus].some(
3442
+ (token) => COMPLETED_STATUS_TOKENS.has(token)
3443
+ )) {
3444
+ return { kind: "completed" };
3445
+ }
3446
+ const waitKind = waitingKindFromTokens([
3447
+ currentPhase,
3448
+ turnPhase,
3449
+ effectiveStatus,
3450
+ sessionStatus
3451
+ ]);
3452
+ if (waitKind) {
3453
+ return { kind: "waiting", waitKind };
3454
+ }
3455
+ if ([currentPhase, turnPhase, effectiveStatus, sessionStatus].some(
3456
+ (token) => WAITING_STATUS_TOKENS.has(token)
3457
+ )) {
3458
+ return { kind: "waiting" };
3459
+ }
3460
+ if ([currentPhase, turnPhase, effectiveStatus, sessionStatus].some(
3461
+ (token) => WORKING_STATUS_TOKENS.has(token)
3462
+ )) {
3463
+ return { kind: "working" };
3464
+ }
3465
+ if (lifecycleStatus === "active" || lifecycleStatus === "ready" || [currentPhase, turnPhase, effectiveStatus, sessionStatus].some(
3466
+ (token) => READY_STATUS_TOKENS.has(token)
3467
+ )) {
3468
+ return { kind: "ready" };
3469
+ }
3470
+ return null;
3471
+ }
3472
+ function waitingKindFromTokens(tokens) {
3473
+ if (tokens.some((token) => WAITING_APPROVAL_TOKENS.has(token))) {
3474
+ return "approval";
3475
+ }
3476
+ if (tokens.some((token) => WAITING_INPUT_TOKENS.has(token))) {
3477
+ return "input";
3478
+ }
3479
+ return void 0;
3480
+ }
3481
+ function normalizeStatusToken(status) {
3482
+ return status?.trim().toLowerCase() ?? "";
3483
+ }
3484
+
3357
3485
  // shared/agentConversation/projection/workspaceAgentMessageProjection.ts
3358
3486
  function projectWorkspaceAgentMessagesToTimelineItems(messages) {
3359
3487
  const sortedMessages = latestMessageSnapshots(messages).sort(
@@ -6459,6 +6587,7 @@ var EMPTY_AGENT_GUI_MESSAGES = [];
6459
6587
  var EMPTY_AGENT_GUI_AVAILABLE_COMMANDS = [];
6460
6588
  var ACTIVITY_STREAM_STATE_RELOAD_DEBOUNCE_MS = 150;
6461
6589
  var AGENT_GUI_DETAIL_MESSAGES_PAGE_SIZE = 100;
6590
+ var AGENT_GUI_SUBMIT_RETARGET_EARLY_MESSAGE_TOLERANCE_MS = 5e3;
6462
6591
  function mergeAgentModelCatalogInvalidationEvents(events) {
6463
6592
  const providers = /* @__PURE__ */ new Set();
6464
6593
  let occurredAtUnixMs = 0;
@@ -7052,8 +7181,18 @@ function filterMessagesForDetailWindowOverlay(input) {
7052
7181
  return newestDurableVersion !== null && Number.isFinite(message.version) && message.version >= newestDurableVersion;
7053
7182
  });
7054
7183
  }
7055
- const oldestDetailVersion = minFiniteMessageVersion(input.detailMessages);
7056
- const newestDetailVersion = maxFiniteMessageVersion(input.detailMessages);
7184
+ const boundedDetailMessages = input.detailMessages.filter(
7185
+ (message) => !isWorkspaceAgentActivityOptimisticMessage(message)
7186
+ );
7187
+ const oldestDetailVersion = minFiniteMessageVersion(boundedDetailMessages);
7188
+ const newestDetailVersion = maxFiniteMessageVersion(boundedDetailMessages);
7189
+ if (oldestDetailVersion === null && newestDetailVersion === null) {
7190
+ const optimisticWindowMessages = filterMessagesForOptimisticDetailWindow({
7191
+ detailMessages: input.detailMessages,
7192
+ localMessages: input.localMessages
7193
+ });
7194
+ return optimisticWindowMessages.length > 0 || input.detailMessages.some(isWorkspaceAgentActivityOptimisticMessage) ? optimisticWindowMessages : [...input.localMessages];
7195
+ }
7057
7196
  return input.localMessages.filter((message) => {
7058
7197
  if (isWorkspaceAgentActivityOptimisticMessage(message)) {
7059
7198
  return true;
@@ -7067,6 +7206,69 @@ function filterMessagesForDetailWindowOverlay(input) {
7067
7206
  return oldestDetailVersion !== null && message.version >= oldestDetailVersion;
7068
7207
  });
7069
7208
  }
7209
+ function filterMessagesForOptimisticDetailWindow(input) {
7210
+ const optimisticTurnIds = new Set(
7211
+ input.detailMessages.filter(isWorkspaceAgentActivityOptimisticMessage).map((message) => message.turnId?.trim() ?? "").filter(Boolean)
7212
+ );
7213
+ if (optimisticTurnIds.size === 0) {
7214
+ return [];
7215
+ }
7216
+ return input.localMessages.filter((message) => {
7217
+ if (isWorkspaceAgentActivityOptimisticMessage(message)) {
7218
+ return true;
7219
+ }
7220
+ const turnId = message.turnId?.trim() ?? "";
7221
+ return turnId !== "" && optimisticTurnIds.has(turnId);
7222
+ });
7223
+ }
7224
+ function retargetOptimisticPromptMessages(messages, input) {
7225
+ const clientSubmitId = input.clientSubmitId.trim();
7226
+ const turnId = input.turnId.trim();
7227
+ if (!clientSubmitId || !turnId || messages.length === 0) {
7228
+ return { changed: false, messages: [...messages] };
7229
+ }
7230
+ const pendingTurnId = createPendingOptimisticTurnId(clientSubmitId);
7231
+ let changed = false;
7232
+ const retargeted = messages.map((message) => {
7233
+ if (!isWorkspaceAgentActivityOptimisticMessage(message) || message.turnId?.trim() !== pendingTurnId) {
7234
+ return message;
7235
+ }
7236
+ const messageClientSubmitId = message.payload?.clientSubmitId;
7237
+ if (typeof messageClientSubmitId === "string" && messageClientSubmitId.trim() && messageClientSubmitId.trim() !== clientSubmitId) {
7238
+ return message;
7239
+ }
7240
+ changed = true;
7241
+ return { ...message, turnId };
7242
+ });
7243
+ return { changed, messages: retargeted };
7244
+ }
7245
+ function shouldRetargetOptimisticPromptFromMessage(message, trace) {
7246
+ const turnId = message.turnId?.trim() ?? "";
7247
+ if (!turnId || trace.turnId) {
7248
+ return false;
7249
+ }
7250
+ const clientSubmitId = stringPayloadValue2(message.payload, "clientSubmitId");
7251
+ if (clientSubmitId?.trim()) {
7252
+ return clientSubmitId.trim() === trace.clientSubmitId;
7253
+ }
7254
+ if (message.role.trim().toLowerCase() === "user") {
7255
+ return false;
7256
+ }
7257
+ const messageTimeUnixMs = messageActivityTimeUnixMs(message);
7258
+ return messageTimeUnixMs === null || messageTimeUnixMs >= trace.startedAtUnixMs - AGENT_GUI_SUBMIT_RETARGET_EARLY_MESSAGE_TOLERANCE_MS;
7259
+ }
7260
+ function messageActivityTimeUnixMs(message) {
7261
+ for (const value of [
7262
+ message.occurredAtUnixMs,
7263
+ message.startedAtUnixMs,
7264
+ message.completedAtUnixMs
7265
+ ]) {
7266
+ if (typeof value === "number" && Number.isFinite(value) && value > 0) {
7267
+ return value;
7268
+ }
7269
+ }
7270
+ return null;
7271
+ }
7070
7272
  function minFiniteMessageVersion(messages) {
7071
7273
  let result = null;
7072
7274
  for (const message of messages) {
@@ -7924,7 +8126,7 @@ function messageFromMessageUpdate(update) {
7924
8126
  agentSessionId: update.agentSessionId,
7925
8127
  messageId: update.messageId.trim() || `message:${id}`,
7926
8128
  version: id,
7927
- ...update.turnId?.trim() ? { turnId: update.turnId.trim() } : {},
8129
+ turnId: update.turnId.trim(),
7928
8130
  role,
7929
8131
  kind,
7930
8132
  status: update.status,
@@ -7933,7 +8135,7 @@ function messageFromMessageUpdate(update) {
7933
8135
  ...isToolCall && update.callId?.trim() ? { callId: update.callId.trim() } : {},
7934
8136
  ...isToolCall && update.title?.trim() ? { title: update.title.trim() } : {}
7935
8137
  },
7936
- ...update.occurredAtUnixMs !== void 0 ? { occurredAtUnixMs: update.occurredAtUnixMs } : {},
8138
+ occurredAtUnixMs: update.occurredAtUnixMs,
7937
8139
  ...update.startedAtUnixMs !== void 0 ? { startedAtUnixMs: update.startedAtUnixMs } : {},
7938
8140
  ...update.completedAtUnixMs !== void 0 ? { completedAtUnixMs: update.completedAtUnixMs } : {}
7939
8141
  };
@@ -8487,10 +8689,22 @@ function useAgentGUINodeController({
8487
8689
  useEffect4(() => {
8488
8690
  const externalId = data.lastActiveAgentSessionId?.trim() ?? "";
8489
8691
  if (externalId === (activeConversationIdRef.current ?? "")) return;
8490
- setIntent((current) => {
8491
- if (!externalId) {
8492
- return current.tag !== "home" ? { tag: "home" } : current;
8692
+ if (!externalId) {
8693
+ const previous = activeConversationIdRef.current;
8694
+ if (previous) {
8695
+ void activation.unactivate(previous);
8493
8696
  }
8697
+ setIntent({ tag: "home" });
8698
+ isComposerHomeRef.current = true;
8699
+ setIsComposerHome(true);
8700
+ activeConversationIdRef.current = null;
8701
+ setActiveConversationId(null);
8702
+ setIsLoadingMessages(false);
8703
+ setDetailError(null);
8704
+ loadDraftComposerOptions();
8705
+ return;
8706
+ }
8707
+ setIntent((current) => {
8494
8708
  if ((current.tag === "active" || current.tag === "requested") && current.id === externalId) {
8495
8709
  return current;
8496
8710
  }
@@ -8689,6 +8903,15 @@ function useAgentGUINodeController({
8689
8903
  const updateSelectedProjectPath = useCallback4(
8690
8904
  (path, metadata) => {
8691
8905
  const normalizedPath = normalizeProjectDraftPath(path);
8906
+ const project = metadata?.project;
8907
+ if (project && normalizedPath && project.path === normalizedPath) {
8908
+ const nextProjects = upsertAgentGUIUserProject(
8909
+ userProjectsRef.current,
8910
+ project
8911
+ );
8912
+ userProjectsRef.current = nextProjects;
8913
+ setUserProjectsSnapshot(nextProjects);
8914
+ }
8692
8915
  selectedProjectPathRef.current = normalizedPath;
8693
8916
  setSelectedProjectPath(normalizedPath);
8694
8917
  const agentSessionId = activeConversationIdRef.current;
@@ -9825,6 +10048,42 @@ function useAgentGUINodeController({
9825
10048
  sessionViewRef
9826
10049
  ]
9827
10050
  );
10051
+ const retargetOptimisticPromptTurn = useCallback4(
10052
+ (agentSessionId, clientSubmitId, turnId) => {
10053
+ const normalizedAgentSessionId = agentSessionId.trim();
10054
+ const normalizedTurnId = turnId.trim();
10055
+ if (!normalizedAgentSessionId || !clientSubmitId.trim() || !normalizedTurnId) {
10056
+ return;
10057
+ }
10058
+ const sessionView = getAgentSessionView(
10059
+ sessionViewRef(normalizedAgentSessionId)
10060
+ );
10061
+ if (!sessionView) {
10062
+ return;
10063
+ }
10064
+ const detail = retargetOptimisticPromptMessages(
10065
+ sessionView.detailMessages,
10066
+ { clientSubmitId, turnId: normalizedTurnId }
10067
+ );
10068
+ if (detail.changed) {
10069
+ setAgentSessionViewDetailMessages(
10070
+ sessionViewRef(normalizedAgentSessionId),
10071
+ detail.messages
10072
+ );
10073
+ }
10074
+ const overlay = retargetOptimisticPromptMessages(
10075
+ sessionView.overlayMessages,
10076
+ { clientSubmitId, turnId: normalizedTurnId }
10077
+ );
10078
+ if (overlay.changed) {
10079
+ setAgentSessionViewOverlayMessages(
10080
+ sessionViewRef(normalizedAgentSessionId),
10081
+ overlay.messages
10082
+ );
10083
+ }
10084
+ },
10085
+ [sessionViewRef]
10086
+ );
9828
10087
  const applyStatePatch = useCallback4(
9829
10088
  (patch) => {
9830
10089
  const agentSessionId = patch.agentSessionId.trim();
@@ -9842,11 +10101,8 @@ function useAgentGUINodeController({
9842
10101
  const structuredTurnPhase = patch.turn?.phase?.trim() ?? "";
9843
10102
  const submitTrace = submitTraceBySessionIdRef.current[agentSessionId];
9844
10103
  if (submitTrace && structuredTurnPhase) {
9845
- const matchesTraceTurn = !submitTrace.turnId || patchTurnId === submitTrace.turnId || patchActiveTurnId === submitTrace.turnId;
10104
+ const matchesTraceTurn = Boolean(submitTrace.turnId) && (patchTurnId === submitTrace.turnId || patchActiveTurnId === submitTrace.turnId);
9846
10105
  if (matchesTraceTurn) {
9847
- if (!submitTrace.turnId && (patchTurnId || patchActiveTurnId)) {
9848
- submitTrace.turnId = patchTurnId || patchActiveTurnId;
9849
- }
9850
10106
  reportAgentSubmitTraceDiagnostic({
9851
10107
  event: `lifecycle.${structuredTurnPhase}`,
9852
10108
  runtime: agentActivityRuntime,
@@ -9959,6 +10215,7 @@ function useAgentGUINodeController({
9959
10215
  [
9960
10216
  patchConversation,
9961
10217
  resolveSessionMessages,
10218
+ retargetOptimisticPromptTurn,
9962
10219
  sessionViewRef,
9963
10220
  setTransientConversation,
9964
10221
  statePatchErrorBySessionId,
@@ -10001,6 +10258,16 @@ function useAgentGUINodeController({
10001
10258
  if (!agentSessionId) {
10002
10259
  continue;
10003
10260
  }
10261
+ const submitTrace = submitTraceBySessionIdRef.current[agentSessionId];
10262
+ const messageTurnId = message.turnId?.trim() ?? "";
10263
+ if (submitTrace && messageTurnId && shouldRetargetOptimisticPromptFromMessage(message, submitTrace)) {
10264
+ submitTrace.turnId = messageTurnId;
10265
+ retargetOptimisticPromptTurn(
10266
+ agentSessionId,
10267
+ submitTrace.clientSubmitId,
10268
+ messageTurnId
10269
+ );
10270
+ }
10004
10271
  const completionKey = completionKeyFromMessage(message);
10005
10272
  if (completionKey) {
10006
10273
  pendingCompletionKeysBySessionId.set(agentSessionId, completionKey);
@@ -10024,7 +10291,8 @@ function useAgentGUINodeController({
10024
10291
  applyStatePatch,
10025
10292
  applyBackgroundTimelineStatusUpdate,
10026
10293
  conversationListQuery,
10027
- recordLocalMessages
10294
+ recordLocalMessages,
10295
+ retargetOptimisticPromptTurn
10028
10296
  ]
10029
10297
  );
10030
10298
  const handleBackgroundActivityStreamEvents = useCallback4(
@@ -13158,6 +13426,25 @@ function areAgentGUIUserProjectsEqual(left, right) {
13158
13426
  return candidate !== void 0 && project.id === candidate.id && project.path === candidate.path && project.label === candidate.label;
13159
13427
  });
13160
13428
  }
13429
+ function upsertAgentGUIUserProject(projects, project) {
13430
+ const normalizedProject = {
13431
+ ...project.createdAtUnixMs === void 0 ? {} : { createdAtUnixMs: project.createdAtUnixMs },
13432
+ id: project.id,
13433
+ ...project.lastUsedAtUnixMs === void 0 || project.lastUsedAtUnixMs === null ? {} : { lastUsedAtUnixMs: project.lastUsedAtUnixMs },
13434
+ label: project.label,
13435
+ path: project.path,
13436
+ ...project.updatedAtUnixMs === void 0 ? {} : { updatedAtUnixMs: project.updatedAtUnixMs }
13437
+ };
13438
+ const index = projects.findIndex(
13439
+ (candidate) => candidate.id === normalizedProject.id || candidate.path === normalizedProject.path
13440
+ );
13441
+ if (index === -1) {
13442
+ return [...projects, normalizedProject];
13443
+ }
13444
+ const next = [...projects];
13445
+ next[index] = normalizedProject;
13446
+ return next;
13447
+ }
13161
13448
  function readAgentGUIUserProjectSnapshot(api) {
13162
13449
  const projects = api?.service?.getSnapshot?.().projects ?? [];
13163
13450
  return projects.map((project) => ({
@@ -15836,6 +16123,7 @@ function AgentProjectDropdown({
15836
16123
  labels,
15837
16124
  i18n,
15838
16125
  previewMode = false,
16126
+ selectProjectDirectory,
15839
16127
  onProjectMissingChange,
15840
16128
  onProjectPathChange
15841
16129
  }) {
@@ -15848,12 +16136,13 @@ function AgentProjectDropdown({
15848
16136
  const userProjectApi = useMemo5(
15849
16137
  () => !previewMode && agentHostApi.userProjects ? {
15850
16138
  ...agentHostApi.userProjects,
15851
- selectDirectory: agentHostApi.workspace.selectDirectory
16139
+ selectDirectory: selectProjectDirectory ?? agentHostApi.workspace.selectDirectory
15852
16140
  } : null,
15853
16141
  [
15854
16142
  agentHostApi.userProjects,
15855
16143
  agentHostApi.workspace.selectDirectory,
15856
- previewMode
16144
+ previewMode,
16145
+ selectProjectDirectory
15857
16146
  ]
15858
16147
  );
15859
16148
  if (previewMode) {
@@ -15924,7 +16213,6 @@ function AgentProjectDropdown({
15924
16213
  ),
15925
16214
  selectedProjectPath: composerSettings.selectedProjectPath,
15926
16215
  service: agentHostApi.userProjects?.service ?? null,
15927
- showCreateProjectAction: true,
15928
16216
  onProjectMissingChange,
15929
16217
  onProjectPathChange
15930
16218
  }
@@ -18063,7 +18351,6 @@ function AgentComposer({
18063
18351
  promptImagesSupported = true,
18064
18352
  composerFocusRequestSequence = null,
18065
18353
  layoutMode = "dock",
18066
- showProjectSelector = true,
18067
18354
  labels,
18068
18355
  workspaceUserProjectI18n,
18069
18356
  onDraftContentChange,
@@ -18081,6 +18368,7 @@ function AgentComposer({
18081
18368
  onCapabilitySettingsRequest,
18082
18369
  onLinkAction,
18083
18370
  onRequestWorkspaceReferences = null,
18371
+ selectProjectDirectory,
18084
18372
  onRequestGitBranches = null,
18085
18373
  contextMentionProviders = EMPTY_CONTEXT_MENTION_PROVIDERS
18086
18374
  }) {
@@ -18652,6 +18940,22 @@ function AgentComposer({
18652
18940
  setFileMentionSuggestion(null);
18653
18941
  setIsPaletteOpen(false);
18654
18942
  }, [fileMentionSuggestion]);
18943
+ const clearActiveFileMentionTrigger = useCallback9(() => {
18944
+ if (!fileMentionSuggestion) {
18945
+ return;
18946
+ }
18947
+ const triggerLength = Math.max(
18948
+ fileMentionSuggestion.range.to - fileMentionSuggestion.range.from,
18949
+ fileMentionSuggestion.text.length
18950
+ );
18951
+ const nextDraft = triggerLength > 0 ? editorHandleRef.current?.replaceTextBeforeSelection(triggerLength, "") : null;
18952
+ if (nextDraft === null || nextDraft === void 0) {
18953
+ return;
18954
+ }
18955
+ draftPromptRef.current = nextDraft;
18956
+ setPaletteDraftPrompt(nextDraft);
18957
+ onDraftContentChange({ ...draftContent, prompt: nextDraft });
18958
+ }, [draftContent, fileMentionSuggestion, onDraftContentChange]);
18655
18959
  const closeOpenPalette = useCallback9(() => {
18656
18960
  if (showFileMentionPalette) {
18657
18961
  closeFileMentionPalette();
@@ -19063,6 +19367,7 @@ function AgentComposer({
19063
19367
  }, [applyReferencePickResult, onRequestWorkspaceReferences]);
19064
19368
  const handleOpenReferencesForEntity = useCallback9(
19065
19369
  (entity) => {
19370
+ clearActiveFileMentionTrigger();
19066
19371
  closeFileMentionPalette();
19067
19372
  if (!onRequestWorkspaceReferences) {
19068
19373
  return;
@@ -19072,6 +19377,7 @@ function AgentComposer({
19072
19377
  );
19073
19378
  },
19074
19379
  [
19380
+ clearActiveFileMentionTrigger,
19075
19381
  closeFileMentionPalette,
19076
19382
  applyReferencePickResult,
19077
19383
  onRequestWorkspaceReferences
@@ -19260,9 +19566,9 @@ function AgentComposer({
19260
19566
  const showEdgeGlow = layoutMode === "hero" && !inputDisabled;
19261
19567
  const showPromptTips = layoutMode === "hero" && promptTips.length > 0;
19262
19568
  const activePromptTip = showPromptTips ? promptTips[0] ?? null : null;
19263
- const showHeroProjectSelector = layoutMode === "hero" && showProjectSelector;
19264
- const showProjectRow = layoutMode === "hero" && (showHeroProjectSelector || activePromptTip);
19265
- const showProjectMissingProbe = !showProjectRow && showProjectSelector && Boolean(composerSettings.projectLocked) && selectedProjectPath !== "";
19569
+ const showHeroProjectSelector = layoutMode === "hero";
19570
+ const showProjectRow = layoutMode === "hero";
19571
+ const showProjectMissingProbe = !showProjectRow && Boolean(composerSettings.projectLocked) && selectedProjectPath !== "";
19266
19572
  const activePromptTipId = activePromptTip?.id ?? null;
19267
19573
  const activePromptTipText = activePromptTip ? `${labels.promptTipsPrefix}${activePromptTip.label} \xB7 ${activePromptTip.prompt}` : "";
19268
19574
  const rotatingPromptTips = activePromptTip && promptTips.length > 1 ? [...promptTips, activePromptTip] : activePromptTip ? [activePromptTip] : [];
@@ -19971,6 +20277,7 @@ function AgentComposer({
19971
20277
  projectLocked: labels.projectLocked,
19972
20278
  projectMissingDescription: labels.projectMissingDescription
19973
20279
  },
20280
+ selectProjectDirectory,
19974
20281
  onProjectMissingChange: setIsSelectedProjectMissing,
19975
20282
  onProjectPathChange
19976
20283
  }
@@ -20371,6 +20678,9 @@ function resolveAgentGUIHeroIconUrl(provider) {
20371
20678
  const normalizedProvider = normalizeManagedAgentProvider(provider);
20372
20679
  return MANAGED_AGENT_ICON_URLS[normalizedProvider] ?? MANAGED_AGENT_ICON_FALLBACK_URL;
20373
20680
  }
20681
+ function shouldEmphasizeEmptyHeroProvider(label) {
20682
+ return !/[\u3400-\u9fff]/u.test(label);
20683
+ }
20374
20684
  var fallbackWorkspaceFileReferenceCopy = {
20375
20685
  t(key, values) {
20376
20686
  return values ? `${key}:${JSON.stringify(values)}` : key;
@@ -20570,7 +20880,6 @@ function AgentGUINodeView({
20570
20880
  slashStatusLimits = [],
20571
20881
  slashStatusLimitsLoading = false,
20572
20882
  previewMode = false,
20573
- showProjectSelector = true,
20574
20883
  onAgentProviderLogin,
20575
20884
  actions,
20576
20885
  conversationRailCollapsed,
@@ -20585,6 +20894,7 @@ function AgentGUINodeView({
20585
20894
  workspaceUserProjectI18n,
20586
20895
  workspaceFileReferenceAdapter = null,
20587
20896
  onOpenConversationWindow,
20897
+ selectProjectDirectory,
20588
20898
  workspaceFileReferenceCopy = null,
20589
20899
  onRequestGitBranches = null,
20590
20900
  contextMentionProviders,
@@ -20916,7 +21226,6 @@ function AgentGUINodeView({
20916
21226
  labels,
20917
21227
  workspaceUserProjectI18n,
20918
21228
  uiLanguage,
20919
- showProjectSelector,
20920
21229
  previewMode,
20921
21230
  createConversationDisabled,
20922
21231
  openclawGateway,
@@ -20932,7 +21241,8 @@ function AgentGUINodeView({
20932
21241
  onCancelDeleteConversation: cancelDeleteConversation,
20933
21242
  onConfirmDeleteConversation: confirmDeleteConversation,
20934
21243
  onOpenProjectFiles: openProjectFiles,
20935
- onOpenConversationWindow: openConversationWindow
21244
+ onOpenConversationWindow: openConversationWindow,
21245
+ selectProjectDirectory
20936
21246
  }),
20937
21247
  [
20938
21248
  cancelDeleteConversation,
@@ -20951,7 +21261,7 @@ function AgentGUINodeView({
20951
21261
  requestDeleteConversation,
20952
21262
  retryOpenclawGateway,
20953
21263
  selectConversation,
20954
- showProjectSelector,
21264
+ selectProjectDirectory,
20955
21265
  toggleConversationPinned,
20956
21266
  uiLanguage,
20957
21267
  viewModel.activeConversationId,
@@ -21041,12 +21351,12 @@ function AgentGUINodeView({
21041
21351
  isAgentProviderReady,
21042
21352
  slashStatusLimits,
21043
21353
  slashStatusLimitsLoading,
21044
- showProjectSelector,
21045
21354
  onLinkAction,
21046
21355
  capabilityMenuState,
21047
21356
  onCapabilitySettingsRequest,
21048
21357
  onAgentProviderLogin,
21049
21358
  onRequestWorkspaceReferences: requestWorkspaceReferences,
21359
+ selectProjectDirectory,
21050
21360
  onRequestGitBranches,
21051
21361
  contextMentionProviders,
21052
21362
  workspaceAppIcons: effectiveWorkspaceAppIcons,
@@ -21157,12 +21467,12 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
21157
21467
  isAgentProviderReady,
21158
21468
  slashStatusLimits,
21159
21469
  slashStatusLimitsLoading,
21160
- showProjectSelector,
21161
21470
  onLinkAction,
21162
21471
  capabilityMenuState,
21163
21472
  onCapabilitySettingsRequest,
21164
21473
  onAgentProviderLogin,
21165
21474
  onRequestWorkspaceReferences,
21475
+ selectProjectDirectory,
21166
21476
  onRequestGitBranches,
21167
21477
  contextMentionProviders,
21168
21478
  workspaceAppIcons = EMPTY_WORKSPACE_APP_ICONS3
@@ -21601,6 +21911,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
21601
21911
  const stableRequestWorkspaceReferences = useOptionalStableEventCallback(
21602
21912
  onRequestWorkspaceReferences
21603
21913
  );
21914
+ const stableSelectProjectDirectory = useOptionalStableEventCallback(selectProjectDirectory);
21604
21915
  const stableRequestGitBranches = useOptionalStableEventCallback(onRequestGitBranches);
21605
21916
  const authLogin = useOptionalStableEventCallback(onAgentProviderLogin);
21606
21917
  const submitBottomDockInteractivePrompt = useCallback10(
@@ -21641,7 +21952,6 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
21641
21952
  composerFocusRequestSequence,
21642
21953
  isActive,
21643
21954
  promptImagesSupported: viewModel.promptImagesSupported,
21644
- showProjectSelector,
21645
21955
  isInterrupting: viewModel.isInterrupting,
21646
21956
  isSendingTurn: isComposerSending,
21647
21957
  isSubmittingPrompt: viewModel.isRespondingApproval,
@@ -21661,6 +21971,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
21661
21971
  onCapabilitySettingsRequest,
21662
21972
  onLinkAction: stableLinkAction,
21663
21973
  onRequestWorkspaceReferences: stableRequestWorkspaceReferences,
21974
+ selectProjectDirectory: stableSelectProjectDirectory,
21664
21975
  onRequestGitBranches: stableRequestGitBranches,
21665
21976
  contextMentionProviders
21666
21977
  }),
@@ -21685,7 +21996,6 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
21685
21996
  removeQueuedPrompt,
21686
21997
  sendQueuedPromptNext,
21687
21998
  showPromptImagesUnsupported,
21688
- showProjectSelector,
21689
21999
  showStopButton,
21690
22000
  slashStatus,
21691
22001
  submitDisabled,
@@ -21693,6 +22003,7 @@ var AgentGUIDetailPane = memo(function AgentGUIDetailPane2({
21693
22003
  submitPrompt,
21694
22004
  stableLinkAction,
21695
22005
  stableRequestGitBranches,
22006
+ stableSelectProjectDirectory,
21696
22007
  stableRequestWorkspaceReferences,
21697
22008
  updateComposerSettings,
21698
22009
  updateDraftContent,
@@ -22148,7 +22459,7 @@ function EmptyHeroTitle({
22148
22459
  providerLabel
22149
22460
  }) {
22150
22461
  const providerStart = providerLabel ? label.indexOf(providerLabel) : -1;
22151
- if (providerStart < 0) {
22462
+ if (!shouldEmphasizeEmptyHeroProvider(label) || providerStart < 0) {
22152
22463
  return /* @__PURE__ */ jsx29(Fragment8, { children: label });
22153
22464
  }
22154
22465
  const providerEnd = providerStart + providerLabel.length;
@@ -22284,7 +22595,7 @@ function syncAgentGUIConversationRailStore(store, next) {
22284
22595
  Object.assign(store, next);
22285
22596
  }
22286
22597
  function agentGUIConversationRailStoreSnapshotsEqual(current, next) {
22287
- 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.showProjectSelector === next.showProjectSelector && current.previewMode === next.previewMode && current.createConversationDisabled === next.createConversationDisabled && current.openclawGateway === next.openclawGateway && current.isCollapsed === next.isCollapsed && 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.onRemoveProject === next.onRemoveProject && current.onConfirmDeleteProjectConversations === next.onConfirmDeleteProjectConversations && current.onRequestDeleteConversation === next.onRequestDeleteConversation && current.onCancelDeleteConversation === next.onCancelDeleteConversation && current.onConfirmDeleteConversation === next.onConfirmDeleteConversation;
22598
+ 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.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;
22288
22599
  }
22289
22600
  var AgentGUIConversationRailStorePane = memo(
22290
22601
  function AgentGUIConversationRailStorePane2({
@@ -22393,7 +22704,6 @@ var AgentGUIConversationRailPane = memo(
22393
22704
  labels,
22394
22705
  workspaceUserProjectI18n,
22395
22706
  uiLanguage,
22396
- showProjectSelector,
22397
22707
  previewMode,
22398
22708
  createConversationDisabled,
22399
22709
  openclawGateway,
@@ -22405,6 +22715,7 @@ var AgentGUIConversationRailPane = memo(
22405
22715
  onToggleConversationPinned,
22406
22716
  onOpenProjectFiles,
22407
22717
  onOpenConversationWindow,
22718
+ selectProjectDirectory,
22408
22719
  onRemoveProject,
22409
22720
  onConfirmDeleteProjectConversations,
22410
22721
  onRequestDeleteConversation,
@@ -22580,7 +22891,7 @@ var AgentGUIConversationRailPane = memo(
22580
22891
  const normalizedProjectPath = normalizeConversationRailProjectPath(projectPath);
22581
22892
  const projectLabel = section.kind === "project" ? section.label : "";
22582
22893
  const isProjectSection = section.kind === "project";
22583
- const showProjectRailHeader = showProjectSelector && !conversationQuery.trim() && section.kind !== "pinned" && (sectionIndex === 0 || groupedConversations[sectionIndex - 1]?.kind === "pinned");
22894
+ const showProjectRailHeader = !conversationQuery.trim() && section.kind !== "pinned" && (sectionIndex === 0 || groupedConversations[sectionIndex - 1]?.kind === "pinned");
22584
22895
  const isSectionCollapsed = isProjectSection && collapsedProjectSectionIds.has(section.id);
22585
22896
  const projectConversationCount = normalizedProjectPath ? projectConversationCountsByPath.get(normalizedProjectPath) ?? 0 : 0;
22586
22897
  return /* @__PURE__ */ jsxs15(Fragment7, { children: [
@@ -22588,6 +22899,7 @@ var AgentGUIConversationRailPane = memo(
22588
22899
  AgentGUIProjectRailHeader,
22589
22900
  {
22590
22901
  labels,
22902
+ selectProjectDirectory,
22591
22903
  workspaceUserProjectI18n
22592
22904
  }
22593
22905
  ) : null,
@@ -22805,7 +23117,7 @@ var AgentGUIConversationRailSection = memo(
22805
23117
  /* @__PURE__ */ jsx29(
22806
23118
  TooltipContent3,
22807
23119
  {
22808
- side: "right",
23120
+ side: "top",
22809
23121
  sideOffset: 6,
22810
23122
  className: AgentGUINode_styles_default.conversationSectionActionTooltip,
22811
23123
  children: createConversationLabel
@@ -23120,6 +23432,7 @@ var AgentGUIConversationRailItem = memo(
23120
23432
  );
23121
23433
  function AgentGUIProjectRailHeader({
23122
23434
  labels,
23435
+ selectProjectDirectory,
23123
23436
  workspaceUserProjectI18n
23124
23437
  }) {
23125
23438
  "use memo";
@@ -23127,9 +23440,13 @@ function AgentGUIProjectRailHeader({
23127
23440
  const userProjectApi = useMemo10(
23128
23441
  () => agentHostApi.userProjects ? {
23129
23442
  ...agentHostApi.userProjects,
23130
- selectDirectory: agentHostApi.workspace.selectDirectory
23443
+ selectDirectory: selectProjectDirectory ?? agentHostApi.workspace.selectDirectory
23131
23444
  } : null,
23132
- [agentHostApi.userProjects, agentHostApi.workspace.selectDirectory]
23445
+ [
23446
+ agentHostApi.userProjects,
23447
+ agentHostApi.workspace.selectDirectory,
23448
+ selectProjectDirectory
23449
+ ]
23133
23450
  );
23134
23451
  return /* @__PURE__ */ jsxs15("div", { className: AgentGUINode_styles_default.projectRailHeader, children: [
23135
23452
  /* @__PURE__ */ jsx29("div", { className: AgentGUINode_styles_default.projectRailTitle, children: /* @__PURE__ */ jsx29("span", { children: workspaceUserProjectI18n.tFirst(["projectSelect.projectLabel"]) }) }),
@@ -23925,11 +24242,11 @@ function composerOverridesByProviderEqual(left, right) {
23925
24242
  return true;
23926
24243
  }
23927
24244
  function areAgentGUINodePropsEqual(previous, next) {
23928
- return previous.nodeId === next.nodeId && previous.workspaceId === next.workspaceId && previous.currentUserId === next.currentUserId && previous.workspacePath === next.workspacePath && previous.workspaceFileReferenceAdapter === next.workspaceFileReferenceAdapter && previous.referenceSourceAggregator === next.referenceSourceAggregator && 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.onCapabilitySettingsRequest === next.onCapabilitySettingsRequest && previous.onAgentProviderLogin === next.onAgentProviderLogin && previous.onClose === next.onClose && previous.onResize === next.onResize && previous.onUpdateNode === next.onUpdateNode && previous.onOpenConversationWindow === next.onOpenConversationWindow && previous.isMaximized === next.isMaximized && previous.isMuted === next.isMuted && previous.onMinimize === next.onMinimize && previous.onToggleMaximize === next.onToggleMaximize && previous.onShowMessage === next.onShowMessage && workspaceAgentProbeRenderStateEqualsForProvider(
24245
+ return previous.nodeId === next.nodeId && previous.workspaceId === next.workspaceId && previous.currentUserId === next.currentUserId && previous.workspacePath === next.workspacePath && previous.workspaceFileReferenceAdapter === next.workspaceFileReferenceAdapter && previous.selectProjectDirectory === next.selectProjectDirectory && previous.referenceSourceAggregator === next.referenceSourceAggregator && 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.onCapabilitySettingsRequest === next.onCapabilitySettingsRequest && previous.onAgentProviderLogin === next.onAgentProviderLogin && previous.onClose === next.onClose && previous.onResize === next.onResize && previous.onUpdateNode === next.onUpdateNode && previous.onOpenConversationWindow === next.onOpenConversationWindow && previous.isMaximized === next.isMaximized && previous.isMuted === next.isMuted && previous.onMinimize === next.onMinimize && previous.onToggleMaximize === next.onToggleMaximize && previous.onShowMessage === next.onShowMessage && workspaceAgentProbeRenderStateEqualsForProvider(
23929
24246
  previous.workspaceAgentProbes,
23930
24247
  next.workspaceAgentProbes,
23931
24248
  previous.state.provider
23932
- ) && previous.onAgentProbeDemandChange === next.onAgentProbeDemandChange && 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.showProjectSelector === next.showProjectSelector && previous.composerFocusRequestSequence === next.composerFocusRequestSequence && previous.newConversationRequestSequence === next.newConversationRequestSequence && previous.openSessionRequest === next.openSessionRequest && previous.prefillPromptRequest === next.prefillPromptRequest;
24249
+ ) && previous.onAgentProbeDemandChange === next.onAgentProbeDemandChange && 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;
23933
24250
  }
23934
24251
  var AgentGUINode = memo2(function AgentGUINode2({
23935
24252
  nodeId,
@@ -23938,6 +24255,7 @@ var AgentGUINode = memo2(function AgentGUINode2({
23938
24255
  workspacePath,
23939
24256
  workspaceFileReferenceAdapter = null,
23940
24257
  onRequestGitBranches = null,
24258
+ selectProjectDirectory,
23941
24259
  referenceSourceAggregator = null,
23942
24260
  resolveMentionReferenceTarget = null,
23943
24261
  resolveWorkspaceReferenceInitialTarget = null,
@@ -23963,7 +24281,6 @@ var AgentGUINode = memo2(function AgentGUINode2({
23963
24281
  newConversationRequestSequence = null,
23964
24282
  openSessionRequest = null,
23965
24283
  prefillPromptRequest = null,
23966
- showProjectSelector = true,
23967
24284
  isMuted = false,
23968
24285
  onMinimize,
23969
24286
  onToggleMaximize,
@@ -24685,7 +25002,6 @@ var AgentGUINode = memo2(function AgentGUINode2({
24685
25002
  slashStatusLimits,
24686
25003
  slashStatusLimitsLoading: workspaceAgentProbes?.isLoadingUsage ?? false,
24687
25004
  previewMode,
24688
- showProjectSelector,
24689
25005
  onLinkAction: handleLinkAction,
24690
25006
  capabilityMenuState,
24691
25007
  onCapabilitySettingsRequest,
@@ -24708,6 +25024,7 @@ var AgentGUINode = memo2(function AgentGUINode2({
24708
25024
  workspaceFileReferenceAdapter,
24709
25025
  onOpenConversationWindow,
24710
25026
  onRequestGitBranches,
25027
+ selectProjectDirectory,
24711
25028
  referenceSourceAggregator,
24712
25029
  resolveMentionReferenceTarget,
24713
25030
  resolveWorkspaceReferenceInitialTarget,