@tutti-os/agent-gui 0.0.126 → 0.0.127

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 (53) hide show
  1. package/dist/{AgentGUI-CKk3WQrn.d.ts → AgentGUI-DprRUk8h.d.ts} +9 -2
  2. package/dist/{AgentRichTextReadonly-KOUZGF5Q.js → AgentRichTextReadonly-SPIPM3UM.js} +5 -5
  3. package/dist/agent-conversation/index.d.ts +1 -1
  4. package/dist/agent-conversation/index.js +7 -7
  5. package/dist/agent-gui.d.ts +2 -2
  6. package/dist/agent-gui.js +14 -14
  7. package/dist/agent-message-center/index.js +6 -6
  8. package/dist/{agentGuiNodeTypes-DedIWrEI.d.ts → agentGuiNodeTypes-5TL1hyCN.d.ts} +8 -2
  9. package/dist/app/renderer/agentactivity.css +10 -1
  10. package/dist/{chunk-BDWZUA3L.js → chunk-54GR2G3U.js} +4 -4
  11. package/dist/{chunk-2JFMGOHU.js → chunk-D5CIV4IB.js} +2 -2
  12. package/dist/chunk-D5CIV4IB.js.map +1 -0
  13. package/dist/{chunk-G3XB4FAQ.js → chunk-EG7IIFNL.js} +3 -3
  14. package/dist/{chunk-4CACBXIB.js → chunk-JE2DXS4U.js} +2 -2
  15. package/dist/{chunk-6RMVLH3G.js → chunk-JVISXD4K.js} +2 -2
  16. package/dist/{chunk-F2Z7P7BB.js → chunk-JWB5Z5GS.js} +4 -4
  17. package/dist/{chunk-QDNOOAAS.js → chunk-LWJITLCI.js} +2 -2
  18. package/dist/{chunk-2ZVXN2Z7.js → chunk-T2CHVUXH.js} +7 -1
  19. package/dist/chunk-T2CHVUXH.js.map +1 -0
  20. package/dist/{chunk-ADQENNSG.js → chunk-WB3KV4VH.js} +3 -3
  21. package/dist/{chunk-CO6XO5A2.js → chunk-WKFMSABH.js} +83 -5
  22. package/dist/chunk-WKFMSABH.js.map +1 -0
  23. package/dist/{chunk-RB6ZYQBA.js → chunk-WKYMLLHT.js} +2 -2
  24. package/dist/{chunk-PRE4IT6E.js → chunk-YJKTYMF4.js} +4 -4
  25. package/dist/{chunk-X22KJXVG.js → chunk-YWKS4ESK.js} +2 -2
  26. package/dist/{chunk-QWKJ646Z.js → chunk-ZXHXR2KT.js} +1044 -813
  27. package/dist/chunk-ZXHXR2KT.js.map +1 -0
  28. package/dist/context-mention-palette/index.js +7 -7
  29. package/dist/i18n/index.d.ts +6 -0
  30. package/dist/i18n/index.js +2 -2
  31. package/dist/index.d.ts +4 -4
  32. package/dist/index.js +14 -14
  33. package/dist/index.js.map +1 -1
  34. package/dist/mention-search.js +5 -5
  35. package/dist/workbench/contribution.js +3 -3
  36. package/dist/workbench/index.js +3 -3
  37. package/dist/workbench/sessionTitle.js +2 -2
  38. package/package.json +14 -14
  39. package/dist/chunk-2JFMGOHU.js.map +0 -1
  40. package/dist/chunk-2ZVXN2Z7.js.map +0 -1
  41. package/dist/chunk-CO6XO5A2.js.map +0 -1
  42. package/dist/chunk-QWKJ646Z.js.map +0 -1
  43. /package/dist/{AgentRichTextReadonly-KOUZGF5Q.js.map → AgentRichTextReadonly-SPIPM3UM.js.map} +0 -0
  44. /package/dist/{chunk-BDWZUA3L.js.map → chunk-54GR2G3U.js.map} +0 -0
  45. /package/dist/{chunk-G3XB4FAQ.js.map → chunk-EG7IIFNL.js.map} +0 -0
  46. /package/dist/{chunk-4CACBXIB.js.map → chunk-JE2DXS4U.js.map} +0 -0
  47. /package/dist/{chunk-6RMVLH3G.js.map → chunk-JVISXD4K.js.map} +0 -0
  48. /package/dist/{chunk-F2Z7P7BB.js.map → chunk-JWB5Z5GS.js.map} +0 -0
  49. /package/dist/{chunk-QDNOOAAS.js.map → chunk-LWJITLCI.js.map} +0 -0
  50. /package/dist/{chunk-ADQENNSG.js.map → chunk-WB3KV4VH.js.map} +0 -0
  51. /package/dist/{chunk-RB6ZYQBA.js.map → chunk-WKYMLLHT.js.map} +0 -0
  52. /package/dist/{chunk-PRE4IT6E.js.map → chunk-YJKTYMF4.js.map} +0 -0
  53. /package/dist/{chunk-X22KJXVG.js.map → chunk-YWKS4ESK.js.map} +0 -0
@@ -12,7 +12,7 @@ import {
12
12
  resolveAgentGuiSessionProviderFlatIconUrl,
13
13
  resolveNextAgentGUIConversationRailWidthPx,
14
14
  shouldAutoCollapseAgentGUIConversationRail
15
- } from "./chunk-G3XB4FAQ.js";
15
+ } from "./chunk-EG7IIFNL.js";
16
16
  import {
17
17
  AGENT_PROVIDERS,
18
18
  AGENT_PROVIDER_LABEL,
@@ -28,7 +28,7 @@ import {
28
28
  resolveAgentGUIFirstUserMessageDisplayPrompt,
29
29
  resolveAgentGUIProviderDisplayLabel,
30
30
  resolveAgentGUIProviderIdentity
31
- } from "./chunk-X22KJXVG.js";
31
+ } from "./chunk-YWKS4ESK.js";
32
32
  import {
33
33
  resolveAgentGuiWorkbenchProviderLabel
34
34
  } from "./chunk-R2ZADXRB.js";
@@ -63,7 +63,7 @@ import {
63
63
  toLocalShortDateTime,
64
64
  updateAgentComposerDraft,
65
65
  useProjectedAgentConversation
66
- } from "./chunk-CO6XO5A2.js";
66
+ } from "./chunk-WKFMSABH.js";
67
67
  import {
68
68
  agentRichTextContentToPromptText,
69
69
  createAgentRichTextInputExtensions,
@@ -73,7 +73,7 @@ import {
73
73
  plainTextToAgentRichTextInlineContent,
74
74
  skillDescriptionForDisplay,
75
75
  skillTriggerForPrefix
76
- } from "./chunk-RB6ZYQBA.js";
76
+ } from "./chunk-WKYMLLHT.js";
77
77
  import {
78
78
  openAgentEnvPanel
79
79
  } from "./chunk-VMQNG2KI.js";
@@ -85,7 +85,7 @@ import {
85
85
  AgentFileMentionPalette,
86
86
  agentMentionItemKey,
87
87
  isAgentMentionItemDisabled
88
- } from "./chunk-BDWZUA3L.js";
88
+ } from "./chunk-54GR2G3U.js";
89
89
  import {
90
90
  normalizeAgentGUIAgents,
91
91
  projectAgentGUIAgentsToInternalTargets
@@ -96,7 +96,7 @@ import {
96
96
  DEFAULT_AGENT_MENTION_FILTER,
97
97
  agentGuiScheduler,
98
98
  buildWorkspaceAgentActivityListViewModel
99
- } from "./chunk-PRE4IT6E.js";
99
+ } from "./chunk-YJKTYMF4.js";
100
100
  import {
101
101
  AGENT_RICH_TEXT_CARET_ANCHOR,
102
102
  createAgentSessionMarkdownLink,
@@ -107,7 +107,7 @@ import {
107
107
  mentionItemToAttrs,
108
108
  normalizeAgentSessionMentionTitle,
109
109
  parseMentionItemFromHref
110
- } from "./chunk-QDNOOAAS.js";
110
+ } from "./chunk-LWJITLCI.js";
111
111
  import {
112
112
  AgentInteractivePromptSurface,
113
113
  PLAN_IMPLEMENTATION_ACTION_FEEDBACK,
@@ -117,7 +117,7 @@ import {
117
117
  dispatchAgentPlanPromptAction,
118
118
  latestPlanTurnId,
119
119
  planImplementationPromptFromPlanTurn
120
- } from "./chunk-F2Z7P7BB.js";
120
+ } from "./chunk-JWB5Z5GS.js";
121
121
  import {
122
122
  useEngineSelector
123
123
  } from "./chunk-2RQM7PJN.js";
@@ -126,7 +126,7 @@ import {
126
126
  ZoomableImage,
127
127
  normalizeAgentApprovalPurpose,
128
128
  resolveWorkspaceLinkAction
129
- } from "./chunk-ADQENNSG.js";
129
+ } from "./chunk-WB3KV4VH.js";
130
130
  import {
131
131
  AgentTargetPresentationProvider,
132
132
  cn,
@@ -144,7 +144,7 @@ import {
144
144
  useAgentHostApi,
145
145
  useOptionalAgentActivityRuntime,
146
146
  useOptionalAgentHostApi
147
- } from "./chunk-2JFMGOHU.js";
147
+ } from "./chunk-D5CIV4IB.js";
148
148
  import {
149
149
  MANAGED_AGENT_ICON_FALLBACK_URL,
150
150
  MANAGED_AGENT_ICON_URLS,
@@ -154,7 +154,7 @@ import {
154
154
  AgentGuiI18nProvider,
155
155
  translate,
156
156
  useTranslation
157
- } from "./chunk-6RMVLH3G.js";
157
+ } from "./chunk-JVISXD4K.js";
158
158
  import {
159
159
  isBetaAgentProvider,
160
160
  normalizeManagedAgentProvider
@@ -174,7 +174,7 @@ import { memo as memo15 } from "react";
174
174
  import { TooltipProvider as TooltipProvider5 } from "@tutti-os/ui-system";
175
175
 
176
176
  // agent-gui/agentGuiNode/AgentGUINode.tsx
177
- import { memo as memo14, useCallback as useCallback57, useEffect as useEffect39, useMemo as useMemo41 } from "react";
177
+ import { memo as memo14, useCallback as useCallback57, useEffect as useEffect38, useMemo as useMemo41 } from "react";
178
178
  import { createWorkspaceUserProjectI18nRuntime } from "@tutti-os/workspace-user-project/i18n";
179
179
  import { createWorkspaceFileManagerI18nRuntime } from "@tutti-os/workspace-file-manager";
180
180
  import { useReferenceProvenanceFilterCatalog } from "@tutti-os/workspace-file-reference/react";
@@ -2029,7 +2029,7 @@ import {
2029
2029
  selectEngineSessionIsRespondingToInteraction as selectEngineSessionIsRespondingToInteraction2,
2030
2030
  selectWorkspaceAgentConsumerSessions as selectWorkspaceAgentConsumerSessions2
2031
2031
  } from "@tutti-os/agent-activity-core";
2032
- import { useCallback as useCallback27, useEffect as useEffect14, useMemo as useMemo18, useRef as useRef18 } from "react";
2032
+ import { useCallback as useCallback27, useEffect as useEffect13, useMemo as useMemo18, useRef as useRef19 } from "react";
2033
2033
 
2034
2034
  // host/agentHostAccountStore.ts
2035
2035
  import { create as create2 } from "zustand";
@@ -2929,7 +2929,8 @@ function agentGUIConversationProjectSummaryFromProject(matchedProject) {
2929
2929
  const summary = {
2930
2930
  id: matchedProject.id,
2931
2931
  path: matchedProject.path,
2932
- label: resolveWorkspaceUserProjectDisplayLabel(matchedProject)
2932
+ label: resolveWorkspaceUserProjectDisplayLabel(matchedProject),
2933
+ pinnedAtUnixMs: matchedProject.pinnedAtUnixMs
2933
2934
  };
2934
2935
  if (matchedProject.sectionKey !== void 0) {
2935
2936
  summary.sectionKey = matchedProject.sectionKey;
@@ -2975,9 +2976,11 @@ function cachedAgentGUIConversationProjectSummary(summary) {
2975
2976
  summary.id,
2976
2977
  summary.path,
2977
2978
  summary.label,
2979
+ summary.sectionKey ?? "",
2978
2980
  summary.createdAtUnixMs ?? "",
2979
2981
  summary.updatedAtUnixMs ?? "",
2980
- summary.lastUsedAtUnixMs ?? ""
2982
+ summary.lastUsedAtUnixMs ?? "",
2983
+ summary.pinnedAtUnixMs ?? ""
2981
2984
  ].join("");
2982
2985
  const cached = agentGUIConversationProjectSummaryCache.get(key);
2983
2986
  if (cached) {
@@ -3901,12 +3904,34 @@ function composerDefaultsPatchFromSettings(touched, finalSettings) {
3901
3904
  for (const field of rememberComposerDefaultsFields) {
3902
3905
  if (touched[field] === void 0) continue;
3903
3906
  const touchedValue = normalizeOptionalText(touched[field]);
3907
+ if (touchedValue === null) continue;
3904
3908
  const finalValue = normalizeOptionalText(finalSettings[field]);
3905
- if (touchedValue !== null && finalValue === null) continue;
3909
+ if (finalValue === null) continue;
3906
3910
  patch[field] = finalValue;
3907
3911
  }
3908
3912
  return Object.keys(patch).length > 0 ? patch : null;
3909
3913
  }
3914
+ function overlayComposerDefaults(base, optimistic) {
3915
+ if (!optimistic) return base;
3916
+ const result = { ...base };
3917
+ for (const field of rememberComposerDefaultsFields) {
3918
+ const value = normalizeOptionalText(optimistic[field]);
3919
+ if (value !== null) {
3920
+ Object.assign(result, { [field]: value });
3921
+ }
3922
+ }
3923
+ return result;
3924
+ }
3925
+ function withoutAcknowledgedComposerDefaults(settings, acknowledged) {
3926
+ const result = { ...settings };
3927
+ for (const field of rememberComposerDefaultsFields) {
3928
+ const acknowledgedValue = normalizeOptionalText(acknowledged[field]);
3929
+ if (acknowledgedValue !== null && normalizeOptionalText(result[field]) === acknowledgedValue) {
3930
+ delete result[field];
3931
+ }
3932
+ }
3933
+ return result;
3934
+ }
3910
3935
  function composerTargetDataFromProviderTarget(input) {
3911
3936
  const agentTargetId = normalizeOptionalText(input.target.agentTargetId) ?? input.target.targetId;
3912
3937
  const currentAgentTargetId = normalizeOptionalText(
@@ -4186,31 +4211,6 @@ function cloneComposerSettings(settings) {
4186
4211
  function sameComposerSettings(left, right) {
4187
4212
  return (left?.model ?? null) === (right?.model ?? null) && (left?.reasoningEffort ?? null) === (right?.reasoningEffort ?? null) && (left?.speed ?? null) === (right?.speed ?? null) && Boolean(left?.planMode) === Boolean(right?.planMode) && (left?.browserUse ?? true) === (right?.browserUse ?? true) && (left?.computerUse ?? true) === (right?.computerUse ?? true) && (left?.permissionModeId ?? null) === (right?.permissionModeId ?? null);
4188
4213
  }
4189
- function buildNodeDefaultComposerSettings(data, options) {
4190
- const composerOverrides = nodeComposerOverridesForProvider(data) ?? {};
4191
- return {
4192
- model: normalizeOptionalText(composerOverrides.model),
4193
- reasoningEffort: normalizeOptionalText(
4194
- composerOverrides.reasoningEffort
4195
- ) ?? options?.defaultReasoningEffort ?? null,
4196
- speed: normalizeOptionalText(
4197
- composerOverrides.speed
4198
- ) ?? options?.defaultSpeed ?? null,
4199
- planMode: Boolean(composerOverrides.planMode),
4200
- browserUse: composerOverrides.browserUse ?? true,
4201
- computerUse: composerOverrides.computerUse ?? true,
4202
- permissionModeId: normalizePermissionModeId(
4203
- composerOverrides.permissionModeId
4204
- )
4205
- };
4206
- }
4207
- function nodeComposerOverridesForProvider(data) {
4208
- const agentTargetId = normalizeOptionalText(data.agentTargetId);
4209
- if (agentTargetId) {
4210
- return data.composerOverridesByAgentTargetId?.[agentTargetId] ?? null;
4211
- }
4212
- return data.composerOverridesByProvider?.[data.provider] ?? data.composerOverrides ?? null;
4213
- }
4214
4214
  function permissionModeOptions(provider, permissionConfig) {
4215
4215
  if (!permissionConfig?.configurable) {
4216
4216
  return [];
@@ -4221,37 +4221,6 @@ function permissionModeOptions(provider, permissionConfig) {
4221
4221
  description: permissionModeDescription(provider, mode)
4222
4222
  }));
4223
4223
  }
4224
- function nodeDataFromComposerSettings(current, settings) {
4225
- const composerOverrides = {
4226
- model: normalizeOptionalText(settings.model),
4227
- reasoningEffort: normalizeOptionalText(settings.reasoningEffort),
4228
- speed: normalizeOptionalText(settings.speed),
4229
- planMode: Boolean(settings.planMode),
4230
- // Raw passthrough (no Boolean coercion): undefined means "default on", so
4231
- // only an explicit false persists as an opt-out.
4232
- browserUse: settings.browserUse,
4233
- computerUse: settings.computerUse,
4234
- permissionModeId: normalizePermissionModeId(settings.permissionModeId)
4235
- };
4236
- const agentTargetId = normalizeOptionalText(current.agentTargetId);
4237
- if (agentTargetId) {
4238
- return {
4239
- ...current,
4240
- composerOverridesByAgentTargetId: {
4241
- ...current.composerOverridesByAgentTargetId ?? {},
4242
- [agentTargetId]: composerOverrides
4243
- }
4244
- };
4245
- }
4246
- return {
4247
- ...current,
4248
- composerOverrides,
4249
- composerOverridesByProvider: {
4250
- ...current.composerOverridesByProvider ?? {},
4251
- [current.provider]: composerOverrides
4252
- }
4253
- };
4254
- }
4255
4224
  function permissionModeLabel(provider, option) {
4256
4225
  const providerKey = `agentHost.agentGui.permissionModes.${provider}.${option.id}.label`;
4257
4226
  const providerLabel = translate(providerKey);
@@ -4297,141 +4266,9 @@ function nodeDefaultDraftKey(agentProvider, agentTargetId) {
4297
4266
  function readNodeDefaultDraftSettings(input) {
4298
4267
  const agentTargetId = normalizeOptionalText(input.data.agentTargetId);
4299
4268
  if (agentTargetId) {
4300
- return input.drafts[nodeDefaultDraftKey(input.data.provider, agentTargetId)] ?? buildNodeDefaultComposerSettings(input.data, {
4301
- defaultReasoningEffort: input.defaultReasoningEffort,
4302
- defaultSpeed: input.defaultSpeed
4303
- });
4269
+ return input.drafts[nodeDefaultDraftKey(input.data.provider, agentTargetId)] ?? {};
4304
4270
  }
4305
- return input.drafts[nodeDefaultDraftKey(input.data.provider)] ?? input.drafts[NODE_DEFAULT_DRAFT_KEY] ?? buildNodeDefaultComposerSettings(input.data, {
4306
- defaultReasoningEffort: input.defaultReasoningEffort,
4307
- defaultSpeed: input.defaultSpeed
4308
- });
4309
- }
4310
-
4311
- // agent-gui/agentGuiNode/controller/agentGuiController.composerPresentation.ts
4312
- function composerTargetDataFromNodeData(data) {
4313
- const agentTargetId = normalizeOptionalText(data.agentTargetId);
4314
- return {
4315
- agentTargetId,
4316
- provider: data.provider,
4317
- targetId: agentTargetId ?? `local:${data.provider}`,
4318
- data
4319
- };
4320
- }
4321
- function composerTargetDataForConversation(input) {
4322
- if (input.activeConversationId === null) {
4323
- return input.selectedTarget;
4324
- }
4325
- if (input.optimisticTarget?.agentSessionId === input.activeConversationId && !nodeDataMatchesComposerTarget(input.data, input.optimisticTarget.target)) {
4326
- return input.optimisticTarget.target;
4327
- }
4328
- return composerTargetDataFromNodeData(input.data);
4329
- }
4330
- function nodeDataMatchesComposerTarget(data, target) {
4331
- return data.provider === target.provider && normalizeOptionalText(data.agentTargetId) === target.agentTargetId;
4332
- }
4333
- function isForegroundModelOptionsLoading(input) {
4334
- return input.supportsModel && input.modelOptionsLoading === true && (input.selection === null || input.selection.options.length === 0);
4335
- }
4336
- function effectiveComposerSettingsFromOptions(options) {
4337
- const settings = options?.effectiveSettings;
4338
- if (!settings) {
4339
- return null;
4340
- }
4341
- return {
4342
- model: normalizeOptionalText(settings.model),
4343
- reasoningEffort: normalizeOptionalText(
4344
- settings.reasoningEffort
4345
- ),
4346
- speed: normalizeOptionalText(settings.speed),
4347
- planMode: settings.planMode ?? void 0,
4348
- permissionModeId: normalizeOptionalText(settings.permissionModeId)
4349
- };
4350
- }
4351
- function composerOptionValues(options) {
4352
- return new Set(options.map((option) => option.value));
4353
- }
4354
- function sanitizeComposerSettingsForOptions(settings, options) {
4355
- if (!options) {
4356
- return settings;
4357
- }
4358
- const modelValues = composerOptionValues(options.models);
4359
- const reasoningValues = composerOptionValues(options.reasoningEfforts);
4360
- const speedValues = composerOptionValues(options.speeds ?? []);
4361
- const permissionValues = new Set(
4362
- options.permissionConfig?.modes.map((mode) => mode.id) ?? []
4363
- );
4364
- const model = normalizeOptionalText(settings.model);
4365
- const reasoningEffort = normalizeOptionalText(settings.reasoningEffort);
4366
- const speed = normalizeOptionalText(settings.speed);
4367
- const permissionModeId = normalizeOptionalText(settings.permissionModeId);
4368
- const modelReasoningSelection = reasoningSelectionForModelFromComposerOptions(
4369
- options,
4370
- reasoningEffort,
4371
- model
4372
- );
4373
- return {
4374
- ...settings,
4375
- model: options.behavior?.modelOptionsAuthoritative === true && model && modelValues.size > 0 && !modelValues.has(model) ? null : model,
4376
- reasoningEffort: modelReasoningSelection !== null ? modelReasoningSelection.currentValue : options.reasoningConfigurable !== true ? null : reasoningEffort && reasoningValues.size > 0 && !reasoningValues.has(reasoningEffort) ? null : reasoningEffort,
4377
- speed: speed && speedValues.size > 0 && !speedValues.has(speed) ? null : speed,
4378
- permissionModeId: permissionModeId && permissionValues.size > 0 && !permissionValues.has(permissionModeId) ? null : permissionModeId
4379
- };
4380
- }
4381
- function sanitizeComposerSettingsForTarget(input) {
4382
- if (!input.target.agentTargetId) {
4383
- return input.settings;
4384
- }
4385
- return sanitizeComposerSettingsForOptions(input.settings, input.options);
4386
- }
4387
- function resolvePresentedComposerSettings(input) {
4388
- const layers = [
4389
- input.sessionSettings,
4390
- input.optimisticSettings,
4391
- input.preloadedSettings,
4392
- input.homeSettings
4393
- ];
4394
- const firstText = (field) => {
4395
- for (const layer of layers) {
4396
- const value = normalizeOptionalText(layer?.[field]);
4397
- if (value) {
4398
- return value;
4399
- }
4400
- }
4401
- return null;
4402
- };
4403
- const firstBoolean = (field, fallback) => {
4404
- for (const layer of layers) {
4405
- const value = layer?.[field];
4406
- if (typeof value === "boolean") {
4407
- return value;
4408
- }
4409
- }
4410
- return fallback;
4411
- };
4412
- return {
4413
- model: firstText("model"),
4414
- reasoningEffort: firstText(
4415
- "reasoningEffort"
4416
- ),
4417
- speed: firstText("speed"),
4418
- planMode: firstBoolean("planMode", false),
4419
- browserUse: firstBoolean("browserUse", true),
4420
- computerUse: firstBoolean("computerUse", true),
4421
- permissionModeId: firstText("permissionModeId")
4422
- };
4423
- }
4424
- function resolveComposerSettingsPresentation(input) {
4425
- const sessionSettings = input.active && (input.sessionSettings != null || Boolean(input.permissionModeId)) ? {
4426
- ...input.sessionSettings ?? {},
4427
- permissionModeId: normalizeOptionalText(input.permissionModeId) ?? normalizeOptionalText(input.sessionSettings?.permissionModeId)
4428
- } : null;
4429
- return resolvePresentedComposerSettings({
4430
- sessionSettings,
4431
- optimisticSettings: input.active ? input.optimisticSettings ?? null : input.homeSettings,
4432
- preloadedSettings: effectiveComposerSettingsFromOptions(input.options),
4433
- homeSettings: input.homeSettings
4434
- });
4271
+ return input.drafts[nodeDefaultDraftKey(input.data.provider)] ?? input.drafts[NODE_DEFAULT_DRAFT_KEY] ?? {};
4435
4272
  }
4436
4273
 
4437
4274
  // agent-gui/agentGuiNode/controller/agentGuiController.diagnostics.ts
@@ -4944,20 +4781,6 @@ function useAgentConversationMessagePaging(input) {
4944
4781
  function createPendingOptimisticTurnId(clientSubmitId) {
4945
4782
  return `pending:${clientSubmitId}`;
4946
4783
  }
4947
- function resolveSameProviderActiveSessionModel(input) {
4948
- const agentSessionId = normalizeOptionalText(input.agentSessionId);
4949
- if (agentSessionId === null) {
4950
- return null;
4951
- }
4952
- const runtimeSession = input.runtime.getSnapshot(input.workspaceId).sessions.find(
4953
- (candidate) => candidate.agentSessionId.trim() === agentSessionId
4954
- ) ?? null;
4955
- const activeProvider = normalizeOptionalText(runtimeSession?.provider) ?? normalizeOptionalText(input.activeProvider);
4956
- if (activeProvider !== input.provider) {
4957
- return null;
4958
- }
4959
- return normalizeOptionalText(input.sessionState?.settings?.model) ?? normalizeOptionalText(runtimeSession?.model);
4960
- }
4961
4784
  function normalizeAgentGUIOpenSessionRequest(request) {
4962
4785
  const agentSessionId = request?.agentSessionId.trim() ?? "";
4963
4786
  if (!agentSessionId || typeof request?.sequence !== "number") {
@@ -5035,13 +4858,8 @@ function resolvePromptImageSelectedModel(input) {
5035
4858
  defaultReasoningEffort: input.defaultReasoningEffort,
5036
4859
  drafts: input.draftSettingsBySessionId
5037
4860
  });
5038
- const targetSafeNodeDefaultSettings = input.activeConversationId === null ? sanitizeComposerSettingsForTarget({
5039
- settings: storedNodeDefaultSettings,
5040
- target: input.selectedComposerTargetData,
5041
- options: input.providerComposerOptions
5042
- }) : storedNodeDefaultSettings;
5043
4861
  const homeComposerSettings = resolveEffectiveComposerSettings({
5044
- settings: targetSafeNodeDefaultSettings
4862
+ settings: storedNodeDefaultSettings
5045
4863
  });
5046
4864
  const activeConversationDraftSettings = input.activeConversationId ? input.draftSettingsBySessionId[input.activeConversationId] ?? null : null;
5047
4865
  const defaultConversationDraftSettings = {
@@ -5221,7 +5039,7 @@ function normalizeInteractiveToolName(toolName) {
5221
5039
  function areAgentGUIUserProjectsEqual(left, right) {
5222
5040
  return left.length === right.length && left.every((project, index) => {
5223
5041
  const candidate = right[index];
5224
- return candidate !== void 0 && project.id === candidate.id && project.path === candidate.path && project.label === candidate.label && project.sectionKey === candidate.sectionKey;
5042
+ return candidate !== void 0 && project.id === candidate.id && project.path === candidate.path && project.label === candidate.label && project.sectionKey === candidate.sectionKey && project.pinnedAtUnixMs === candidate.pinnedAtUnixMs;
5225
5043
  });
5226
5044
  }
5227
5045
  function upsertAgentGUIUserProject(projects, project) {
@@ -5231,6 +5049,7 @@ function upsertAgentGUIUserProject(projects, project) {
5231
5049
  ...project.lastUsedAtUnixMs === void 0 || project.lastUsedAtUnixMs === null ? {} : { lastUsedAtUnixMs: project.lastUsedAtUnixMs },
5232
5050
  label: project.label,
5233
5051
  path: project.path,
5052
+ pinnedAtUnixMs: project.pinnedAtUnixMs,
5234
5053
  ...project.sectionKey === void 0 ? {} : { sectionKey: project.sectionKey },
5235
5054
  ...project.updatedAtUnixMs === void 0 ? {} : { updatedAtUnixMs: project.updatedAtUnixMs }
5236
5055
  };
@@ -5252,6 +5071,7 @@ function readAgentGUIUserProjectSnapshot(api) {
5252
5071
  ...project.lastUsedAtUnixMs === void 0 || project.lastUsedAtUnixMs === null ? {} : { lastUsedAtUnixMs: project.lastUsedAtUnixMs },
5253
5072
  label: project.label,
5254
5073
  path: project.path,
5074
+ pinnedAtUnixMs: project.pinnedAtUnixMs,
5255
5075
  ...project.sectionKey === void 0 ? {} : { sectionKey: project.sectionKey },
5256
5076
  ...project.updatedAtUnixMs === void 0 ? {} : { updatedAtUnixMs: project.updatedAtUnixMs }
5257
5077
  }));
@@ -7020,6 +6840,96 @@ function composerSettingsSupportFromOptions(composerOptions, sessionCapabilities
7020
6840
  };
7021
6841
  }
7022
6842
 
6843
+ // agent-gui/agentGuiNode/controller/agentGuiController.composerPresentation.ts
6844
+ function composerTargetDataFromNodeData(data) {
6845
+ const agentTargetId = normalizeOptionalText(data.agentTargetId);
6846
+ return {
6847
+ agentTargetId,
6848
+ provider: data.provider,
6849
+ targetId: agentTargetId ?? `local:${data.provider}`,
6850
+ data
6851
+ };
6852
+ }
6853
+ function composerTargetDataForConversation(input) {
6854
+ if (input.activeConversationId === null) {
6855
+ return input.selectedTarget;
6856
+ }
6857
+ if (input.optimisticTarget?.agentSessionId === input.activeConversationId && !nodeDataMatchesComposerTarget(input.data, input.optimisticTarget.target)) {
6858
+ return input.optimisticTarget.target;
6859
+ }
6860
+ return composerTargetDataFromNodeData(input.data);
6861
+ }
6862
+ function nodeDataMatchesComposerTarget(data, target) {
6863
+ return data.provider === target.provider && normalizeOptionalText(data.agentTargetId) === target.agentTargetId;
6864
+ }
6865
+ function isForegroundModelOptionsLoading(input) {
6866
+ return input.supportsModel && input.modelOptionsLoading === true && (input.selection === null || input.selection.options.length === 0);
6867
+ }
6868
+ function effectiveComposerSettingsFromOptions(options) {
6869
+ const settings = options?.effectiveSettings;
6870
+ if (!settings) {
6871
+ return null;
6872
+ }
6873
+ return {
6874
+ model: normalizeOptionalText(settings.model),
6875
+ reasoningEffort: normalizeOptionalText(
6876
+ settings.reasoningEffort
6877
+ ),
6878
+ speed: normalizeOptionalText(settings.speed),
6879
+ planMode: settings.planMode ?? void 0,
6880
+ permissionModeId: normalizeOptionalText(settings.permissionModeId)
6881
+ };
6882
+ }
6883
+ function resolvePresentedComposerSettings(input) {
6884
+ const layers = [
6885
+ input.sessionSettings,
6886
+ input.optimisticSettings,
6887
+ input.preloadedSettings,
6888
+ input.homeSettings
6889
+ ];
6890
+ const firstText = (field) => {
6891
+ for (const layer of layers) {
6892
+ const value = normalizeOptionalText(layer?.[field]);
6893
+ if (value) {
6894
+ return value;
6895
+ }
6896
+ }
6897
+ return null;
6898
+ };
6899
+ const firstBoolean = (field, fallback) => {
6900
+ for (const layer of layers) {
6901
+ const value = layer?.[field];
6902
+ if (typeof value === "boolean") {
6903
+ return value;
6904
+ }
6905
+ }
6906
+ return fallback;
6907
+ };
6908
+ return {
6909
+ model: firstText("model"),
6910
+ reasoningEffort: firstText(
6911
+ "reasoningEffort"
6912
+ ),
6913
+ speed: firstText("speed"),
6914
+ planMode: firstBoolean("planMode", false),
6915
+ browserUse: firstBoolean("browserUse", true),
6916
+ computerUse: firstBoolean("computerUse", true),
6917
+ permissionModeId: firstText("permissionModeId")
6918
+ };
6919
+ }
6920
+ function resolveComposerSettingsPresentation(input) {
6921
+ const sessionSettings = input.active && (input.sessionSettings != null || Boolean(input.permissionModeId)) ? {
6922
+ ...input.sessionSettings ?? {},
6923
+ permissionModeId: normalizeOptionalText(input.permissionModeId) ?? normalizeOptionalText(input.sessionSettings?.permissionModeId)
6924
+ } : null;
6925
+ return resolvePresentedComposerSettings({
6926
+ sessionSettings,
6927
+ optimisticSettings: input.active ? input.optimisticSettings ?? null : input.homeSettings,
6928
+ preloadedSettings: effectiveComposerSettingsFromOptions(input.options),
6929
+ homeSettings: input.homeSettings
6930
+ });
6931
+ }
6932
+
7023
6933
  // agent-gui/agentGuiNode/controller/useAgentGUIComposerCapabilities.ts
7024
6934
  function useAgentGUIComposerCapabilities(input) {
7025
6935
  const composerTargetData = composerTargetDataForConversation({
@@ -7189,6 +7099,12 @@ function dispatchEvent(event) {
7189
7099
  }
7190
7100
  }
7191
7101
  }
7102
+ function subscribe(type, callback) {
7103
+ return addSubscriber({
7104
+ matches: (event) => event.type === type,
7105
+ emit: (event) => callback(event)
7106
+ });
7107
+ }
7192
7108
  function subscribeCoalesced(type, options, callback) {
7193
7109
  const pendingByKey = /* @__PURE__ */ new Map();
7194
7110
  const timersByKey = /* @__PURE__ */ new Map();
@@ -7267,23 +7183,40 @@ function useAgentGUIComposerOptionsSync(input) {
7267
7183
  );
7268
7184
  const loadComposerOptionsForTarget = useCallback8(
7269
7185
  (targetData, options) => {
7270
- if (input.isCreatingConversation || !targetData.agentTargetId) return;
7271
- const settings = readNodeDefaultDraftSettings({
7186
+ if (input.isCreatingConversation && !options?.allowWhileCreating || !targetData.agentTargetId) {
7187
+ return Promise.resolve();
7188
+ }
7189
+ const localSettings = options?.settings ?? readNodeDefaultDraftSettings({
7272
7190
  data: targetData.data,
7273
7191
  defaultReasoningEffort: input.defaultReasoningEffort,
7274
7192
  drafts: input.draftSettingsBySessionIdRef.current
7275
7193
  });
7194
+ const authorityRead = options?.reconcileAcknowledgedDefaults ? input.onComposerDefaultsAuthorityReloadedRef.current.prepareRead(
7195
+ targetData,
7196
+ localSettings
7197
+ ) : { force: false, receipt: null, settings: localSettings };
7198
+ const localDefaults = options?.excludePersistentDefaults ? composerDefaultsPatchFromSettings(localSettings, localSettings) : null;
7199
+ const requestSettings = localDefaults ? withoutAcknowledgedComposerDefaults(
7200
+ authorityRead.settings,
7201
+ localDefaults
7202
+ ) : authorityRead.settings;
7276
7203
  const cwd = input.selectedProjectPathRef.current?.trim() || input.workspacePath.trim() || "";
7277
- void Promise.resolve(
7204
+ return Promise.resolve(
7278
7205
  input.agentActivityRuntime.getComposerOptions({
7279
7206
  workspaceId: input.workspaceId,
7280
7207
  cwd,
7281
- force: options?.force,
7208
+ force: options?.force || authorityRead.force ? true : void 0,
7282
7209
  provider: targetData.provider,
7283
7210
  agentTargetId: targetData.agentTargetId,
7284
- settings
7211
+ settings: requestSettings
7285
7212
  })
7286
- ).catch(() => void 0);
7213
+ ).then(() => {
7214
+ if (options?.reconcileAcknowledgedDefaults) {
7215
+ input.onComposerDefaultsAuthorityReloadedRef.current.reloaded(
7216
+ authorityRead.receipt
7217
+ );
7218
+ }
7219
+ });
7287
7220
  },
7288
7221
  [
7289
7222
  input.agentActivityRuntime,
@@ -7295,23 +7228,36 @@ function useAgentGUIComposerOptionsSync(input) {
7295
7228
  );
7296
7229
  const loadDraftComposerOptions = useCallback8(
7297
7230
  (options) => {
7298
- loadComposerOptionsForTarget(
7231
+ void loadComposerOptionsForTarget(
7299
7232
  composerTargetDataForConversation({
7300
7233
  activeConversationId: input.activeConversationIdRef.current,
7301
7234
  data: input.dataRef.current,
7302
7235
  optimisticTarget: null,
7303
7236
  selectedTarget: input.selectedComposerTargetDataRef.current
7304
7237
  }),
7305
- options
7306
- );
7238
+ {
7239
+ ...options,
7240
+ reconcileAcknowledgedDefaults: input.activeConversationIdRef.current === null && input.isComposerHomeRef.current
7241
+ }
7242
+ ).catch(() => void 0);
7307
7243
  },
7308
7244
  [
7309
7245
  input.activeConversationIdRef,
7310
7246
  input.dataRef,
7247
+ input.isComposerHomeRef,
7311
7248
  input.selectedComposerTargetDataRef,
7312
7249
  loadComposerOptionsForTarget
7313
7250
  ]
7314
7251
  );
7252
+ const reloadComposerOptionsForTarget = useCallback8(
7253
+ (reloadInput) => loadComposerOptionsForTarget(reloadInput.target, {
7254
+ allowWhileCreating: true,
7255
+ force: true,
7256
+ reconcileAcknowledgedDefaults: true,
7257
+ settings: reloadInput.settings
7258
+ }),
7259
+ [loadComposerOptionsForTarget]
7260
+ );
7315
7261
  input.loadDraftComposerOptionsRef.current = loadDraftComposerOptions;
7316
7262
  useEffect5(() => {
7317
7263
  if (input.previewMode) return void 0;
@@ -7343,6 +7289,37 @@ function useAgentGUIComposerOptionsSync(input) {
7343
7289
  }
7344
7290
  );
7345
7291
  }, [input.loadSessionState, input.previewMode, loadDraftComposerOptions]);
7292
+ useEffect5(() => {
7293
+ if (input.previewMode) return void 0;
7294
+ return subscribe("agent-composer-defaults-invalidated", (event) => {
7295
+ const selectedTarget = composerTargetDataForConversation({
7296
+ activeConversationId: input.activeConversationIdRef.current,
7297
+ data: input.dataRef.current,
7298
+ optimisticTarget: null,
7299
+ selectedTarget: input.selectedComposerTargetDataRef.current
7300
+ });
7301
+ if (selectedTarget.agentTargetId !== event.agentTargetId) {
7302
+ return;
7303
+ }
7304
+ const localIntent = readNodeDefaultDraftSettings({
7305
+ data: selectedTarget.data,
7306
+ defaultReasoningEffort: input.defaultReasoningEffort,
7307
+ drafts: input.draftSettingsBySessionIdRef.current
7308
+ });
7309
+ void loadComposerOptionsForTarget(selectedTarget, {
7310
+ allowWhileCreating: true,
7311
+ excludePersistentDefaults: true,
7312
+ force: true,
7313
+ reconcileAcknowledgedDefaults: true,
7314
+ settings: localIntent
7315
+ }).catch(() => void 0);
7316
+ });
7317
+ }, [
7318
+ input.defaultReasoningEffort,
7319
+ input.onComposerDefaultsAuthorityReloadedRef,
7320
+ input.previewMode,
7321
+ loadComposerOptionsForTarget
7322
+ ]);
7346
7323
  useEffect5(() => {
7347
7324
  if (input.previewMode) return;
7348
7325
  const conversationActivated = input.activeConversationId !== null && previousActiveConversationIdRef.current !== input.activeConversationId;
@@ -7395,7 +7372,7 @@ function useAgentGUIComposerOptionsSync(input) {
7395
7372
  input.reloadSelectedConversation,
7396
7373
  input.sessionEngine
7397
7374
  ]);
7398
- return { loadDraftComposerOptions };
7375
+ return { loadDraftComposerOptions, reloadComposerOptionsForTarget };
7399
7376
  }
7400
7377
 
7401
7378
  // agent-gui/agentGuiNode/controller/useAgentGUIControllerRefs.ts
@@ -7429,7 +7406,15 @@ function useAgentGUIControllerRefs(input) {
7429
7406
  const handledComposerAppendSequenceRef = useRef9(null);
7430
7407
  const loadDraftComposerOptionsRef = useRef9(() => {
7431
7408
  });
7432
- const lastActiveModelByProviderRef = useRef9({});
7409
+ const onComposerDefaultsAuthorityReloadedRef = useRef9({
7410
+ prepareRead: (_target, settings) => ({
7411
+ force: false,
7412
+ receipt: null,
7413
+ settings
7414
+ }),
7415
+ reloaded: () => {
7416
+ }
7417
+ });
7433
7418
  const conversationIdsRef = useRef9(
7434
7419
  new Set(input.conversations.map((conversation) => conversation.id))
7435
7420
  );
@@ -7483,10 +7468,10 @@ function useAgentGUIControllerRefs(input) {
7483
7468
  isCreatingConversationRef,
7484
7469
  isMountedRef,
7485
7470
  isNoProjectPathRef,
7486
- lastActiveModelByProviderRef,
7487
7471
  lastRenderStateDiagnosticKeyRef,
7488
7472
  loadDraftComposerOptionsRef,
7489
7473
  onDataChangeRef,
7474
+ onComposerDefaultsAuthorityReloadedRef,
7490
7475
  onRememberComposerDefaultsRef,
7491
7476
  onShowMessageRef,
7492
7477
  pendingOpenSessionRequestRef,
@@ -7512,7 +7497,7 @@ import {
7512
7497
  selectEngineSession as selectEngineSession2,
7513
7498
  selectEngineSessionSettingsUpdate
7514
7499
  } from "@tutti-os/agent-activity-core";
7515
- import { useCallback as useCallback9 } from "react";
7500
+ import { useCallback as useCallback9, useRef as useRef10 } from "react";
7516
7501
 
7517
7502
  // agent-gui/agentGuiNode/model/composerModeSelection.ts
7518
7503
  function normalizePermissionModeSelection(permissionModeId) {
@@ -7532,6 +7517,101 @@ function shouldRetrySessionSettingsUpdate(status) {
7532
7517
  return status === "unknown";
7533
7518
  }
7534
7519
 
7520
+ // agent-gui/agentGuiNode/controller/agentGuiComposerDefaultsReconciliation.ts
7521
+ function createAgentGUIComposerDefaultsLedger() {
7522
+ return {
7523
+ acknowledgedByDraftKey: {},
7524
+ latestByDraftKey: {},
7525
+ nextGeneration: 0
7526
+ };
7527
+ }
7528
+ function registerAgentGUIComposerDefaultsMutation(ledger, draftKey, defaults) {
7529
+ const latest = ledger.latestByDraftKey[draftKey] ??= {};
7530
+ const acknowledged = ledger.acknowledgedByDraftKey[draftKey] ??= {};
7531
+ const fields = {};
7532
+ for (const field of rememberComposerDefaultsFields) {
7533
+ const value = normalizeOptionalText(defaults[field]);
7534
+ if (value === null) continue;
7535
+ const generation = ++ledger.nextGeneration;
7536
+ latest[field] = generation;
7537
+ delete acknowledged[field];
7538
+ fields[field] = { generation, value };
7539
+ }
7540
+ return { draftKey, fields };
7541
+ }
7542
+ function acknowledgeAgentGUIComposerDefaultsMutation(ledger, mutation, result) {
7543
+ const latest = ledger.latestByDraftKey[mutation.draftKey];
7544
+ if (!latest) return false;
7545
+ const acknowledgedFields = new Set(result.acknowledgedFields);
7546
+ const acknowledged = ledger.acknowledgedByDraftKey[mutation.draftKey] ??= {};
7547
+ let changed = false;
7548
+ for (const field of rememberComposerDefaultsFields) {
7549
+ const requested = mutation.fields[field];
7550
+ if (!requested || !acknowledgedFields.has(field) || latest[field] !== requested.generation) {
7551
+ continue;
7552
+ }
7553
+ acknowledged[field] = requested;
7554
+ changed = true;
7555
+ }
7556
+ return changed;
7557
+ }
7558
+ function prepareAcknowledgedComposerDefaultsAuthorityRead(ledger, draftKey, settings) {
7559
+ const authoritySettings = { ...settings };
7560
+ const receipt = {
7561
+ draftKey,
7562
+ fields: {}
7563
+ };
7564
+ const latest = ledger.latestByDraftKey[draftKey];
7565
+ const acknowledged = ledger.acknowledgedByDraftKey[draftKey];
7566
+ if (latest && acknowledged) {
7567
+ for (const field of rememberComposerDefaultsFields) {
7568
+ const entry = acknowledged[field];
7569
+ if (entry && latest[field] === entry.generation && normalizeOptionalText(authoritySettings[field]) === entry.value) {
7570
+ receipt.fields[field] = { ...entry };
7571
+ delete authoritySettings[field];
7572
+ }
7573
+ }
7574
+ }
7575
+ const hasAcknowledgedFields = Object.keys(receipt.fields).length > 0;
7576
+ return {
7577
+ // An acknowledged field must cross the authority boundary again before
7578
+ // its optimistic draft can retire. Bypass a potentially pre-ack cache.
7579
+ force: hasAcknowledgedFields,
7580
+ receipt: hasAcknowledgedFields ? receipt : null,
7581
+ settings: authoritySettings
7582
+ };
7583
+ }
7584
+ function retireAcknowledgedComposerDefaultsForRead(ledger, receipt, settings) {
7585
+ const latest = ledger.latestByDraftKey[receipt.draftKey];
7586
+ const acknowledged = ledger.acknowledgedByDraftKey[receipt.draftKey];
7587
+ if (!latest || !acknowledged) return [];
7588
+ const retired = [];
7589
+ for (const field of rememberComposerDefaultsFields) {
7590
+ const readEntry = receipt.fields[field];
7591
+ const currentEntry = acknowledged[field];
7592
+ if (!readEntry || !currentEntry || currentEntry.generation !== readEntry.generation || latest[field] !== readEntry.generation) {
7593
+ continue;
7594
+ }
7595
+ if (normalizeOptionalText(settings[field]) === readEntry.value) {
7596
+ retired.push({ field, value: readEntry.value });
7597
+ }
7598
+ delete acknowledged[field];
7599
+ }
7600
+ if (Object.keys(acknowledged).length === 0) {
7601
+ delete ledger.acknowledgedByDraftKey[receipt.draftKey];
7602
+ }
7603
+ return retired;
7604
+ }
7605
+ function removeRetiredComposerDefaults(settings, retired) {
7606
+ const result = { ...settings };
7607
+ for (const entry of retired) {
7608
+ if (normalizeOptionalText(result[entry.field]) === entry.value) {
7609
+ delete result[entry.field];
7610
+ }
7611
+ }
7612
+ return result;
7613
+ }
7614
+
7535
7615
  // agent-gui/agentGuiNode/controller/useAgentGUIComposerSettingsActions.ts
7536
7616
  function useAgentGUIComposerSettingsActions(input) {
7537
7617
  const {
@@ -7543,10 +7623,12 @@ function useAgentGUIComposerSettingsActions(input) {
7543
7623
  dataRef,
7544
7624
  defaultReasoningEffort,
7545
7625
  draftSettingsBySessionIdRef,
7626
+ isMountedRef,
7546
7627
  loadDraftComposerOptions,
7547
- onDataChangeRef,
7628
+ onComposerDefaultsAuthorityReloadedRef,
7548
7629
  onRememberComposerDefaultsRef,
7549
7630
  onShowMessageRef,
7631
+ reloadComposerOptionsForTarget,
7550
7632
  selectedComposerTargetDataRef,
7551
7633
  sessionEngine,
7552
7634
  setDraftSettingsBySessionId,
@@ -7556,11 +7638,53 @@ function useAgentGUIComposerSettingsActions(input) {
7556
7638
  const composerSupport = {
7557
7639
  permissionModeChangeDeferred: input.composerSupportPermissionModeChangeDeferred
7558
7640
  };
7641
+ const composerDefaultsLedgerRef = useRef10(
7642
+ createAgentGUIComposerDefaultsLedger()
7643
+ );
7644
+ const retireAcknowledgedDefaultsForRead = useCallback9(
7645
+ (receipt) => {
7646
+ if (!isMountedRef.current || !receipt) return;
7647
+ const currentDraft = draftSettingsBySessionIdRef.current[receipt.draftKey];
7648
+ if (!currentDraft) return;
7649
+ const retired = retireAcknowledgedComposerDefaultsForRead(
7650
+ composerDefaultsLedgerRef.current,
7651
+ receipt,
7652
+ currentDraft
7653
+ );
7654
+ if (retired.length === 0) return;
7655
+ draftSettingsBySessionIdRef.current = reconcileRetiredDraftMap(
7656
+ draftSettingsBySessionIdRef.current,
7657
+ receipt.draftKey,
7658
+ retired
7659
+ );
7660
+ setDraftSettingsBySessionId(
7661
+ (current) => reconcileRetiredDraftMap(current, receipt.draftKey, retired)
7662
+ );
7663
+ },
7664
+ [draftSettingsBySessionIdRef, isMountedRef, setDraftSettingsBySessionId]
7665
+ );
7666
+ const prepareComposerDefaultsAuthorityRead = useCallback9(
7667
+ (target, settings) => prepareAcknowledgedComposerDefaultsAuthorityRead(
7668
+ composerDefaultsLedgerRef.current,
7669
+ nodeDefaultDraftKey(target.provider, target.agentTargetId),
7670
+ settings
7671
+ ),
7672
+ []
7673
+ );
7674
+ onComposerDefaultsAuthorityReloadedRef.current = {
7675
+ prepareRead: prepareComposerDefaultsAuthorityRead,
7676
+ reloaded: retireAcknowledgedDefaultsForRead
7677
+ };
7559
7678
  const updateComposerSettings = useCallback9(
7560
7679
  (nextSettings) => {
7561
7680
  const supportedNextSettings = {
7562
7681
  ...nextSettings
7563
7682
  };
7683
+ for (const field of rememberComposerDefaultsFields) {
7684
+ if (supportedNextSettings[field] !== void 0 && normalizeOptionalText(supportedNextSettings[field]) === null) {
7685
+ delete supportedNextSettings[field];
7686
+ }
7687
+ }
7564
7688
  const agentSessionId = activeConversationIdRef.current;
7565
7689
  if (!agentSessionId) {
7566
7690
  const targetData = selectedComposerTargetDataRef.current;
@@ -7568,67 +7692,75 @@ function useAgentGUIComposerSettingsActions(input) {
7568
7692
  targetData.provider,
7569
7693
  targetData.agentTargetId
7570
7694
  );
7571
- const storedDefaults = readNodeDefaultDraftSettings({
7695
+ const storedIntent = readNodeDefaultDraftSettings({
7572
7696
  data: targetData.data,
7573
7697
  defaultReasoningEffort,
7574
7698
  drafts: draftSettingsBySessionIdRef.current
7575
7699
  });
7576
7700
  const previousSettings = resolveEffectiveComposerSettings({
7577
- settings: storedDefaults
7701
+ settings: storedIntent
7578
7702
  });
7579
- const merged = {
7580
- ...previousSettings,
7581
- ...supportedNextSettings,
7582
- planMode: supportedNextSettings.planMode ?? previousSettings.planMode,
7583
- browserUse: supportedNextSettings.browserUse ?? previousSettings.browserUse,
7584
- computerUse: supportedNextSettings.computerUse ?? previousSettings.computerUse
7703
+ const mergedIntent = {
7704
+ ...storedIntent,
7705
+ ...supportedNextSettings
7585
7706
  };
7707
+ for (const field of rememberComposerDefaultsFields) {
7708
+ if (supportedNextSettings[field] !== void 0) {
7709
+ Object.assign(mergedIntent, {
7710
+ [field]: normalizeOptionalText(supportedNextSettings[field])
7711
+ });
7712
+ }
7713
+ }
7586
7714
  const snapshotComposerOptions = composerOptionsForTarget({
7587
7715
  snapshot: agentActivityRuntime.getSnapshot(workspaceId),
7588
7716
  target: targetData
7589
7717
  });
7590
- const sanitizedMerged = sanitizeComposerSettingsForTarget({
7591
- settings: merged,
7592
- target: targetData,
7593
- options: snapshotComposerOptions
7594
- });
7595
- const targetSafeMerged = {
7596
- ...sanitizedMerged,
7597
- permissionModeId: normalizePermissionModeId(
7598
- supportedNextSettings.permissionModeId === void 0 ? merged.permissionModeId : supportedNextSettings.permissionModeId
7599
- )
7600
- };
7601
7718
  draftSettingsBySessionIdRef.current = {
7602
7719
  ...draftSettingsBySessionIdRef.current,
7603
- [defaultDraftKey]: targetSafeMerged
7720
+ [defaultDraftKey]: mergedIntent
7604
7721
  };
7605
7722
  setDraftSettingsBySessionId((current) => ({
7606
7723
  ...current,
7607
- [defaultDraftKey]: targetSafeMerged
7724
+ [defaultDraftKey]: mergedIntent
7608
7725
  }));
7609
- onDataChangeRef.current(
7610
- (current) => nodeDataFromComposerSettings(
7726
+ const rememberedDefaultsPatch2 = composerDefaultsPatchFromSettings(
7727
+ supportedNextSettings,
7728
+ mergedIntent
7729
+ );
7730
+ if (rememberedDefaultsPatch2) {
7731
+ const mutation = registerAgentGUIComposerDefaultsMutation(
7732
+ composerDefaultsLedgerRef.current,
7733
+ defaultDraftKey,
7734
+ rememberedDefaultsPatch2
7735
+ );
7736
+ const acknowledgement = invokeRememberComposerDefaults(
7737
+ onRememberComposerDefaultsRef.current,
7611
7738
  {
7612
- ...current,
7739
+ agentTargetId: targetData.agentTargetId,
7613
7740
  provider: targetData.provider,
7614
- agentTargetId: targetData.agentTargetId
7615
- },
7616
- targetSafeMerged
7617
- )
7618
- );
7619
- void onRememberComposerDefaultsRef.current?.({
7620
- agentTargetId: targetData.agentTargetId,
7621
- provider: targetData.provider,
7622
- defaults: composerDefaultsPatchFromSettings(
7623
- supportedNextSettings,
7624
- targetSafeMerged
7625
- )
7626
- });
7741
+ defaults: rememberedDefaultsPatch2
7742
+ }
7743
+ );
7744
+ if (targetData.agentTargetId && acknowledgement) {
7745
+ void reconcileAcknowledgedHomeDefaults({
7746
+ acknowledgement,
7747
+ draftKey: defaultDraftKey,
7748
+ draftSettingsBySessionIdRef,
7749
+ isMountedRef,
7750
+ ledger: composerDefaultsLedgerRef.current,
7751
+ mutation,
7752
+ reloadComposerOptionsForTarget,
7753
+ target: targetData
7754
+ }).catch(() => void 0);
7755
+ }
7756
+ }
7627
7757
  void agentActivityRuntime.trackDraftComposerSettingsChange?.({
7628
7758
  workspaceId,
7629
7759
  provider: targetData.provider,
7630
7760
  previousSettings,
7631
- nextSettings: targetSafeMerged
7761
+ nextSettings: resolveEffectiveComposerSettings({
7762
+ settings: mergedIntent
7763
+ })
7632
7764
  });
7633
7765
  loadDraftComposerOptions(
7634
7766
  snapshotComposerOptions?.behavior?.refreshModelOptionsAfterSettings === true ? { force: true } : void 0
@@ -7660,6 +7792,25 @@ function useAgentGUIComposerSettingsActions(input) {
7660
7792
  const nextComputerUse = supportedNextSettings.computerUse;
7661
7793
  const currentComputerUse = sessionSettings?.computerUse ?? true;
7662
7794
  const sessionSettingsPatch = {};
7795
+ const rememberedDefaultsPatch = composerDefaultsPatchFromSettings(
7796
+ supportedNextSettings,
7797
+ supportedNextSettings
7798
+ );
7799
+ if (rememberedDefaultsPatch) {
7800
+ const defaultAgentTargetId = normalizeOptionalText(canonicalSession?.agentTargetId) ?? normalizeOptionalText(dataRef.current.agentTargetId);
7801
+ const defaultProvider = canonicalSession?.provider ?? dataRef.current.provider;
7802
+ const saving = invokeRememberComposerDefaults(
7803
+ onRememberComposerDefaultsRef.current,
7804
+ {
7805
+ agentTargetId: defaultAgentTargetId,
7806
+ provider: defaultProvider,
7807
+ defaults: rememberedDefaultsPatch
7808
+ }
7809
+ );
7810
+ if (saving) {
7811
+ void saving.catch(() => void 0);
7812
+ }
7813
+ }
7663
7814
  if (nextModel !== void 0 && nextModel !== currentModel) {
7664
7815
  sessionSettingsPatch.model = nextModel;
7665
7816
  }
@@ -7690,61 +7841,6 @@ function useAgentGUIComposerSettingsActions(input) {
7690
7841
  }
7691
7842
  }
7692
7843
  if (Object.keys(sessionSettingsPatch).length > 0 && (canonicalSession !== null || isPreActivationSession)) {
7693
- const rememberedDefaultsPatch = composerDefaultsPatchFromSettings(
7694
- sessionSettingsPatch,
7695
- sessionSettingsPatch
7696
- );
7697
- if (rememberedDefaultsPatch) {
7698
- const defaultAgentTargetId = normalizeOptionalText(canonicalSession?.agentTargetId) ?? normalizeOptionalText(dataRef.current.agentTargetId);
7699
- const defaultProvider = canonicalSession?.provider ?? dataRef.current.provider;
7700
- void onRememberComposerDefaultsRef.current?.({
7701
- agentTargetId: defaultAgentTargetId,
7702
- provider: defaultProvider,
7703
- defaults: rememberedDefaultsPatch
7704
- });
7705
- const durableNodeDefaultsPatch = {};
7706
- for (const field of rememberComposerDefaultsFields) {
7707
- if (sessionSettingsPatch[field] !== void 0) {
7708
- durableNodeDefaultsPatch[field] = sessionSettingsPatch[field];
7709
- }
7710
- }
7711
- const defaultDraftKey = nodeDefaultDraftKey(
7712
- defaultProvider,
7713
- defaultAgentTargetId
7714
- );
7715
- const defaultData = {
7716
- ...dataRef.current,
7717
- provider: defaultProvider,
7718
- agentTargetId: defaultAgentTargetId
7719
- };
7720
- const storedNodeDefaults = readNodeDefaultDraftSettings({
7721
- data: defaultData,
7722
- defaultReasoningEffort,
7723
- drafts: draftSettingsBySessionIdRef.current
7724
- });
7725
- const nextNodeDefaults = {
7726
- ...storedNodeDefaults,
7727
- ...durableNodeDefaultsPatch
7728
- };
7729
- draftSettingsBySessionIdRef.current = {
7730
- ...draftSettingsBySessionIdRef.current,
7731
- [defaultDraftKey]: nextNodeDefaults
7732
- };
7733
- setDraftSettingsBySessionId((current) => ({
7734
- ...current,
7735
- [defaultDraftKey]: nextNodeDefaults
7736
- }));
7737
- onDataChangeRef.current(
7738
- (current) => nodeDataFromComposerSettings(
7739
- {
7740
- ...current,
7741
- provider: defaultProvider,
7742
- agentTargetId: defaultAgentTargetId
7743
- },
7744
- nextNodeDefaults
7745
- )
7746
- );
7747
- }
7748
7844
  if (isPreActivationSession) {
7749
7845
  sessionEngine.dispatch({
7750
7846
  type: "activation/settingsPatched",
@@ -7775,6 +7871,7 @@ function useAgentGUIComposerSettingsActions(input) {
7775
7871
  defaultReasoningEffort,
7776
7872
  composerSupport.permissionModeChangeDeferred,
7777
7873
  loadDraftComposerOptions,
7874
+ reloadComposerOptionsForTarget,
7778
7875
  sessionEngine,
7779
7876
  workspaceId
7780
7877
  ]
@@ -7782,14 +7879,56 @@ function useAgentGUIComposerSettingsActions(input) {
7782
7879
  updateComposerSettingsRef.current = updateComposerSettings;
7783
7880
  return { updateComposerSettings };
7784
7881
  }
7882
+ function invokeRememberComposerDefaults(callback, input) {
7883
+ if (!callback) return void 0;
7884
+ try {
7885
+ const result = callback(input);
7886
+ return result === void 0 ? void 0 : Promise.resolve(result);
7887
+ } catch (error) {
7888
+ return Promise.reject(error);
7889
+ }
7890
+ }
7891
+ async function reconcileAcknowledgedHomeDefaults(input) {
7892
+ const result = await input.acknowledgement;
7893
+ if (!input.isMountedRef.current) return;
7894
+ const currentDraft = input.draftSettingsBySessionIdRef.current[input.draftKey];
7895
+ if (!currentDraft) {
7896
+ return;
7897
+ }
7898
+ if (!acknowledgeAgentGUIComposerDefaultsMutation(
7899
+ input.ledger,
7900
+ input.mutation,
7901
+ result
7902
+ )) {
7903
+ return;
7904
+ }
7905
+ await input.reloadComposerOptionsForTarget({
7906
+ settings: currentDraft,
7907
+ target: input.target
7908
+ });
7909
+ }
7910
+ function reconcileRetiredDraftMap(current, draftKey, retired) {
7911
+ const draft = current[draftKey];
7912
+ if (!draft) return current;
7913
+ const nextDraft = removeRetiredComposerDefaults(draft, retired);
7914
+ if (Object.keys(draft).length === Object.keys(nextDraft).length)
7915
+ return current;
7916
+ const next = { ...current };
7917
+ if (Object.keys(nextDraft).length === 0) {
7918
+ delete next[draftKey];
7919
+ } else {
7920
+ next[draftKey] = nextDraft;
7921
+ }
7922
+ return next;
7923
+ }
7785
7924
 
7786
7925
  // agent-gui/agentGuiNode/controller/useAgentGUIContinueConversation.ts
7787
- import { useCallback as useCallback10, useRef as useRef10 } from "react";
7926
+ import { useCallback as useCallback10, useRef as useRef11 } from "react";
7788
7927
  function buildContinueInNewConversationDraft(input) {
7789
7928
  return updateAgentComposerDraft(input.sourceDraft, { prompt: input.prompt });
7790
7929
  }
7791
7930
  function useAgentGUIContinueConversation(input) {
7792
- const inputRef = useRef10(input);
7931
+ const inputRef = useRef11(input);
7793
7932
  inputRef.current = input;
7794
7933
  return useCallback10(() => {
7795
7934
  const current = inputRef.current;
@@ -8535,6 +8674,34 @@ function useAgentGUIConversationMetadataActions(input) {
8535
8674
  },
8536
8675
  [agentHostApi.debug, agentHostApi.userProjects]
8537
8676
  );
8677
+ const toggleProjectPinned = useCallback14(
8678
+ async (projectId, pinned) => {
8679
+ const normalizedProjectId = projectId.trim();
8680
+ const pin = agentHostApi.userProjects?.pin;
8681
+ if (!normalizedProjectId || !pin) return;
8682
+ agentHostApi.debug?.logRuntimeDiagnostics?.({
8683
+ phase: "pin_user_project_requested",
8684
+ pinned,
8685
+ projectId: normalizedProjectId
8686
+ });
8687
+ try {
8688
+ await pin({ projectId: normalizedProjectId, pinned });
8689
+ agentHostApi.debug?.logRuntimeDiagnostics?.({
8690
+ phase: "pin_user_project_succeeded",
8691
+ pinned,
8692
+ projectId: normalizedProjectId
8693
+ });
8694
+ } catch (error) {
8695
+ agentHostApi.debug?.logRuntimeDiagnostics?.({
8696
+ error: getAgentGUIErrorMessage(error),
8697
+ phase: "pin_user_project_failed",
8698
+ pinned,
8699
+ projectId: normalizedProjectId
8700
+ });
8701
+ }
8702
+ },
8703
+ [agentHostApi.debug, agentHostApi.userProjects]
8704
+ );
8538
8705
  const toggleConversationPinned = useCallback14(
8539
8706
  (agentSessionId, pinned) => {
8540
8707
  const normalizedAgentSessionId = agentSessionId.trim();
@@ -8610,6 +8777,7 @@ function useAgentGUIConversationMetadataActions(input) {
8610
8777
  return {
8611
8778
  moveProject,
8612
8779
  removeProject,
8780
+ toggleProjectPinned,
8613
8781
  toggleConversationPinned,
8614
8782
  markConversationUnread,
8615
8783
  renameConversation
@@ -8640,9 +8808,7 @@ function useAgentGUINewConversationActivation(input) {
8640
8808
  workspaceId,
8641
8809
  activeConversationIdRef,
8642
8810
  isComposerHomeRef,
8643
- conversationsRef,
8644
8811
  activeSessionState,
8645
- lastActiveModelByProviderRef,
8646
8812
  sessionEngine,
8647
8813
  activation,
8648
8814
  currentUserId,
@@ -8696,43 +8862,10 @@ function useAgentGUINewConversationActivation(input) {
8696
8862
  drafts: draftSettingsBySessionIdRef.current
8697
8863
  });
8698
8864
  const snapshotComposerOptions = getCachedComposerOptions();
8699
- const targetSafeInitialSettings = sanitizeComposerSettingsForTarget({
8700
- settings: initialNodeSettings,
8701
- target: targetData,
8702
- options: snapshotComposerOptions
8703
- });
8704
- const initialSettings = resolveComposerSettingsPresentation({
8705
- active: false,
8706
- homeSettings: targetSafeInitialSettings,
8707
- options: snapshotComposerOptions
8708
- });
8709
- const currentActiveConversationId = activeConversationIdRef.current;
8710
- const currentActiveConversation = currentActiveConversationId ? resolveConversationSummaryById(
8711
- conversationsRef.current,
8712
- currentActiveConversationId
8713
- ) : null;
8714
- const inheritedModel = normalizeOptionalText(targetSafeInitialSettings.model) === null ? resolveSameProviderActiveSessionModel({
8715
- activeProvider: currentActiveConversation?.provider ?? null,
8716
- agentSessionId: currentActiveConversationId,
8717
- provider,
8718
- runtime: agentActivityRuntime,
8719
- sessionState: activeSessionState,
8720
- workspaceId
8721
- }) ?? normalizeOptionalText(
8722
- lastActiveModelByProviderRef.current[provider]
8723
- ) : null;
8724
- const settings = sanitizeComposerSettingsForTarget({
8725
- settings: inheritedModel === null ? {
8726
- ...initialSettings,
8727
- ...submitOptions?.requiredSettingsPatch
8728
- } : {
8729
- ...initialSettings,
8730
- model: inheritedModel,
8731
- ...submitOptions?.requiredSettingsPatch
8732
- },
8733
- target: targetData,
8734
- options: snapshotComposerOptions
8735
- });
8865
+ const settings = {
8866
+ ...initialNodeSettings,
8867
+ ...submitOptions?.requiredSettingsPatch
8868
+ };
8736
8869
  const prewarmedSessionId = normalizedInitialContent.length > 0 && snapshotComposerOptions?.behavior?.prewarmDraftSession === true ? draftAgentSessionIdFromComposerOptions(snapshotComposerOptions) : null;
8737
8870
  const agentSessionId = prewarmedSessionId && activation.stateFor(prewarmedSessionId) === "inactive" && isPendingActivationViable5(
8738
8871
  selectLatestActivationForSession5(
@@ -9078,7 +9211,7 @@ function resolveAgentGUIInteractionTarget(interactions, requestId) {
9078
9211
  import {
9079
9212
  selectEngineSession as selectEngineSession3
9080
9213
  } from "@tutti-os/agent-activity-core";
9081
- import { useCallback as useCallback18, useRef as useRef11 } from "react";
9214
+ import { useCallback as useCallback18, useRef as useRef12 } from "react";
9082
9215
 
9083
9216
  // agent-gui/agentGuiNode/controller/agentGuiOptimisticGoal.ts
9084
9217
  function projectOptimisticGoalControl(currentGoal, action, objective) {
@@ -9117,7 +9250,7 @@ function unresolvedOptimisticGoalControl(optimisticGoalControl, agentSessionId,
9117
9250
 
9118
9251
  // agent-gui/agentGuiNode/controller/useAgentGUIGoalControlActions.ts
9119
9252
  function useAgentGUIGoalControlActions(input) {
9120
- const requestSequenceRef = useRef11(0);
9253
+ const requestSequenceRef = useRef12(0);
9121
9254
  const beginOptimisticGoalControl = useCallback18(
9122
9255
  (agentSessionId, action, objective, requestId, reconcileOnObjectiveMatch = false) => {
9123
9256
  const canonicalSession = selectEngineSession3(
@@ -9913,7 +10046,7 @@ function useAgentGUIViewModel(candidate) {
9913
10046
  }
9914
10047
 
9915
10048
  // agent-gui/agentGuiNode/controller/useAgentGUIComposerPresentation.ts
9916
- import { useEffect as useEffect8, useMemo as useMemo9 } from "react";
10049
+ import { useMemo as useMemo9 } from "react";
9917
10050
 
9918
10051
  // agent-gui/agentGuiNode/model/agentCapabilityUseSubmit.ts
9919
10052
  var AGENT_CAPABILITY_USE_CONFIG = {
@@ -10401,13 +10534,7 @@ function useAgentGUIComposerPresentation(input) {
10401
10534
  drafts: input.draftSettingsBySessionId
10402
10535
  })
10403
10536
  );
10404
- const targetSafeNodeDefaultSettings = useStableComposerSettings(
10405
- input.activeConversationId === null ? sanitizeComposerSettingsForTarget({
10406
- settings: storedNodeDefaultSettings,
10407
- target: input.selectedComposerTargetData,
10408
- options: input.providerComposerOptions
10409
- }) : storedNodeDefaultSettings
10410
- );
10537
+ const targetSafeNodeDefaultSettings = storedNodeDefaultSettings;
10411
10538
  const homeComposerSettings = useStableComposerSettings(
10412
10539
  resolveComposerSettingsPresentation({
10413
10540
  active: false,
@@ -10415,45 +10542,6 @@ function useAgentGUIComposerPresentation(input) {
10415
10542
  options: input.providerComposerOptions
10416
10543
  })
10417
10544
  );
10418
- useEffect8(() => {
10419
- if (input.activeConversationId !== null || !input.selectedComposerTargetData.agentTargetId || !input.providerComposerOptions || sameComposerSettings(
10420
- storedNodeDefaultSettings,
10421
- targetSafeNodeDefaultSettings
10422
- )) {
10423
- return;
10424
- }
10425
- const targetDefaultDraftKey = nodeDefaultDraftKey(
10426
- input.selectedComposerTargetData.provider,
10427
- input.selectedComposerTargetData.agentTargetId
10428
- );
10429
- input.draftSettingsBySessionIdRef.current = {
10430
- ...input.draftSettingsBySessionIdRef.current,
10431
- [targetDefaultDraftKey]: targetSafeNodeDefaultSettings
10432
- };
10433
- input.setDraftSettingsBySessionId((current) => ({
10434
- ...current,
10435
- [targetDefaultDraftKey]: targetSafeNodeDefaultSettings
10436
- }));
10437
- input.onDataChangeRef.current(
10438
- (current) => nodeDataFromComposerSettings(
10439
- {
10440
- ...current,
10441
- provider: input.selectedComposerTargetData.provider,
10442
- agentTargetId: input.selectedComposerTargetData.agentTargetId
10443
- },
10444
- targetSafeNodeDefaultSettings
10445
- )
10446
- );
10447
- }, [
10448
- input.activeConversationId,
10449
- input.draftSettingsBySessionIdRef,
10450
- input.onDataChangeRef,
10451
- input.providerComposerOptions,
10452
- input.selectedComposerTargetData,
10453
- input.setDraftSettingsBySessionId,
10454
- storedNodeDefaultSettings,
10455
- targetSafeNodeDefaultSettings
10456
- ]);
10457
10545
  const activeConversationDraftSettings = input.activeConversationId ? input.draftSettingsBySessionId[input.activeConversationId] ?? null : null;
10458
10546
  const draftSettings = useStableComposerSettings(
10459
10547
  resolveComposerSettingsPresentation({
@@ -10469,7 +10557,9 @@ function useAgentGUIComposerPresentation(input) {
10469
10557
  const usesPlaceholderDraftModel = persistedDraftModel === null || persistedDraftModel === "default";
10470
10558
  const liveConfigModel = input.activeConversationId !== null && usesPlaceholderDraftModel ? normalizeOptionalText(input.activeEngineSession?.settings?.model) : null;
10471
10559
  const draftModel = usesPlaceholderDraftModel ? liveConfigModel ?? persistedDraftModel : persistedDraftModel;
10472
- const draftReasoningEffort = input.composerSupport.reasoning ? normalizeOptionalText(draftSettings.reasoningEffort) : null;
10560
+ const draftReasoningEffort = normalizeOptionalText(
10561
+ draftSettings.reasoningEffort
10562
+ );
10473
10563
  const draftSpeed = normalizeOptionalText(
10474
10564
  draftSettings.speed
10475
10565
  );
@@ -10481,7 +10571,7 @@ function useAgentGUIComposerPresentation(input) {
10481
10571
  ),
10482
10572
  [draftModel, draftReasoningEffort, input.providerComposerOptions]
10483
10573
  );
10484
- const presentedReasoningEffort = activeSessionReasoningSelection ? activeSessionReasoningSelection.currentValue : draftReasoningEffort;
10574
+ const optionsReasoningEffort = activeSessionReasoningSelection ? activeSessionReasoningSelection.currentValue : draftReasoningEffort;
10485
10575
  const activeSessionModelSelection = useMemo9(
10486
10576
  () => modelSelectionFromComposerOptions(
10487
10577
  input.providerComposerOptions,
@@ -10506,18 +10596,35 @@ function useAgentGUIComposerPresentation(input) {
10506
10596
  const hasOptionsSource = input.providerComposerOptions !== null;
10507
10597
  const hasACPSettings = hasOptionsSource && (!input.composerSupport.model || activeSessionModelSelection !== null) && (!input.composerSupport.reasoning || activeSessionReasoningSelection !== null);
10508
10598
  const selectedPermissionModeValue = normalizePermissionModeId(draftSettings.permissionModeId) ?? normalizePermissionModeId(permissionConfig?.defaultValue);
10599
+ const protectedSettings = overlayComposerDefaults(
10600
+ {
10601
+ model: draftModel,
10602
+ permissionModeId: selectedPermissionModeValue,
10603
+ reasoningEffort: optionsReasoningEffort,
10604
+ speed: draftSpeed
10605
+ },
10606
+ input.activeConversationId === null ? input.selectedComposerTargetData.agentTargetId ? storedNodeDefaultSettings : null : sessionSettings
10607
+ );
10608
+ const presentedModel = normalizeOptionalText(protectedSettings.model);
10609
+ const presentedReasoningEffort = normalizeOptionalText(
10610
+ protectedSettings.reasoningEffort
10611
+ );
10612
+ const presentedSpeed = normalizeOptionalText(
10613
+ protectedSettings.speed
10614
+ );
10615
+ const presentedPermissionMode = normalizePermissionModeId(
10616
+ protectedSettings.permissionModeId
10617
+ );
10509
10618
  return {
10510
10619
  sessionSettings,
10511
10620
  draftSettings: {
10512
- model: draftModel,
10621
+ model: presentedModel,
10513
10622
  reasoningEffort: presentedReasoningEffort,
10514
- speed: draftSpeed,
10623
+ speed: presentedSpeed,
10515
10624
  planMode: Boolean(draftSettings.planMode),
10516
10625
  browserUse: draftSettings.browserUse ?? true,
10517
10626
  computerUse: draftSettings.computerUse ?? true,
10518
- permissionModeId: normalizePermissionModeId(
10519
- draftSettings.permissionModeId
10520
- )
10627
+ permissionModeId: presentedPermissionMode
10521
10628
  },
10522
10629
  supportsModel: input.composerSupport.model,
10523
10630
  supportsReasoningEffort: input.composerSupport.reasoning,
@@ -10542,10 +10649,10 @@ function useAgentGUIComposerPresentation(input) {
10542
10649
  reasoningUnavailable: input.activeConversationId !== null && sessionSettings === null && input.composerSupport.reasoning && draftReasoningEffort === null,
10543
10650
  speedUnavailable: input.activeConversationId !== null && sessionSettings === null && input.composerSupport.speed && draftSpeed === null,
10544
10651
  permissionModeUnavailable: input.activeConversationId !== null && sessionSettings === null && supportsPermissionMode && selectedPermissionModeValue === null,
10545
- selectedModelValue: draftModel,
10652
+ selectedModelValue: presentedModel,
10546
10653
  selectedReasoningEffortValue: presentedReasoningEffort,
10547
- selectedSpeedValue: draftSpeed,
10548
- selectedPermissionModeValue,
10654
+ selectedSpeedValue: presentedSpeed,
10655
+ selectedPermissionModeValue: presentedPermissionMode,
10549
10656
  permissionConfig,
10550
10657
  selectedProjectPath: input.activeConversationId !== null ? input.activeConversation?.cwd ?? null : input.selectedProjectPath,
10551
10658
  selectedProjectSectionKey: input.activeConversationId !== null ? input.activeConversation?.railSectionKey ?? null : resolveSelectedProjectSectionKey(
@@ -10576,10 +10683,12 @@ function useAgentGUIComposerPresentation(input) {
10576
10683
  input.composerOptionsLoading,
10577
10684
  input.composerTargetProvider,
10578
10685
  input.providerComposerOptions,
10686
+ input.selectedComposerTargetData.agentTargetId,
10579
10687
  input.selectedProjectPath,
10580
10688
  input.userProjects,
10581
- presentedReasoningEffort,
10582
- sessionSettings
10689
+ optionsReasoningEffort,
10690
+ sessionSettings,
10691
+ storedNodeDefaultSettings
10583
10692
  ]);
10584
10693
  return {
10585
10694
  draftModel,
@@ -10656,6 +10765,9 @@ function useAgentGUIControllerActions(actions) {
10656
10765
  );
10657
10766
  const removeProject = useStableControllerEventCallback(actions.removeProject);
10658
10767
  const moveProject = useStableControllerEventCallback(actions.moveProject);
10768
+ const toggleProjectPinned = useStableControllerEventCallback(
10769
+ actions.toggleProjectPinned
10770
+ );
10659
10771
  const confirmDeleteProjectConversations = useStableControllerEventCallback(
10660
10772
  actions.confirmDeleteProjectConversations
10661
10773
  );
@@ -10709,6 +10821,7 @@ function useAgentGUIControllerActions(actions) {
10709
10821
  editQueuedPrompt,
10710
10822
  removeProject,
10711
10823
  moveProject,
10824
+ toggleProjectPinned,
10712
10825
  confirmDeleteProjectConversations,
10713
10826
  confirmDeleteConversations,
10714
10827
  toggleConversationPinned,
@@ -10734,6 +10847,7 @@ function useAgentGUIControllerActions(actions) {
10734
10847
  markConversationUnread,
10735
10848
  removeProject,
10736
10849
  moveProject,
10850
+ toggleProjectPinned,
10737
10851
  removeQueuedPrompt,
10738
10852
  renameConversation,
10739
10853
  requestDeleteConversation,
@@ -10761,9 +10875,9 @@ import {
10761
10875
  selectEngineAvailableCommands,
10762
10876
  selectEngineTurnsForSession
10763
10877
  } from "@tutti-os/agent-activity-core";
10764
- import { useEffect as useEffect9, useMemo as useMemo11, useRef as useRef12 } from "react";
10878
+ import { useEffect as useEffect8, useMemo as useMemo11, useRef as useRef13 } from "react";
10765
10879
  function useAgentGUIConversationDetail(input) {
10766
- const projectionConversationRef = useRef12(null);
10880
+ const projectionConversationRef = useRef13(null);
10767
10881
  const activeCanonicalLiveTurn = Boolean(
10768
10882
  input.activeTurn && input.activeTurn.phase !== "settled"
10769
10883
  );
@@ -10853,8 +10967,8 @@ function useAgentGUIConversationDetail(input) {
10853
10967
  }
10854
10968
  return conversationModels.conversation;
10855
10969
  }, [conversationDetail, conversationModels.conversation]);
10856
- const diagnosticKeyRef = useRef12(null);
10857
- useEffect9(() => {
10970
+ const diagnosticKeyRef = useRef13(null);
10971
+ useEffect8(() => {
10858
10972
  if (!input.activeConversationId || !conversation) {
10859
10973
  diagnosticKeyRef.current = null;
10860
10974
  return;
@@ -10944,9 +11058,9 @@ function useAgentGUIConversationDetail(input) {
10944
11058
  }
10945
11059
 
10946
11060
  // agent-gui/agentGuiNode/controller/useAgentGUIConversationPresentation.ts
10947
- import { useEffect as useEffect10, useMemo as useMemo12, useRef as useRef13 } from "react";
11061
+ import { useEffect as useEffect9, useMemo as useMemo12, useRef as useRef14 } from "react";
10948
11062
  function useAgentGUIConversationPresentation(input) {
10949
- const visibleConversationsRef = useRef13(
11063
+ const visibleConversationsRef = useRef14(
10950
11064
  null
10951
11065
  );
10952
11066
  const conversationProjection = useMemo12(() => {
@@ -10977,7 +11091,7 @@ function useAgentGUIConversationPresentation(input) {
10977
11091
  input.userProjects
10978
11092
  ]);
10979
11093
  const visibleConversations = conversationProjection.visibleConversations;
10980
- const activeConversationRef = useRef13(
11094
+ const activeConversationRef = useRef14(
10981
11095
  null
10982
11096
  );
10983
11097
  const activeConversation = useMemo12(() => {
@@ -11060,7 +11174,7 @@ function useAgentGUIConversationPresentation(input) {
11060
11174
  conversationProjection.semanticConversations,
11061
11175
  input.workspacePath
11062
11176
  ]);
11063
- useEffect10(() => {
11177
+ useEffect9(() => {
11064
11178
  if (input.previewMode || input.agentTargetsLoading || !input.activeConversationId) {
11065
11179
  return;
11066
11180
  }
@@ -11127,15 +11241,15 @@ function useAgentGUIConversationPresentation(input) {
11127
11241
  // agent-gui/agentGuiNode/controller/useAgentGUIProviderHome.ts
11128
11242
  import {
11129
11243
  useCallback as useCallback21,
11130
- useEffect as useEffect11,
11131
- useRef as useRef14
11244
+ useEffect as useEffect10,
11245
+ useRef as useRef15
11132
11246
  } from "react";
11133
11247
  import {
11134
11248
  selectEngineSession as selectEngineSession5,
11135
11249
  selectEngineSessionDeleted
11136
11250
  } from "@tutti-os/agent-activity-core";
11137
11251
  function useAgentGUIProviderHome(input) {
11138
- const inputRef = useRef14(input);
11252
+ const inputRef = useRef15(input);
11139
11253
  inputRef.current = input;
11140
11254
  const resolveDefaultHomeComposerTarget = useCallback21(() => {
11141
11255
  const current = inputRef.current;
@@ -11274,7 +11388,7 @@ function useAgentGUIProviderHome(input) {
11274
11388
  },
11275
11389
  []
11276
11390
  );
11277
- useEffect11(() => {
11391
+ useEffect10(() => {
11278
11392
  if (input.previewMode || input.activeConversationId !== null || input.conversationFilter.kind !== "all" || input.homeComposerTargetOverride !== null || agentGUINodeDataHasComposerTarget(input.data) || !input.providerReadinessGates || !input.firstReadyHomeComposerProviderTarget) {
11279
11393
  return;
11280
11394
  }
@@ -11400,7 +11514,7 @@ function useAgentGUIProviderHome(input) {
11400
11514
  },
11401
11515
  [selectHomeComposerAgentTarget]
11402
11516
  );
11403
- useEffect11(() => {
11517
+ useEffect10(() => {
11404
11518
  if (input.previewMode || input.agentTargetsLoading || input.activeConversationId === null || input.conversationFilter.kind !== "agentTarget" || input.isLoadingConversations || !input.conversationListInitialized) {
11405
11519
  return;
11406
11520
  }
@@ -11445,7 +11559,7 @@ import {
11445
11559
  selectPlanDecisionForTurn,
11446
11560
  selectPlanTurnDismissed
11447
11561
  } from "@tutti-os/agent-activity-core";
11448
- import { useEffect as useEffect12, useMemo as useMemo13 } from "react";
11562
+ import { useEffect as useEffect11, useMemo as useMemo13 } from "react";
11449
11563
  function useAgentGUISessionPresentation(input) {
11450
11564
  const latestTimelinePlanTurnId = latestPlanTurnId(input.activeTimelineItems);
11451
11565
  const planImplementationTurnId = input.activeConversationId !== null && input.composerSupport.planImplementation && input.composerSupport.plan && input.activeEngineLatestTurn?.phase === "settled" && input.activeEngineLatestTurn.outcome === "completed" && input.activeEngineLatestTurn.turnId === latestTimelinePlanTurnId ? latestTimelinePlanTurnId : null;
@@ -11472,24 +11586,6 @@ function useAgentGUISessionPresentation(input) {
11472
11586
  input.activeConversation?.title ?? ""
11473
11587
  ) : null;
11474
11588
  const pendingInteractivePrompt = input.serverInteractivePrompt ?? planImplementationPrompt;
11475
- useEffect12(() => {
11476
- const provider = normalizeOptionalText(
11477
- input.activeEngineSession?.provider ?? input.activeConversation?.provider
11478
- );
11479
- if (provider === null) return;
11480
- const model = normalizeOptionalText(input.activeSessionState?.settings?.model) ?? normalizeOptionalText(input.activeEngineSession?.settings?.model);
11481
- if (model === null) return;
11482
- input.lastActiveModelByProviderRef.current = {
11483
- ...input.lastActiveModelByProviderRef.current,
11484
- [provider]: model
11485
- };
11486
- }, [
11487
- input.activeConversation?.provider,
11488
- input.activeEngineSession?.provider,
11489
- input.activeEngineSession?.settings?.model,
11490
- input.activeSessionState?.settings?.model,
11491
- input.lastActiveModelByProviderRef
11492
- ]);
11493
11589
  const activeHasPendingSubmittedTurn = Boolean(
11494
11590
  input.activeConversationId && input.activeLatestPendingSubmitTurnId
11495
11591
  );
@@ -11566,7 +11662,7 @@ function useAgentGUISessionPresentation(input) {
11566
11662
  const hasSentUserMessage = input.activeTimelineItems.some(
11567
11663
  (item) => item.role === "user"
11568
11664
  );
11569
- useEffect12(() => {
11665
+ useEffect11(() => {
11570
11666
  const firstVersion = minFiniteMessageVersion(input.activeMessages);
11571
11667
  const lastVersion = maxFiniteMessageVersion(input.activeMessages);
11572
11668
  const diagnosticKey = [
@@ -11849,7 +11945,7 @@ function useAgentGUIViewAssembly(input) {
11849
11945
  }
11850
11946
 
11851
11947
  // agent-gui/agentGuiNode/controller/useAgentGUIProviderCatalogSelection.ts
11852
- import { useEffect as useEffect13, useMemo as useMemo15, useState as useState4 } from "react";
11948
+ import { useEffect as useEffect12, useMemo as useMemo15, useState as useState4 } from "react";
11853
11949
  function useAgentGUIProviderCatalogSelection(input) {
11854
11950
  const {
11855
11951
  comingSoonProviders,
@@ -11983,7 +12079,7 @@ function useAgentGUIProviderCatalogSelection(input) {
11983
12079
  selectedAgentTargetIsExplicit
11984
12080
  ]
11985
12081
  );
11986
- useEffect13(() => {
12082
+ useEffect12(() => {
11987
12083
  if (homeComposerTargetOverride && agentGUIProviderTargetsEqual(
11988
12084
  homeComposerTargetOverride,
11989
12085
  selectedAgentTarget
@@ -12023,7 +12119,7 @@ import {
12023
12119
  selectEngineSessionDeleted as selectEngineSessionDeleted2,
12024
12120
  selectEngineSessionDetailHydrated as selectEngineSessionDetailHydrated2,
12025
12121
  selectEngineSessionDetailLoading,
12026
- selectEngineSessionError,
12122
+ selectEngineSessionOperationError,
12027
12123
  selectEngineSessionIsRespondingToInteraction,
12028
12124
  selectEngineSessionReconcile as selectEngineSessionReconcile2,
12029
12125
  selectEngineSessionSettingsUpdate as selectEngineSessionSettingsUpdate2,
@@ -12110,16 +12206,24 @@ function useAgentGUISessionEngineState(input) {
12110
12206
  sessionEngine,
12111
12207
  (state) => selectEngineLatestTurn(state, activeConversationId)
12112
12208
  );
12209
+ const activeEngineSettingsUpdate = useEngineSelector(
12210
+ sessionEngine,
12211
+ (state) => selectEngineSessionSettingsUpdate2(state, activeConversationId)
12212
+ );
12113
12213
  const activeCanonicalComposerSettings = useMemo16(
12114
- () => ({
12115
- model: activeEngineSession?.settings?.model ?? void 0,
12116
- permissionModeId: activeEngineSession?.settings?.permissionModeId ?? void 0,
12117
- planMode: activeEngineSession?.settings?.planMode ?? void 0,
12118
- browserUse: activeEngineSession?.settings?.browserUse ?? void 0,
12119
- reasoningEffort: activeEngineSession?.settings?.reasoningEffort ?? void 0,
12120
- speed: activeEngineSession?.settings?.speed ?? void 0
12121
- }),
12122
- [activeEngineSession?.settings]
12214
+ () => mergeOptimisticSessionSettings(
12215
+ {
12216
+ model: activeEngineSession?.settings?.model ?? void 0,
12217
+ permissionModeId: activeEngineSession?.settings?.permissionModeId ?? void 0,
12218
+ planMode: activeEngineSession?.settings?.planMode ?? void 0,
12219
+ browserUse: activeEngineSession?.settings?.browserUse ?? void 0,
12220
+ computerUse: activeEngineSession?.settings?.computerUse ?? void 0,
12221
+ reasoningEffort: activeEngineSession?.settings?.reasoningEffort ?? void 0,
12222
+ speed: activeEngineSession?.settings?.speed ?? void 0
12223
+ },
12224
+ activeEngineSettingsUpdate
12225
+ ),
12226
+ [activeEngineSession?.settings, activeEngineSettingsUpdate]
12123
12227
  );
12124
12228
  const activeSessionState = useMemo16(() => {
12125
12229
  if (!activeEngineSession) return null;
@@ -12142,9 +12246,9 @@ function useAgentGUISessionEngineState(input) {
12142
12246
  activeEngineActiveTurn,
12143
12247
  activeEngineSession
12144
12248
  ]);
12145
- const activeEngineLifecycleError = useEngineSelector(
12249
+ const activeEngineOperationError = useEngineSelector(
12146
12250
  sessionEngine,
12147
- (state) => selectEngineSessionError(state, activeConversationId)
12251
+ (state) => selectEngineSessionOperationError(state, activeConversationId)
12148
12252
  );
12149
12253
  const activeEngineQueueError = useEngineSelector(
12150
12254
  sessionEngine,
@@ -12154,11 +12258,7 @@ function useAgentGUISessionEngineState(input) {
12154
12258
  sessionEngine,
12155
12259
  (state) => selectEngineInteractionResponseError(state, activeConversationId)
12156
12260
  );
12157
- const activeEngineSettingsUpdate = useEngineSelector(
12158
- sessionEngine,
12159
- (state) => selectEngineSessionSettingsUpdate2(state, activeConversationId)
12160
- );
12161
- const activeEngineError = activeEngineLifecycleError ?? activeEngineInteractionError ?? activeEngineSettingsUpdate?.errorMessage ?? activeEngineQueueError;
12261
+ const activeEngineError = activeEngineOperationError ?? activeEngineInteractionError ?? activeEngineQueueError;
12162
12262
  const isRespondingToInteraction = useEngineSelector(
12163
12263
  sessionEngine,
12164
12264
  (state) => selectEngineSessionIsRespondingToInteraction(state, activeConversationId)
@@ -12204,6 +12304,27 @@ function useAgentGUISessionEngineState(input) {
12204
12304
  isSubmitting
12205
12305
  };
12206
12306
  }
12307
+ function mergeOptimisticSessionSettings(canonical, update) {
12308
+ if (!update || update.status !== "inFlight" && update.status !== "unknown") {
12309
+ return canonical;
12310
+ }
12311
+ const optimistic = {
12312
+ ...update.settings ?? {},
12313
+ ...update.queuedSettings ?? {}
12314
+ };
12315
+ return {
12316
+ ...canonical,
12317
+ ...typeof optimistic.model === "string" ? { model: optimistic.model } : {},
12318
+ ...typeof optimistic.permissionModeId === "string" ? { permissionModeId: optimistic.permissionModeId } : {},
12319
+ ...typeof optimistic.planMode === "boolean" ? { planMode: optimistic.planMode } : {},
12320
+ ...typeof optimistic.browserUse === "boolean" ? { browserUse: optimistic.browserUse } : {},
12321
+ ...typeof optimistic.computerUse === "boolean" ? { computerUse: optimistic.computerUse } : {},
12322
+ ...typeof optimistic.reasoningEffort === "string" ? {
12323
+ reasoningEffort: optimistic.reasoningEffort
12324
+ } : {},
12325
+ ...typeof optimistic.speed === "string" ? { speed: optimistic.speed } : {}
12326
+ };
12327
+ }
12207
12328
 
12208
12329
  // agent-gui/agentGuiNode/controller/useAgentGUISessionDetailTransport.ts
12209
12330
  import {
@@ -12215,7 +12336,7 @@ import { useCallback as useCallback25, useMemo as useMemo17 } from "react";
12215
12336
  import { useCallback as useCallback24 } from "react";
12216
12337
 
12217
12338
  // contexts/workspace/presentation/renderer/agentSessions/useAgentSessionPagingState.ts
12218
- import { useCallback as useCallback22, useRef as useRef15, useState as useState5 } from "react";
12339
+ import { useCallback as useCallback22, useRef as useRef16, useState as useState5 } from "react";
12219
12340
  var EMPTY_ENTRY = {
12220
12341
  error: null,
12221
12342
  isLoadingMessages: false,
@@ -12223,7 +12344,7 @@ var EMPTY_ENTRY = {
12223
12344
  };
12224
12345
  function useAgentSessionPagingState() {
12225
12346
  const [entries, setEntries] = useState5({});
12226
- const entriesRef = useRef15(entries);
12347
+ const entriesRef = useRef16(entries);
12227
12348
  entriesRef.current = entries;
12228
12349
  const update = useCallback22(
12229
12350
  (ref, updater) => {
@@ -12269,7 +12390,7 @@ function sessionKey(ref) {
12269
12390
  }
12270
12391
 
12271
12392
  // contexts/workspace/presentation/renderer/agentSessions/useAgentSessionTransport.ts
12272
- import { useCallback as useCallback23, useRef as useRef16, useState as useState6 } from "react";
12393
+ import { useCallback as useCallback23, useRef as useRef17, useState as useState6 } from "react";
12273
12394
  var EMPTY_ENTRY2 = {
12274
12395
  olderMessages: [],
12275
12396
  hasOlderMessages: false,
@@ -12277,7 +12398,7 @@ var EMPTY_ENTRY2 = {
12277
12398
  };
12278
12399
  function useAgentSessionTransport() {
12279
12400
  const [entries, setEntries] = useState6({});
12280
- const entriesRef = useRef16(entries);
12401
+ const entriesRef = useRef17(entries);
12281
12402
  entriesRef.current = entries;
12282
12403
  const update = useCallback23(
12283
12404
  (ref, updater) => {
@@ -12554,7 +12675,7 @@ function useAgentGUISessionDetailTransport(input) {
12554
12675
  }
12555
12676
 
12556
12677
  // agent-gui/agentGuiNode/controller/useAgentGUILocalState.ts
12557
- import { useCallback as useCallback26, useRef as useRef17, useState as useState7 } from "react";
12678
+ import { useCallback as useCallback26, useRef as useRef18, useState as useState7 } from "react";
12558
12679
  function useAgentGUILocalState({
12559
12680
  data,
12560
12681
  userProjectsApi
@@ -12574,7 +12695,7 @@ function useAgentGUILocalState({
12574
12695
  data.lastActiveAgentSessionId === null
12575
12696
  );
12576
12697
  const [draftByScopeKey, setDraftByScopeKey] = useState7({});
12577
- const submittedDraftSnapshotsRef = useRef17({});
12698
+ const submittedDraftSnapshotsRef = useRef18({});
12578
12699
  const [draftSettingsBySessionId, setDraftSettingsBySessionId] = useState7({});
12579
12700
  const [isLoadingMessages, setIsLoadingMessages] = useState7(false);
12580
12701
  const [isDeletingConversation, setIsDeletingConversation] = useState7(false);
@@ -12588,7 +12709,7 @@ function useAgentGUILocalState({
12588
12709
  const [detailError, setDetailError] = useState7(null);
12589
12710
  const [goalClearNoticeSequence, setGoalClearNoticeSequence] = useState7(0);
12590
12711
  const [optimisticGoalControl, setOptimisticGoalControl] = useState7(null);
12591
- const railRevealRevisionRef = useRef17(0);
12712
+ const railRevealRevisionRef = useRef18(0);
12592
12713
  const [railRevealRequest, setRailRevealRequest] = useState7(null);
12593
12714
  const clearRailRevealRequest = useCallback26(() => {
12594
12715
  setRailRevealRequest(null);
@@ -12784,9 +12905,9 @@ function useAgentGUINodeController({
12784
12905
  )
12785
12906
  )
12786
12907
  );
12787
- const updateComposerSettingsRef = useRef18(() => {
12908
+ const updateComposerSettingsRef = useRef19(() => {
12788
12909
  });
12789
- const planActionsRef = useRef18({ implement: () => {
12910
+ const planActionsRef = useRef19({ implement: () => {
12790
12911
  }, feedback: () => {
12791
12912
  }, skip: () => {
12792
12913
  } });
@@ -12805,7 +12926,7 @@ function useAgentGUINodeController({
12805
12926
  defaultReasoningEffort,
12806
12927
  providerComposerOptions
12807
12928
  } = composerCapabilities;
12808
- const planImplementationTurnIdRef = useRef18(null);
12929
+ const planImplementationTurnIdRef = useRef19(null);
12809
12930
  const accountProfilesByUserId = useAccountStore(
12810
12931
  (state) => state.profilesByUserId
12811
12932
  );
@@ -12842,6 +12963,7 @@ function useAgentGUINodeController({
12842
12963
  isMountedRef,
12843
12964
  loadDraftComposerOptionsRef,
12844
12965
  onDataChangeRef,
12966
+ onComposerDefaultsAuthorityReloadedRef,
12845
12967
  pendingOpenSessionRequestRef,
12846
12968
  reloadSelectedConversationRef,
12847
12969
  selectedComposerTargetDataRef,
@@ -12915,7 +13037,7 @@ function useAgentGUINodeController({
12915
13037
  },
12916
13038
  []
12917
13039
  );
12918
- useEffect14(() => {
13040
+ useEffect13(() => {
12919
13041
  const api = agentHostApi.userProjects;
12920
13042
  let disposed = false;
12921
13043
  setUserProjectsSnapshot(readAgentGUIUserProjectSnapshot(api));
@@ -12958,7 +13080,7 @@ function useAgentGUINodeController({
12958
13080
  setIsUserProjectMutationPending,
12959
13081
  setUserProjectsSnapshot
12960
13082
  ]);
12961
- useEffect14(() => {
13083
+ useEffect13(() => {
12962
13084
  if (activeConversationId === null && isComposerHome) {
12963
13085
  return;
12964
13086
  }
@@ -13028,7 +13150,7 @@ function useAgentGUINodeController({
13028
13150
  },
13029
13151
  [agentActivityRuntime, workspaceId]
13030
13152
  );
13031
- useEffect14(() => {
13153
+ useEffect13(() => {
13032
13154
  if (previewMode) {
13033
13155
  return;
13034
13156
  }
@@ -13065,7 +13187,7 @@ function useAgentGUINodeController({
13065
13187
  transientConversation,
13066
13188
  workspaceId
13067
13189
  });
13068
- const { loadDraftComposerOptions } = useAgentGUIComposerOptionsSync({
13190
+ const { loadDraftComposerOptions, reloadComposerOptionsForTarget } = useAgentGUIComposerOptionsSync({
13069
13191
  activeConversationId,
13070
13192
  activeConversationIdRef,
13071
13193
  agentActivityRuntime,
@@ -13081,6 +13203,7 @@ function useAgentGUINodeController({
13081
13203
  isCreatingConversation,
13082
13204
  loadDraftComposerOptionsRef,
13083
13205
  loadSessionState,
13206
+ onComposerDefaultsAuthorityReloadedRef,
13084
13207
  previewMode,
13085
13208
  providerComposerOptions,
13086
13209
  reloadSelectedConversation,
@@ -13116,6 +13239,7 @@ function useAgentGUINodeController({
13116
13239
  isExplicitAgentGUIAgentTarget,
13117
13240
  isRespondingToInteraction: activeRelatedIsRespondingToInteraction,
13118
13241
  loadDraftComposerOptions,
13242
+ reloadComposerOptionsForTarget,
13119
13243
  normalizedExplicitProviderTargets,
13120
13244
  normalizedProviderTargets,
13121
13245
  planActionsRef,
@@ -13191,9 +13315,9 @@ function useAgentGUINodeController({
13191
13315
  // agent-gui/agentGuiNode/AgentGUINodeView.tsx
13192
13316
  import {
13193
13317
  useCallback as useCallback55,
13194
- useEffect as useEffect37,
13318
+ useEffect as useEffect36,
13195
13319
  useMemo as useMemo39,
13196
- useRef as useRef46,
13320
+ useRef as useRef47,
13197
13321
  useState as useState36
13198
13322
  } from "react";
13199
13323
  import { TooltipProvider as TooltipProvider4 } from "@tutti-os/ui-system";
@@ -13301,6 +13425,7 @@ var styles = {
13301
13425
  conversationSectionPaginationButton: "agent-gui-node__conversation-section-pagination-button",
13302
13426
  conversationSectionToggle: "agent-gui-node__conversation-section-toggle",
13303
13427
  projectDragImage: "agent-gui-node__project-drag-image",
13428
+ pinnedProjectRailHeader: "agent-gui-node__pinned-project-rail-header",
13304
13429
  conversationSelect: "agent-gui-node__conversation-select",
13305
13430
  conversationStatusGlyph: "agent-gui-node__conversation-status-glyph",
13306
13431
  conversationTime: "agent-gui-node__conversation-time",
@@ -13394,7 +13519,7 @@ var styles = {
13394
13519
  var AgentGUINode_styles_default = styles;
13395
13520
 
13396
13521
  // agent-gui/agentGuiNode/view/agentGUIViewUtils.ts
13397
- import { useCallback as useCallback28, useLayoutEffect, useMemo as useMemo19, useRef as useRef19 } from "react";
13522
+ import { useCallback as useCallback28, useLayoutEffect, useMemo as useMemo19, useRef as useRef20 } from "react";
13398
13523
  function objectRecord(value) {
13399
13524
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
13400
13525
  }
@@ -13412,14 +13537,14 @@ function stringValue3(value) {
13412
13537
  return typeof value === "string" ? value : "";
13413
13538
  }
13414
13539
  function useStableEventCallback(callback) {
13415
- const callbackRef = useRef19(callback);
13540
+ const callbackRef = useRef20(callback);
13416
13541
  useLayoutEffect(() => {
13417
13542
  callbackRef.current = callback;
13418
13543
  }, [callback]);
13419
13544
  return useCallback28((...args) => callbackRef.current(...args), []);
13420
13545
  }
13421
13546
  function useOptionalStableEventCallback(callback) {
13422
- const callbackRef = useRef19(callback);
13547
+ const callbackRef = useRef20(callback);
13423
13548
  useLayoutEffect(() => {
13424
13549
  callbackRef.current = callback;
13425
13550
  }, [callback]);
@@ -13450,7 +13575,7 @@ function conversationPlainTitle(conversation, labels, uiLanguage) {
13450
13575
  }
13451
13576
 
13452
13577
  // agent-gui/agentGuiNode/view/AgentGUIAccountConfig.tsx
13453
- import { memo, useCallback as useCallback29, useEffect as useEffect16, useState as useState9 } from "react";
13578
+ import { memo, useCallback as useCallback29, useEffect as useEffect15, useState as useState9 } from "react";
13454
13579
  import {
13455
13580
  Coins,
13456
13581
  Crown as Crown2,
@@ -13488,7 +13613,7 @@ function AccountMembershipBadge({
13488
13613
 
13489
13614
  // agent-gui/agentGuiNode/AgentProbeUsageFreshness.tsx
13490
13615
  import { RefreshCw } from "lucide-react";
13491
- import { useEffect as useEffect15, useState as useState8 } from "react";
13616
+ import { useEffect as useEffect14, useState as useState8 } from "react";
13492
13617
  import { jsx as jsx12, jsxs as jsxs5 } from "react/jsx-runtime";
13493
13618
  var FRESHNESS_TICK_MS = 2e4;
13494
13619
  function freshnessAgeText(capturedAtUnixMs, nowMs, labels) {
@@ -13522,7 +13647,7 @@ function AgentProbeUsageFreshness({
13522
13647
  setClickSpinNonce((nonce) => nonce + 1);
13523
13648
  onRefresh();
13524
13649
  };
13525
- useEffect15(() => {
13650
+ useEffect14(() => {
13526
13651
  if (!showRelativeTime) {
13527
13652
  return;
13528
13653
  }
@@ -13654,7 +13779,7 @@ var AgentGUIAccountRewardToast = memo(function AgentGUIAccountRewardToast2({
13654
13779
  labels
13655
13780
  }) {
13656
13781
  "use memo";
13657
- useEffect16(() => {
13782
+ useEffect15(() => {
13658
13783
  if (!toast4.visible) {
13659
13784
  return;
13660
13785
  }
@@ -14100,7 +14225,7 @@ import {
14100
14225
  memo as memo4,
14101
14226
  useCallback as useCallback44,
14102
14227
  useMemo as useMemo31,
14103
- useRef as useRef34,
14228
+ useRef as useRef35,
14104
14229
  useState as useState24
14105
14230
  } from "react";
14106
14231
  import { Tooltip as Tooltip5, TooltipContent as TooltipContent5, TooltipTrigger as TooltipTrigger5 } from "@tutti-os/ui-system";
@@ -15669,9 +15794,9 @@ import { Button as Button2 } from "@tutti-os/ui-system";
15669
15794
  import {
15670
15795
  forwardRef as forwardRef2,
15671
15796
  useCallback as useCallback30,
15672
- useEffect as useEffect17,
15797
+ useEffect as useEffect16,
15673
15798
  useImperativeHandle,
15674
- useRef as useRef20
15799
+ useRef as useRef21
15675
15800
  } from "react";
15676
15801
  import {
15677
15802
  motion as motion2,
@@ -15702,7 +15827,7 @@ var CastIcon = forwardRef2(
15702
15827
  }, ref) => {
15703
15828
  const controls = useAnimation();
15704
15829
  const reduceMotion = useReducedMotion();
15705
- const isControlledRef = useRef20(false);
15830
+ const isControlledRef = useRef21(false);
15706
15831
  const startAnimation = useCallback30(() => {
15707
15832
  if (reduceMotion) {
15708
15833
  return;
@@ -15719,7 +15844,7 @@ var CastIcon = forwardRef2(
15719
15844
  stopAnimation
15720
15845
  };
15721
15846
  });
15722
- useEffect17(() => {
15847
+ useEffect16(() => {
15723
15848
  if (active) {
15724
15849
  startAnimation();
15725
15850
  return;
@@ -16022,7 +16147,7 @@ function AgentSessionChrome({
16022
16147
  }
16023
16148
 
16024
16149
  // agent-gui/agentGuiNode/AgentComposer.tsx
16025
- import { useEffect as useEffect28, useRef as useRef31, useState as useState20 } from "react";
16150
+ import { useEffect as useEffect27, useRef as useRef32, useState as useState20 } from "react";
16026
16151
  import { repairMentionPaletteHighlight } from "@tutti-os/ui-rich-text/at-panel";
16027
16152
 
16028
16153
  // agent-gui/agentGuiNode/AgentSlashStatusPanel.tsx
@@ -16153,7 +16278,7 @@ function AgentSlashStatusPanel({
16153
16278
  import { flushSync as flushSync3 } from "react-dom";
16154
16279
  import {
16155
16280
  useCallback as useCallback31,
16156
- useRef as useRef21
16281
+ useRef as useRef22
16157
16282
  } from "react";
16158
16283
 
16159
16284
  // agent-gui/agentGuiNode/composer/composerDraftUtils.ts
@@ -16215,7 +16340,7 @@ function agentComposerDevConsoleDiagnosticSinkEnabled(runtime) {
16215
16340
 
16216
16341
  // agent-gui/agentGuiNode/composer/useComposerDraftAttachments.ts
16217
16342
  function useStableEventCallback2(callback) {
16218
- const callbackRef = useRef21(callback);
16343
+ const callbackRef = useRef22(callback);
16219
16344
  callbackRef.current = callback;
16220
16345
  return useCallback31((...args) => callbackRef.current(...args), []);
16221
16346
  }
@@ -16271,7 +16396,7 @@ function useComposerDraftAttachments({
16271
16396
  return next;
16272
16397
  }
16273
16398
  );
16274
- const openReferencesForEntityRef = useRef21(null);
16399
+ const openReferencesForEntityRef = useRef22(null);
16275
16400
  const handleDraftChange = useStableEventCallback2(
16276
16401
  (nextDraft) => {
16277
16402
  if (isGoalModeActive) {
@@ -17287,8 +17412,8 @@ import {
17287
17412
  // agent-gui/agentGuiNode/composer/AgentComposerChrome.tsx
17288
17413
  import {
17289
17414
  useCallback as useCallback32,
17290
- useEffect as useEffect18,
17291
- useRef as useRef22,
17415
+ useEffect as useEffect17,
17416
+ useRef as useRef23,
17292
17417
  useState as useState10
17293
17418
  } from "react";
17294
17419
  import {
@@ -17336,14 +17461,14 @@ function AgentUsageChip({
17336
17461
  }) {
17337
17462
  "use memo";
17338
17463
  const [usagePopoverOpen, setUsagePopoverOpen] = useState10(false);
17339
- const usagePopoverHoverTimerRef = useRef22(null);
17340
- const usagePopoverContentRef = useRef22(null);
17464
+ const usagePopoverHoverTimerRef = useRef23(null);
17465
+ const usagePopoverContentRef = useRef23(null);
17341
17466
  const clampedPercent = Math.max(0, Math.min(100, percentUsed));
17342
17467
  const chipLabel = labels.usageChipLabel({ percent: clampedPercent });
17343
17468
  const showTokens = usedTokens !== null && totalTokens !== null;
17344
17469
  const usageLevel = agentUsageChipLevel(clampedPercent);
17345
17470
  const ringColor = agentUsageRingColor(usageLevel);
17346
- const usagePopoverCloseTimerRef = useRef22(null);
17471
+ const usagePopoverCloseTimerRef = useRef23(null);
17347
17472
  const clearUsagePopoverHoverTimer = useCallback32(() => {
17348
17473
  if (usagePopoverHoverTimerRef.current) {
17349
17474
  clearTimeout(usagePopoverHoverTimerRef.current);
@@ -17408,7 +17533,7 @@ function AgentUsageChip({
17408
17533
  closeUsagePopover
17409
17534
  ]
17410
17535
  );
17411
- useEffect18(
17536
+ useEffect17(
17412
17537
  () => () => {
17413
17538
  clearUsagePopoverHoverTimer();
17414
17539
  clearUsagePopoverCloseTimer();
@@ -17628,7 +17753,7 @@ function AgentComposerHandoffIcon({
17628
17753
  }) {
17629
17754
  const [isLottieReady, setIsLottieReady] = useState10(false);
17630
17755
  const shouldLoadAnimation = !disabled && isPlaying;
17631
- useEffect18(() => {
17756
+ useEffect17(() => {
17632
17757
  if (!shouldLoadAnimation) {
17633
17758
  return;
17634
17759
  }
@@ -17769,10 +17894,10 @@ function useMentionPaletteFrame(inputShellRef, showFileMentionPalette) {
17769
17894
  import {
17770
17895
  useCallback as useCallback34,
17771
17896
  useMemo as useMemo23,
17772
- useRef as useRef23
17897
+ useRef as useRef24
17773
17898
  } from "react";
17774
17899
  function useStableEventCallback3(callback) {
17775
- const callbackRef = useRef23(callback);
17900
+ const callbackRef = useRef24(callback);
17776
17901
  callbackRef.current = callback;
17777
17902
  return useCallback34((...args) => callbackRef.current(...args), []);
17778
17903
  }
@@ -18192,8 +18317,8 @@ function useComposerSlashActions(input) {
18192
18317
  // agent-gui/agentGuiNode/composer/useComposerMentionActions.ts
18193
18318
  import {
18194
18319
  useCallback as useCallback35,
18195
- useEffect as useEffect19,
18196
- useRef as useRef24
18320
+ useEffect as useEffect18,
18321
+ useRef as useRef25
18197
18322
  } from "react";
18198
18323
  import {
18199
18324
  createMentionPaletteStateAdapter,
@@ -18213,7 +18338,7 @@ function isAgentRichTextImeComposing(event) {
18213
18338
 
18214
18339
  // agent-gui/agentGuiNode/composer/useComposerMentionActions.ts
18215
18340
  function useStableEventCallback4(callback) {
18216
- const callbackRef = useRef24(callback);
18341
+ const callbackRef = useRef25(callback);
18217
18342
  callbackRef.current = callback;
18218
18343
  return useCallback35((...args) => callbackRef.current(...args), []);
18219
18344
  }
@@ -18420,7 +18545,7 @@ function useComposerMentionActions(input) {
18420
18545
  const handlePaletteKeyDown = useStableEventCallback4(
18421
18546
  (event) => handleFileMentionKeyDown(event) || handleSlashPaletteKeyDown(event) || handleSlashCommandMenuKeyDown(event) || handlePlanModeToggleKeyDown(event)
18422
18547
  );
18423
- useEffect19(() => {
18548
+ useEffect18(() => {
18424
18549
  if (!showPalette || workspaceReferencePickerOpen) {
18425
18550
  return;
18426
18551
  }
@@ -18468,12 +18593,12 @@ function useComposerMentionActions(input) {
18468
18593
  },
18469
18594
  [currentUserId, selectedProjectPath, selectedProjectSectionKey, workspaceId]
18470
18595
  );
18471
- useEffect19(() => {
18596
+ useEffect18(() => {
18472
18597
  if (!showFileMentionPalette && shouldCenterMentionHighlight) {
18473
18598
  setShouldCenterMentionHighlight(false);
18474
18599
  }
18475
18600
  }, [shouldCenterMentionHighlight, showFileMentionPalette]);
18476
- useEffect19(() => {
18601
+ useEffect18(() => {
18477
18602
  if (!showFileMentionPalette) {
18478
18603
  return;
18479
18604
  }
@@ -18596,10 +18721,10 @@ function useComposerProviderTargets(input) {
18596
18721
  }
18597
18722
 
18598
18723
  // agent-gui/agentGuiNode/composer/useComposerFocusAndDrop.ts
18599
- import { useCallback as useCallback36, useEffect as useEffect21 } from "react";
18724
+ import { useCallback as useCallback36, useEffect as useEffect20 } from "react";
18600
18725
 
18601
18726
  // agent-gui/agentGuiNode/composer/useComposerFileDrop.ts
18602
- import { useEffect as useEffect20, useState as useState12 } from "react";
18727
+ import { useEffect as useEffect19, useState as useState12 } from "react";
18603
18728
 
18604
18729
  // agent-gui/agentGuiNode/agentRichText/agentRichTextPromptImages.ts
18605
18730
  function imageFilesFromDataTransfer(dataTransfer) {
@@ -18810,7 +18935,7 @@ function useComposerFileDrop({
18810
18935
  }) {
18811
18936
  const [fileDropOverlayHost, setFileDropOverlayHost] = useState12(null);
18812
18937
  const [fileDropOverlayActive, setFileDropOverlayActive] = useState12(false);
18813
- useEffect20(() => {
18938
+ useEffect19(() => {
18814
18939
  const composer = composerRef.current;
18815
18940
  const dropTarget = composer?.closest("#agent-gui-detail") ?? composer;
18816
18941
  if (!dropTarget) {
@@ -19011,7 +19136,7 @@ function useComposerFocusAndDrop(input) {
19011
19136
  scheduleComposerFocus,
19012
19137
  onPromptImagesUnsupported
19013
19138
  });
19014
- useEffect21(() => {
19139
+ useEffect20(() => {
19015
19140
  if (!isActive) {
19016
19141
  wasActiveRef.current = false;
19017
19142
  return;
@@ -19021,7 +19146,7 @@ function useComposerFocusAndDrop(input) {
19021
19146
  }
19022
19147
  wasActiveRef.current = true;
19023
19148
  }, [isActive, scheduleComposerFocus]);
19024
- useEffect21(() => {
19149
+ useEffect20(() => {
19025
19150
  if (composerFocusRequestSequence === null || composerFocusRequestSequence === lastComposerFocusRequestRef.current) {
19026
19151
  return;
19027
19152
  }
@@ -19039,7 +19164,7 @@ function useComposerFocusAndDrop(input) {
19039
19164
  // agent-gui/agentGuiNode/composer/useComposerPresentation.tsx
19040
19165
  import {
19041
19166
  useCallback as useCallback37,
19042
- useEffect as useEffect22,
19167
+ useEffect as useEffect21,
19043
19168
  useState as useState14
19044
19169
  } from "react";
19045
19170
  import { createPortal } from "react-dom";
@@ -19226,7 +19351,7 @@ function useComposerPresentation(input) {
19226
19351
  sendButtonBusy ? "send_busy" : null
19227
19352
  ].filter((reason) => reason !== null);
19228
19353
  const sendDisabledReasonKey = sendDisabledReasons.join(",");
19229
- useEffect22(() => {
19354
+ useEffect21(() => {
19230
19355
  reportAgentComposerDiagnostic(agentActivityRuntime, {
19231
19356
  details: {
19232
19357
  canUploadAttachment,
@@ -19281,7 +19406,7 @@ function useComposerPresentation(input) {
19281
19406
  const effectivePlaceholder = disabledReasonText || placeholder;
19282
19407
  const visibleDraftFiles = draftFiles;
19283
19408
  const visibleDraftLargeTexts = draftLargeTexts;
19284
- useEffect22(() => {
19409
+ useEffect21(() => {
19285
19410
  if (previousSelectedProjectPathRef.current === selectedProjectPath) {
19286
19411
  return;
19287
19412
  }
@@ -19304,7 +19429,7 @@ function useComposerPresentation(input) {
19304
19429
  selectedProjectSectionKey,
19305
19430
  workspaceId
19306
19431
  ]);
19307
- useEffect22(() => {
19432
+ useEffect21(() => {
19308
19433
  setDismissedPromptRequestId(null);
19309
19434
  }, [activePromptRequestId]);
19310
19435
  const submitInteractivePromptAndDismiss = useCallback37(
@@ -19438,7 +19563,7 @@ import {
19438
19563
  import {
19439
19564
  Component as Component2,
19440
19565
  useLayoutEffect as useLayoutEffect4,
19441
- useRef as useRef25,
19566
+ useRef as useRef26,
19442
19567
  useState as useState15
19443
19568
  } from "react";
19444
19569
  import { ChevronRight } from "lucide-react";
@@ -19720,9 +19845,9 @@ function AgentQueuedPromptPanel({
19720
19845
  "use memo";
19721
19846
  const runtime = useOptionalAgentActivityRuntime();
19722
19847
  const [isExpanded, setIsExpanded] = useState15(false);
19723
- const singlePromptTextRef = useRef25(null);
19724
- const queuedPromptListRef = useRef25(null);
19725
- const pointerHandledEditPromptIdRef = useRef25(null);
19848
+ const singlePromptTextRef = useRef26(null);
19849
+ const queuedPromptListRef = useRef26(null);
19850
+ const pointerHandledEditPromptIdRef = useRef26(null);
19726
19851
  const [isSinglePromptOverflowing, setIsSinglePromptOverflowing] = useState15(false);
19727
19852
  const [expandedListMaxHeightPx, setExpandedListMaxHeightPx] = useState15(280);
19728
19853
  const singlePromptHasImages = queuedPrompts.length === 1 && queuedPromptImages(queuedPrompts[0]).length > 0;
@@ -19964,7 +20089,7 @@ function AgentQueuedPromptPanel({
19964
20089
  import {
19965
20090
  Fragment as Fragment6,
19966
20091
  cloneElement,
19967
- useEffect as useEffect23,
20092
+ useEffect as useEffect22,
19968
20093
  useState as useState16
19969
20094
  } from "react";
19970
20095
  import { ChevronDown as ChevronDown2, ZapIcon } from "lucide-react";
@@ -20855,7 +20980,7 @@ function AgentProjectMissingStatusProbe({
20855
20980
  "use memo";
20856
20981
  const agentHostApi = useAgentHostApi();
20857
20982
  const selectedPath = composerSettings.selectedProjectPath?.trim() ?? "";
20858
- useEffect23(() => {
20983
+ useEffect22(() => {
20859
20984
  let canceled = false;
20860
20985
  const userProjects = agentHostApi.userProjects;
20861
20986
  if (!userProjects || !composerSettings.projectLocked || !selectedPath) {
@@ -21226,9 +21351,9 @@ function ComposerModelOptionTooltip({
21226
21351
  import {
21227
21352
  forwardRef as forwardRef3,
21228
21353
  useCallback as useCallback39,
21229
- useEffect as useEffect24,
21354
+ useEffect as useEffect23,
21230
21355
  useMemo as useMemo26,
21231
- useRef as useRef27,
21356
+ useRef as useRef28,
21232
21357
  useState as useState17
21233
21358
  } from "react";
21234
21359
  import { useEditor } from "@tiptap/react";
@@ -21756,7 +21881,7 @@ function useAgentRichTextEditorHandle(input) {
21756
21881
  // agent-gui/agentGuiNode/agentRichText/AgentRichTextEditorSurface.tsx
21757
21882
  import {
21758
21883
  useCallback as useCallback38,
21759
- useRef as useRef26
21884
+ useRef as useRef27
21760
21885
  } from "react";
21761
21886
  import { createPortal as createPortal2 } from "react-dom";
21762
21887
  import { EditorContent } from "@tiptap/react";
@@ -21844,7 +21969,7 @@ function AgentRichTextContextMenuButton({
21844
21969
  label,
21845
21970
  onSelect
21846
21971
  }) {
21847
- const selectionStartedRef = useRef26(false);
21972
+ const selectionStartedRef = useRef27(false);
21848
21973
  const select = useCallback38(() => {
21849
21974
  if (disabled || selectionStartedRef.current) return;
21850
21975
  selectionStartedRef.current = true;
@@ -21946,34 +22071,34 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
21946
22071
  }, ref) {
21947
22072
  "use memo";
21948
22073
  const { t } = useTranslation();
21949
- const lastEmittedPromptRef = useRef27(value);
21950
- const editorRef = useRef27(null);
21951
- const onChangeRef = useRef27(onChange);
21952
- const onFocusRef = useRef27(onFocus);
21953
- const onUserContentChangeRef = useRef27(onUserContentChange);
21954
- const pendingFocusMethodRef = useRef27(null);
21955
- const onSubmitRef = useRef27(onSubmit);
21956
- const onSubmitGuidanceRef = useRef27(onSubmitGuidance);
21957
- const onKeyDownForPaletteRef = useRef27(onKeyDownForPalette);
21958
- const onFileMentionSuggestionChangeRef = useRef27(
22074
+ const lastEmittedPromptRef = useRef28(value);
22075
+ const editorRef = useRef28(null);
22076
+ const onChangeRef = useRef28(onChange);
22077
+ const onFocusRef = useRef28(onFocus);
22078
+ const onUserContentChangeRef = useRef28(onUserContentChange);
22079
+ const pendingFocusMethodRef = useRef28(null);
22080
+ const onSubmitRef = useRef28(onSubmit);
22081
+ const onSubmitGuidanceRef = useRef28(onSubmitGuidance);
22082
+ const onKeyDownForPaletteRef = useRef28(onKeyDownForPalette);
22083
+ const onFileMentionSuggestionChangeRef = useRef28(
21959
22084
  onFileMentionSuggestionChange
21960
22085
  );
21961
- const onFileMentionSuggestionKeyDownRef = useRef27(
22086
+ const onFileMentionSuggestionKeyDownRef = useRef28(
21962
22087
  onFileMentionSuggestionKeyDown
21963
22088
  );
21964
- const onLinkClickRef = useRef27(onLinkClick);
21965
- const onPromptImagesUnsupportedRef = useRef27(onPromptImagesUnsupported);
21966
- const onPasteImagesRef = useRef27(onPasteImages);
21967
- const onPasteLargeTextRef = useRef27(onPasteLargeText);
21968
- const onDropFilesRef = useRef27(onDropFiles);
21969
- const promptImagesSupportedRef = useRef27(promptImagesSupported);
21970
- const getReferenceForFileRef = useRef27(getReferenceForFile);
21971
- const placeholderRef = useRef27(placeholder);
21972
- const removeMentionLabelRef = useRef27(removeMentionLabel);
21973
- const availableSkillsRef = useRef27(availableSkills);
21974
- const availableCapabilitiesRef = useRef27(availableCapabilities);
21975
- const suppressPastedAtSuggestionRef = useRef27(false);
21976
- const scrollFrameRef = useRef27(null);
22089
+ const onLinkClickRef = useRef28(onLinkClick);
22090
+ const onPromptImagesUnsupportedRef = useRef28(onPromptImagesUnsupported);
22091
+ const onPasteImagesRef = useRef28(onPasteImages);
22092
+ const onPasteLargeTextRef = useRef28(onPasteLargeText);
22093
+ const onDropFilesRef = useRef28(onDropFiles);
22094
+ const promptImagesSupportedRef = useRef28(promptImagesSupported);
22095
+ const getReferenceForFileRef = useRef28(getReferenceForFile);
22096
+ const placeholderRef = useRef28(placeholder);
22097
+ const removeMentionLabelRef = useRef28(removeMentionLabel);
22098
+ const availableSkillsRef = useRef28(availableSkills);
22099
+ const availableCapabilitiesRef = useRef28(availableCapabilities);
22100
+ const suppressPastedAtSuggestionRef = useRef28(false);
22101
+ const scrollFrameRef = useRef28(null);
21977
22102
  const [contextMenu, setContextMenu] = useState17(null);
21978
22103
  const closeContextMenu = useCallback39(() => {
21979
22104
  setContextMenu(null);
@@ -22435,7 +22560,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
22435
22560
  submitOnEnter
22436
22561
  });
22437
22562
  };
22438
- useEffect24(
22563
+ useEffect23(
22439
22564
  () => () => {
22440
22565
  if (scrollFrameRef.current !== null && typeof window.cancelAnimationFrame === "function") {
22441
22566
  window.cancelAnimationFrame(scrollFrameRef.current);
@@ -22443,7 +22568,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
22443
22568
  },
22444
22569
  []
22445
22570
  );
22446
- useEffect24(() => {
22571
+ useEffect23(() => {
22447
22572
  if (!contextMenu) {
22448
22573
  return;
22449
22574
  }
@@ -22471,7 +22596,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
22471
22596
  },
22472
22597
  ref
22473
22598
  });
22474
- useEffect24(() => {
22599
+ useEffect23(() => {
22475
22600
  if (!editor) {
22476
22601
  return;
22477
22602
  }
@@ -22482,7 +22607,7 @@ var AgentRichTextEditor = forwardRef3(function AgentRichTextEditor2({
22482
22607
  editor.state.tr.setMeta("agentRichTextPlaceholder", placeholder)
22483
22608
  );
22484
22609
  }, [disabled, editor, placeholder]);
22485
- useEffect24(() => {
22610
+ useEffect23(() => {
22486
22611
  if (!editor || editor.isDestroyed) {
22487
22612
  return;
22488
22613
  }
@@ -22558,7 +22683,7 @@ function AgentReferenceProvenanceFilterControl({
22558
22683
  }
22559
22684
 
22560
22685
  // agent-gui/agentGuiNode/AgentSlashCommandPalette.tsx
22561
- import { Fragment as Fragment8, useEffect as useEffect25, useRef as useRef28 } from "react";
22686
+ import { Fragment as Fragment8, useEffect as useEffect24, useRef as useRef29 } from "react";
22562
22687
  import { Spinner as Spinner3 } from "@tutti-os/ui-system";
22563
22688
  import {
22564
22689
  Globe,
@@ -22605,8 +22730,8 @@ function AgentSlashCommandPalette({
22605
22730
  onSelectSkill
22606
22731
  }) {
22607
22732
  "use memo";
22608
- const highlightedOptionRef = useRef28(null);
22609
- useEffect25(() => {
22733
+ const highlightedOptionRef = useRef29(null);
22734
+ useEffect24(() => {
22610
22735
  highlightedOptionRef.current?.scrollIntoView({ block: "nearest" });
22611
22736
  }, [highlightedIndex]);
22612
22737
  if (entries.length === 0 && !capabilitiesLoading) {
@@ -22806,7 +22931,7 @@ function slashPaletteEntryIcon(entry) {
22806
22931
  }
22807
22932
 
22808
22933
  // agent-gui/agentGuiNode/AgentReviewPickerPanel.tsx
22809
- import { useCallback as useCallback40, useEffect as useEffect26, useMemo as useMemo27, useRef as useRef29, useState as useState18 } from "react";
22934
+ import { useCallback as useCallback40, useEffect as useEffect25, useMemo as useMemo27, useRef as useRef30, useState as useState18 } from "react";
22810
22935
  import { menuItemClassName } from "@tutti-os/ui-system";
22811
22936
 
22812
22937
  // agent-gui/agentGuiNode/AgentReviewBranchController.ts
@@ -22924,9 +23049,9 @@ function AgentReviewPickerPanel({
22924
23049
  const [stage, setStage] = useState18("root");
22925
23050
  const [query, setQuery] = useState18("");
22926
23051
  const [highlightedIndex, setHighlightedIndex] = useState18(0);
22927
- const searchInputRef = useRef29(null);
22928
- const highlightedOptionRef = useRef29(null);
22929
- const reviewBranchControllerRef = useRef29(
23052
+ const searchInputRef = useRef30(null);
23053
+ const highlightedOptionRef = useRef30(null);
23054
+ const reviewBranchControllerRef = useRef30(
22930
23055
  null
22931
23056
  );
22932
23057
  const [branchState, setBranchState] = useState18({
@@ -22935,7 +23060,7 @@ function AgentReviewPickerPanel({
22935
23060
  currentBranch: null,
22936
23061
  error: null
22937
23062
  });
22938
- useEffect26(() => {
23063
+ useEffect25(() => {
22939
23064
  const controller = new AgentReviewBranchController();
22940
23065
  reviewBranchControllerRef.current = controller;
22941
23066
  const unsubscribe = controller.subscribe(setBranchState);
@@ -22945,7 +23070,7 @@ function AgentReviewPickerPanel({
22945
23070
  reviewBranchControllerRef.current = null;
22946
23071
  };
22947
23072
  }, []);
22948
- useEffect26(() => {
23073
+ useEffect25(() => {
22949
23074
  const controller = reviewBranchControllerRef.current;
22950
23075
  if (!controller) {
22951
23076
  return;
@@ -22955,7 +23080,7 @@ function AgentReviewPickerPanel({
22955
23080
  controller.ensureLoaded();
22956
23081
  }
22957
23082
  }, [onRequestGitBranches, stage]);
22958
- useEffect26(() => {
23083
+ useEffect25(() => {
22959
23084
  searchInputRef.current?.focus();
22960
23085
  }, [stage]);
22961
23086
  const submit = useCallback40(
@@ -23045,7 +23170,7 @@ function AgentReviewPickerPanel({
23045
23170
  goToStage
23046
23171
  ]);
23047
23172
  const safeHighlightedIndex = entries.length === 0 ? -1 : Math.min(highlightedIndex, entries.length - 1);
23048
- useEffect26(() => {
23173
+ useEffect25(() => {
23049
23174
  highlightedOptionRef.current?.scrollIntoView({ block: "nearest" });
23050
23175
  }, [safeHighlightedIndex]);
23051
23176
  const searchPlaceholder = stage === "base" ? labels.branchPlaceholder : stage === "commit" ? labels.commitPlaceholder : stage === "custom" ? labels.customPlaceholder : labels.searchPlaceholder;
@@ -23168,10 +23293,10 @@ function AgentReviewPickerPanel({
23168
23293
  import {
23169
23294
  forwardRef as forwardRef4,
23170
23295
  useCallback as useCallback41,
23171
- useEffect as useEffect27,
23296
+ useEffect as useEffect26,
23172
23297
  useLayoutEffect as useLayoutEffect5,
23173
23298
  useMemo as useMemo28,
23174
- useRef as useRef30,
23299
+ useRef as useRef31,
23175
23300
  useState as useState19
23176
23301
  } from "react";
23177
23302
  import { createPortal as createPortal3 } from "react-dom";
@@ -23318,7 +23443,7 @@ var ComposerFloatingMenuSurface = forwardRef4(function ComposerFloatingMenuSurfa
23318
23443
  surfaceRef,
23319
23444
  testId
23320
23445
  }, forwardedRef) {
23321
- const localSurfaceRef = useRef30(null);
23446
+ const localSurfaceRef = useRef31(null);
23322
23447
  const frame = useComposerAnchoredMenuFrame({
23323
23448
  anchorRef,
23324
23449
  maxHeight,
@@ -23336,7 +23461,7 @@ var ComposerFloatingMenuSurface = forwardRef4(function ComposerFloatingMenuSurfa
23336
23461
  },
23337
23462
  [forwardedRef, surfaceRef]
23338
23463
  );
23339
- useEffect27(() => {
23464
+ useEffect26(() => {
23340
23465
  if (!open || !onDismiss) {
23341
23466
  return;
23342
23467
  }
@@ -24770,12 +24895,12 @@ function AgentComposer(props) {
24770
24895
  const [isSelectedProjectMissing, setIsSelectedProjectMissing] = useState20(false);
24771
24896
  const [isSlashStatusPanelOpen, setIsSlashStatusPanelOpen] = useState20(false);
24772
24897
  const slashStatusAgentSessionId = slashStatus?.agentSessionId ?? null;
24773
- const previousSlashStatusAgentSessionIdRef = useRef31(
24898
+ const previousSlashStatusAgentSessionIdRef = useRef32(
24774
24899
  slashStatusAgentSessionId
24775
24900
  );
24776
24901
  const selectedProjectPath = composerSettings.selectedProjectPath?.trim() ?? "";
24777
24902
  const selectedProjectSectionKey = composerSettings.selectedProjectSectionKey?.trim() ?? "";
24778
- const previousSelectedProjectPathRef = useRef31(selectedProjectPath);
24903
+ const previousSelectedProjectPathRef = useRef32(selectedProjectPath);
24779
24904
  const [mentionSearchState, setMentionSearchState] = useState20({
24780
24905
  status: "idle",
24781
24906
  query: "",
@@ -24785,26 +24910,26 @@ function AgentComposer(props) {
24785
24910
  groups: [],
24786
24911
  error: null
24787
24912
  });
24788
- const composerRef = useRef31(null);
24789
- const inputShellRef = useRef31(null);
24790
- const promptInputAreaRef = useRef31(null);
24791
- const paletteContentRef = useRef31(null);
24792
- const draftPromptRef = useRef31(draftPrompt);
24793
- const draftImagesRef = useRef31(draftImages);
24794
- const draftFilesRef = useRef31(draftFiles);
24795
- const draftLargeTextsRef = useRef31(draftLargeTexts);
24796
- const draftByScopeKeyRef = useRef31({
24913
+ const composerRef = useRef32(null);
24914
+ const inputShellRef = useRef32(null);
24915
+ const promptInputAreaRef = useRef32(null);
24916
+ const paletteContentRef = useRef32(null);
24917
+ const draftPromptRef = useRef32(draftPrompt);
24918
+ const draftImagesRef = useRef32(draftImages);
24919
+ const draftFilesRef = useRef32(draftFiles);
24920
+ const draftLargeTextsRef = useRef32(draftLargeTexts);
24921
+ const draftByScopeKeyRef = useRef32({
24797
24922
  [draftScopeKey]: draftContent
24798
24923
  });
24799
24924
  draftByScopeKeyRef.current[draftScopeKey] = draftContent;
24800
- const promptTipRef = useRef31(null);
24801
- const mentionControllerRef = useRef31(
24925
+ const promptTipRef = useRef32(null);
24926
+ const mentionControllerRef = useRef32(
24802
24927
  null
24803
24928
  );
24804
- const editorHandleRef = useRef31(null);
24805
- const wasActiveRef = useRef31(isActive);
24806
- const lastComposerFocusRequestRef = useRef31(null);
24807
- const autoMentionHighlightedKeyRef = useRef31(null);
24929
+ const editorHandleRef = useRef32(null);
24930
+ const wasActiveRef = useRef32(isActive);
24931
+ const lastComposerFocusRequestRef = useRef32(null);
24932
+ const autoMentionHighlightedKeyRef = useRef32(null);
24808
24933
  const [isPromptTipOverflowing, setIsPromptTipOverflowing] = useState20(false);
24809
24934
  const [dockComposerInputHeight, setDockComposerInputHeight] = useState20(
24810
24935
  DOCK_COMPOSER_INPUT_MIN_HEIGHT2
@@ -24853,10 +24978,10 @@ function AgentComposer(props) {
24853
24978
  inputShellRef,
24854
24979
  showFileMentionPalette
24855
24980
  );
24856
- useEffect28(() => {
24981
+ useEffect27(() => {
24857
24982
  setHighlightedIndex(0);
24858
24983
  }, [skillQueryMatch?.prefix, skillQueryMatch?.query, slashQuery]);
24859
- useEffect28(() => {
24984
+ useEffect27(() => {
24860
24985
  const preferredKey = shouldResetMentionHighlightToFilter && mentionSearchState.mode === "browse" ? `category:${mentionSearchState.filter}` : null;
24861
24986
  if (shouldResetMentionHighlightToFilter) {
24862
24987
  const nextKey = repairMentionPaletteHighlight({
@@ -24890,7 +25015,7 @@ function AgentComposer(props) {
24890
25015
  mentionSearchState,
24891
25016
  shouldResetMentionHighlightToFilter
24892
25017
  ]);
24893
- useEffect28(() => {
25018
+ useEffect27(() => {
24894
25019
  const controller = new AgentMentionSearchController({
24895
25020
  contextMentionProviders
24896
25021
  });
@@ -24908,7 +25033,7 @@ function AgentComposer(props) {
24908
25033
  mentionControllerRef.current = null;
24909
25034
  };
24910
25035
  }, [contextMentionProviders]);
24911
- useEffect28(() => {
25036
+ useEffect27(() => {
24912
25037
  draftImagesRef.current = agentComposerDraftImages(draftContent);
24913
25038
  draftFilesRef.current = agentComposerDraftFiles(draftContent);
24914
25039
  draftLargeTextsRef.current = agentComposerDraftLargeTexts(draftContent);
@@ -24923,7 +25048,7 @@ function AgentComposer(props) {
24923
25048
  });
24924
25049
  }
24925
25050
  }, [draftContent, draftPrompt, goalDraftObjective]);
24926
- useEffect28(() => {
25051
+ useEffect27(() => {
24927
25052
  mentionControllerRef.current?.setProvenanceCatalog(
24928
25053
  referenceProvenanceFilter?.snapshot.catalog ?? null
24929
25054
  );
@@ -24934,7 +25059,7 @@ function AgentComposer(props) {
24934
25059
  referenceProvenanceFilter?.snapshot.catalog,
24935
25060
  referenceProvenanceFilter?.snapshot.value
24936
25061
  ]);
24937
- useEffect28(() => {
25062
+ useEffect27(() => {
24938
25063
  if (previousSlashStatusAgentSessionIdRef.current === slashStatusAgentSessionId) {
24939
25064
  return;
24940
25065
  }
@@ -25571,7 +25696,7 @@ import {
25571
25696
  useCallback as useCallback42,
25572
25697
  useContext,
25573
25698
  useMemo as useMemo29,
25574
- useRef as useRef32
25699
+ useRef as useRef33
25575
25700
  } from "react";
25576
25701
  import { toast as toast2 } from "@tutti-os/ui-system";
25577
25702
 
@@ -25659,7 +25784,7 @@ function useCreateAgentTargetSetupController(agentTarget) {
25659
25784
  },
25660
25785
  [agentTargetId, hostApi?.debug]
25661
25786
  );
25662
- const controllerRef = useRef32(null);
25787
+ const controllerRef = useRef33(null);
25663
25788
  const targetKey = enabled ? agentTargetId : "";
25664
25789
  const controllerEntry = useMemo29(() => {
25665
25790
  const previousState = controllerRef.current?.targetKey === targetKey ? controllerRef.current.controller.getSnapshot() : null;
@@ -26504,7 +26629,7 @@ function EmptyHeroTitle({
26504
26629
 
26505
26630
  // agent-gui/agentGuiNode/view/AgentGUIProviderManagerDialog.tsx
26506
26631
  import {
26507
- useRef as useRef33,
26632
+ useRef as useRef34,
26508
26633
  useState as useState22
26509
26634
  } from "react";
26510
26635
  import { CircleMinus, CirclePlus } from "lucide-react";
@@ -26546,12 +26671,12 @@ function AgentGUIProviderManagerDialog({
26546
26671
  null
26547
26672
  );
26548
26673
  const [dragPreview, setDragPreview] = useState22(null);
26549
- const dragStateRef = useRef33(null);
26550
- const dragPreviewRef = useRef33(null);
26674
+ const dragStateRef = useRef34(null);
26675
+ const dragPreviewRef = useRef34(null);
26551
26676
  const [longPressTargetId, setLongPressTargetId] = useState22(
26552
26677
  null
26553
26678
  );
26554
- const longPressOriginRef = useRef33(null);
26679
+ const longPressOriginRef = useRef34(null);
26555
26680
  const finalAvailableAgent = availableTargets.length === 1;
26556
26681
  const showRunningAgentBlocked = (targetId) => {
26557
26682
  const target = targets.find((candidate) => candidate.targetId === targetId);
@@ -27008,7 +27133,7 @@ function AgentGUIProviderManagerDialog({
27008
27133
  }
27009
27134
 
27010
27135
  // agent-gui/agentGuiNode/view/useAgentGUIProviderRailPreferences.ts
27011
- import { useCallback as useCallback43, useEffect as useEffect29, useState as useState23 } from "react";
27136
+ import { useCallback as useCallback43, useEffect as useEffect28, useState as useState23 } from "react";
27012
27137
  function readAgentGUIProviderRailPreferences(storageKey) {
27013
27138
  return parseAgentGUIProviderRailPreferences(
27014
27139
  globalThis.localStorage?.getItem(storageKey)
@@ -27019,7 +27144,7 @@ function useAgentGUIProviderRailPreferences() {
27019
27144
  const [preferences, setPreferences] = useState23(
27020
27145
  () => readAgentGUIProviderRailPreferences(storageKey)
27021
27146
  );
27022
- useEffect29(() => {
27147
+ useEffect28(() => {
27023
27148
  const refreshPreferences = () => {
27024
27149
  setPreferences(readAgentGUIProviderRailPreferences(storageKey));
27025
27150
  };
@@ -27150,7 +27275,7 @@ var AgentGUIProviderRail = memo4(function AgentGUIProviderRail2({
27150
27275
  preferences: providerRailPreferences
27151
27276
  } = useAgentGUIProviderRailPreferences();
27152
27277
  const [dragState, setDragState] = useState24(null);
27153
- const dragStateRef = useRef34(null);
27278
+ const dragStateRef = useRef35(null);
27154
27279
  const setProviderRailDragState = useCallback44(
27155
27280
  (nextDragState) => {
27156
27281
  dragStateRef.current = nextDragState;
@@ -27630,9 +27755,9 @@ import {
27630
27755
  Fragment as Fragment14,
27631
27756
  memo as memo7,
27632
27757
  useCallback as useCallback49,
27633
- useEffect as useEffect30,
27758
+ useEffect as useEffect29,
27634
27759
  useMemo as useMemo33,
27635
- useRef as useRef37,
27760
+ useRef as useRef38,
27636
27761
  useState as useState27
27637
27762
  } from "react";
27638
27763
  import { Button as SystemButton } from "@tutti-os/ui-system";
@@ -27826,6 +27951,31 @@ function planRuntimeRailMembershipRefresh(input) {
27826
27951
  function isConversationRailInitialLoadPending(input) {
27827
27952
  return input.runtimeSectionsEnabled && input.pending && input.sections === null;
27828
27953
  }
27954
+ function isConversationRailProjectPinned(project) {
27955
+ return (project?.pinnedAtUnixMs ?? 0) > 0;
27956
+ }
27957
+ function conversationRailSectionHeaderVisibility(sections, sectionIndex) {
27958
+ const section = sections[sectionIndex];
27959
+ if (!section) {
27960
+ return { showPinnedHeader: false, showProjectsHeader: false };
27961
+ }
27962
+ const sectionIsPinnedProject = section.kind === "project" && isConversationRailProjectPinned(section.project);
27963
+ const precedingSections = sections.slice(0, sectionIndex);
27964
+ return {
27965
+ showPinnedHeader: sectionIsPinnedProject && !precedingSections.some(
27966
+ (candidate) => candidate.kind === "pinned" || candidate.kind === "project" && isConversationRailProjectPinned(candidate.project)
27967
+ ),
27968
+ showProjectsHeader: section.kind !== "pinned" && !sectionIsPinnedProject && !precedingSections.some(
27969
+ (candidate) => candidate.kind === "project" && !isConversationRailProjectPinned(candidate.project)
27970
+ )
27971
+ };
27972
+ }
27973
+ function partitionConversationRailUserProjects(projects) {
27974
+ return [
27975
+ ...projects.filter((project) => project.pinnedAtUnixMs > 0),
27976
+ ...projects.filter((project) => project.pinnedAtUnixMs <= 0)
27977
+ ];
27978
+ }
27829
27979
  function canonicalConversationRailSummaries(conversations) {
27830
27980
  return conversations.filter(
27831
27981
  (conversation) => conversation.projectionSource !== "pending_activation"
@@ -28068,22 +28218,22 @@ function projectConversationsByExactRailSectionKey(input) {
28068
28218
  }
28069
28219
  function projectConversationRailSectionsByExactKey(input) {
28070
28220
  const seen = /* @__PURE__ */ new Set();
28071
- const sections = input.userProjects.flatMap(
28072
- (project) => {
28073
- const sectionKey = project.sectionKey?.trim() ?? "";
28074
- if (!sectionKey || seen.has(sectionKey)) return [];
28075
- seen.add(sectionKey);
28076
- return [
28077
- {
28078
- id: sectionKey,
28079
- kind: "project",
28080
- label: project.label,
28081
- project,
28082
- items: []
28083
- }
28084
- ];
28085
- }
28086
- );
28221
+ const sections = partitionConversationRailUserProjects(
28222
+ input.userProjects
28223
+ ).flatMap((project) => {
28224
+ const sectionKey = project.sectionKey?.trim() ?? "";
28225
+ if (!sectionKey || seen.has(sectionKey)) return [];
28226
+ seen.add(sectionKey);
28227
+ return [
28228
+ {
28229
+ id: sectionKey,
28230
+ kind: "project",
28231
+ label: project.label,
28232
+ project,
28233
+ items: []
28234
+ }
28235
+ ];
28236
+ });
28087
28237
  sections.push({
28088
28238
  id: "conversations",
28089
28239
  kind: "conversations",
@@ -28126,6 +28276,7 @@ function projectRuntimeSectionsToConversationRailMemberships(input) {
28126
28276
  label: section.userProject.label,
28127
28277
  lastUsedAtUnixMs: section.userProject.lastUsedAtUnixMs,
28128
28278
  path: section.userProject.path,
28279
+ pinnedAtUnixMs: section.userProject.pinnedAtUnixMs,
28129
28280
  sectionKey: section.userProject.sectionKey,
28130
28281
  updatedAtUnixMs: section.userProject.updatedAtUnixMs
28131
28282
  } : null;
@@ -28256,7 +28407,7 @@ function conversationSummariesRenderEqual2(left, right) {
28256
28407
  return left.id === right.id && left.agentTargetId === right.agentTargetId && left.provider === right.provider && left.title === right.title && left.titleLeadingMentionKind === right.titleLeadingMentionKind && left.titleFallback === right.titleFallback && left.status === right.status && left.cwd === right.cwd && left.railSectionKey === right.railSectionKey && left.pinnedAtUnixMs === right.pinnedAtUnixMs && left.sortTimeUnixMs === right.sortTimeUnixMs && left.updatedAtUnixMs === right.updatedAtUnixMs && left.projectionSource === right.projectionSource && left.isImported === right.isImported && left.hasUnreadCompletion === right.hasUnreadCompletion && left.unreadCompletionKey === right.unreadCompletionKey && left.needsUserAction === right.needsUserAction && conversationProjectsRenderEqual2(left.project, right.project);
28257
28408
  }
28258
28409
  function conversationProjectsRenderEqual2(left, right) {
28259
- return left === right || (!left || !right ? !left && !right : left.id === right.id && left.path === right.path && left.sectionKey === right.sectionKey && left.label === right.label && left.createdAtUnixMs === right.createdAtUnixMs && left.updatedAtUnixMs === right.updatedAtUnixMs && left.lastUsedAtUnixMs === right.lastUsedAtUnixMs && left.sectionKey === right.sectionKey);
28410
+ return left === right || (!left || !right ? !left && !right : left.id === right.id && left.path === right.path && left.sectionKey === right.sectionKey && left.label === right.label && left.createdAtUnixMs === right.createdAtUnixMs && left.updatedAtUnixMs === right.updatedAtUnixMs && left.lastUsedAtUnixMs === right.lastUsedAtUnixMs && left.pinnedAtUnixMs === right.pinnedAtUnixMs && left.sectionKey === right.sectionKey);
28260
28411
  }
28261
28412
 
28262
28413
  // agent-gui/agentGuiNode/model/agentGuiConversationRailSectionTemplates.ts
@@ -28271,7 +28422,9 @@ function preserveConversationRailSectionTemplates(input) {
28271
28422
  }
28272
28423
  existingById.delete("pinned");
28273
28424
  const projectSectionKeys = /* @__PURE__ */ new Set();
28274
- for (const project of input.userProjects) {
28425
+ for (const project of partitionConversationRailUserProjects(
28426
+ input.userProjects
28427
+ )) {
28275
28428
  const sectionKey = project.sectionKey?.trim() ?? "";
28276
28429
  if (!sectionKey || projectSectionKeys.has(sectionKey)) continue;
28277
28430
  projectSectionKeys.add(sectionKey);
@@ -28424,9 +28577,11 @@ function useAgentGUIProjectDrag(input) {
28424
28577
  runtime.viewport = event.currentTarget.closest("aside")?.querySelector('[data-slot="scroll-area-viewport"]') ?? null;
28425
28578
  const nextDragState = {
28426
28579
  beforeProjectId: projectId,
28580
+ canDrop: false,
28427
28581
  indicator: null,
28428
28582
  indicatorSectionId: null,
28429
- projectId
28583
+ projectId,
28584
+ projectPinned: (section.project?.pinnedAtUnixMs ?? 0) > 0
28430
28585
  };
28431
28586
  runtime.dragState = nextDragState;
28432
28587
  setDragState(nextDragState);
@@ -28453,14 +28608,32 @@ function useAgentGUIProjectDrag(input) {
28453
28608
  const targetId = section.project?.id?.trim() ?? "";
28454
28609
  const currentDragState = runtime.dragState;
28455
28610
  if (!runtime.active || !currentDragState || !targetId) return;
28611
+ const targetPinned = (section.project?.pinnedAtUnixMs ?? 0) > 0;
28612
+ if (targetPinned !== currentDragState.projectPinned) {
28613
+ event.dataTransfer.dropEffect = "none";
28614
+ const nextDragState2 = {
28615
+ ...currentDragState,
28616
+ beforeProjectId: null,
28617
+ canDrop: false,
28618
+ indicator: null,
28619
+ indicatorSectionId: null
28620
+ };
28621
+ runtime.dragState = nextDragState2;
28622
+ setDragState(nextDragState2);
28623
+ return;
28624
+ }
28456
28625
  event.preventDefault();
28457
28626
  event.dataTransfer.dropEffect = "move";
28458
- const targetIndex = input.userProjects.findIndex(
28627
+ const partitionProjects = input.userProjects.filter(
28628
+ (project) => (project.pinnedAtUnixMs ?? 0) > 0 === currentDragState.projectPinned
28629
+ );
28630
+ const targetIndex = partitionProjects.findIndex(
28459
28631
  (project) => project.id === targetId
28460
28632
  );
28461
28633
  const nextDragState = {
28462
28634
  ...currentDragState,
28463
- beforeProjectId: edge === "before" ? targetId : input.userProjects[targetIndex + 1]?.id ?? null,
28635
+ canDrop: true,
28636
+ beforeProjectId: edge === "before" ? targetId : partitionProjects[targetIndex + 1]?.id ?? null,
28464
28637
  indicator: edge,
28465
28638
  indicatorSectionId: section.id
28466
28639
  };
@@ -28474,6 +28647,10 @@ function useAgentGUIProjectDrag(input) {
28474
28647
  async (event) => {
28475
28648
  const currentDragState = runtime.dragState;
28476
28649
  if (!currentDragState || !runtime.active) return;
28650
+ if (!currentDragState.canDrop) {
28651
+ clear();
28652
+ return;
28653
+ }
28477
28654
  event.preventDefault();
28478
28655
  const { beforeProjectId, projectId } = currentDragState;
28479
28656
  clear();
@@ -28535,7 +28712,7 @@ import {
28535
28712
  memo as memo5,
28536
28713
  useCallback as useCallback46,
28537
28714
  useMemo as useMemo32,
28538
- useRef as useRef35,
28715
+ useRef as useRef36,
28539
28716
  useState as useState26
28540
28717
  } from "react";
28541
28718
  import { ExternalLink as ExternalLink2 } from "lucide-react";
@@ -28784,9 +28961,9 @@ var AgentGUIConversationRailItem = memo5(
28784
28961
  [item.id, registerItemElement]
28785
28962
  );
28786
28963
  const [contextMenuResetKey, setContextMenuResetKey] = useState26(0);
28787
- const contextMenuRenameRequestedRef = useRef35(false);
28788
- const contextMenuOpenConversationWindowRequestedRef = useRef35(false);
28789
- const contextMenuCopySessionLinkRequestedRef = useRef35(false);
28964
+ const contextMenuRenameRequestedRef = useRef36(false);
28965
+ const contextMenuOpenConversationWindowRequestedRef = useRef36(false);
28966
+ const contextMenuCopySessionLinkRequestedRef = useRef36(false);
28790
28967
  const agentHostApi = useOptionalAgentHostApi();
28791
28968
  const handleMouseLeave = useCallback46(() => {
28792
28969
  if (isPendingDeleteConversation && !isRailInteractionLocked()) {
@@ -29199,6 +29376,7 @@ var AgentGUIConversationRailSection = memo6(
29199
29376
  isConversationSearchActive,
29200
29377
  isLoadingMoreConversations,
29201
29378
  isRailInteractionLocked,
29379
+ isProjectActionLocked,
29202
29380
  projectDragDisabled,
29203
29381
  projectDragging,
29204
29382
  projectDropIndicator,
@@ -29219,6 +29397,7 @@ var AgentGUIConversationRailSection = memo6(
29219
29397
  onRequestSectionBatchDeletion,
29220
29398
  setPendingProjectAction,
29221
29399
  onToggleConversationPinned,
29400
+ onToggleProjectPinned,
29222
29401
  onMarkConversationUnread,
29223
29402
  onOpenProjectFiles,
29224
29403
  onOpenConversationWindow,
@@ -29234,6 +29413,8 @@ var AgentGUIConversationRailSection = memo6(
29234
29413
  }) {
29235
29414
  "use memo";
29236
29415
  const isProjectSection = section.kind === "project";
29416
+ const projectPinned = (section.project?.pinnedAtUnixMs ?? 0) > 0;
29417
+ const projectId = section.project?.id?.trim() ?? "";
29237
29418
  const pageableItems = section.items.filter(
29238
29419
  (item) => item.projectionSource !== "pending_activation"
29239
29420
  );
@@ -29339,6 +29520,7 @@ var AgentGUIConversationRailSection = memo6(
29339
29520
  type: "button",
29340
29521
  className: AgentGUINode_styles_default.conversationSectionToggle,
29341
29522
  "aria-expanded": !isSectionCollapsed,
29523
+ "aria-label": projectPinned ? labels.pinnedProjectAccessibleName(section.label) : section.label,
29342
29524
  onClick: () => {
29343
29525
  if (!isRailInteractionLocked()) {
29344
29526
  onToggleProjectSectionCollapsed(section.id);
@@ -29428,6 +29610,7 @@ var AgentGUIConversationRailSection = memo6(
29428
29610
  className: AgentGUINode_styles_default.conversationSectionMoreButton,
29429
29611
  "aria-label": labels.projectSectionMoreActions,
29430
29612
  size: "sm",
29613
+ disabled: isProjectActionLocked(),
29431
29614
  children: /* @__PURE__ */ jsx51(MoreHorizontalIcon, { "aria-hidden": "true" })
29432
29615
  }
29433
29616
  )
@@ -29443,6 +29626,7 @@ var AgentGUIConversationRailSection = memo6(
29443
29626
  className: AgentGUINode_styles_default.conversationSectionMoreButton,
29444
29627
  "aria-label": labels.projectSectionMoreActions,
29445
29628
  size: "sm",
29629
+ disabled: isProjectActionLocked(),
29446
29630
  children: /* @__PURE__ */ jsx51(MoreHorizontalIcon, { "aria-hidden": "true" })
29447
29631
  }
29448
29632
  ) })
@@ -29484,6 +29668,18 @@ var AgentGUIConversationRailSection = memo6(
29484
29668
  children: /* @__PURE__ */ jsx51("span", { children: labels.projectSectionViewFiles })
29485
29669
  }
29486
29670
  ),
29671
+ /* @__PURE__ */ jsx51(
29672
+ DropdownMenuItem3,
29673
+ {
29674
+ className: `${AgentGUINode_styles_default.composerMenuItem} nodrag [-webkit-app-region:no-drag]`,
29675
+ disabled: !projectId || isProjectActionLocked(),
29676
+ onSelect: () => {
29677
+ if (!projectId || isProjectActionLocked()) return;
29678
+ void onToggleProjectPinned(projectId, !projectPinned);
29679
+ },
29680
+ children: /* @__PURE__ */ jsx51("span", { children: projectPinned ? labels.unpinProject : labels.pinProject })
29681
+ }
29682
+ ),
29487
29683
  /* @__PURE__ */ jsx51(
29488
29684
  DropdownMenuItem3,
29489
29685
  {
@@ -29501,8 +29697,9 @@ var AgentGUIConversationRailSection = memo6(
29501
29697
  DropdownMenuItem3,
29502
29698
  {
29503
29699
  className: `${AgentGUINode_styles_default.composerMenuItem} nodrag [-webkit-app-region:no-drag]`,
29700
+ disabled: isProjectActionLocked(),
29504
29701
  onSelect: () => {
29505
- if (isRailInteractionLocked()) return;
29702
+ if (isProjectActionLocked()) return;
29506
29703
  const label = projectLabel || projectPath;
29507
29704
  setPendingProjectAction({
29508
29705
  kind: "remove",
@@ -29689,7 +29886,7 @@ function AgentGUIProjectActionConfirmationDialog(props) {
29689
29886
  }
29690
29887
 
29691
29888
  // agent-gui/agentGuiNode/view/useAgentGUIConversationRailViewState.ts
29692
- import { useCallback as useCallback48, useLayoutEffect as useLayoutEffect6, useReducer, useRef as useRef36 } from "react";
29889
+ import { useCallback as useCallback48, useLayoutEffect as useLayoutEffect6, useReducer, useRef as useRef37 } from "react";
29693
29890
  function applyRailScrollNavigation(input) {
29694
29891
  const activeConversationId = input.activeConversationId?.trim() || null;
29695
29892
  const current = input.current.navigationKey === input.navigationKey ? input.current : {
@@ -29735,10 +29932,10 @@ function useAgentGUIConversationRailViewState(input) {
29735
29932
  reduceAgentGUIConversationRailViewState,
29736
29933
  /* @__PURE__ */ new Map()
29737
29934
  );
29738
- const conversationListRef = useRef36(null);
29739
- const conversationItemElementsRef = useRef36(/* @__PURE__ */ new Map());
29740
- const scrollTopByScopeRef = useRef36(/* @__PURE__ */ new Map());
29741
- const navigationRef = useRef36({
29935
+ const conversationListRef = useRef37(null);
29936
+ const conversationItemElementsRef = useRef37(/* @__PURE__ */ new Map());
29937
+ const scrollTopByScopeRef = useRef37(/* @__PURE__ */ new Map());
29938
+ const navigationRef = useRef37({
29742
29939
  handledRevealRevision: 0,
29743
29940
  navigationKey: null,
29744
29941
  phase: "scope-pending"
@@ -29834,7 +30031,7 @@ function useAgentGUIConversationRailViewState(input) {
29834
30031
  import { jsx as jsx53, jsxs as jsxs37 } from "react/jsx-runtime";
29835
30032
  function useDelayedBoolean(value, delayMs) {
29836
30033
  const [delayedValue, setDelayedValue] = useState27(false);
29837
- useEffect30(() => {
30034
+ useEffect29(() => {
29838
30035
  if (!value) {
29839
30036
  setDelayedValue(false);
29840
30037
  return;
@@ -29877,6 +30074,7 @@ var AgentGUIConversationRailPane = memo7(
29877
30074
  selectProjectDirectory,
29878
30075
  onRemoveProject,
29879
30076
  onMoveProject,
30077
+ onToggleProjectPinned,
29880
30078
  onConfirmDeleteProjectConversations,
29881
30079
  onConfirmDeleteConversations,
29882
30080
  onRequestDeleteConversation,
@@ -29891,9 +30089,9 @@ var AgentGUIConversationRailPane = memo7(
29891
30089
  const [isRequestingBatchDeletion, setIsRequestingBatchDeletion] = useState27(false);
29892
30090
  const [openProjectMenuSectionId, setOpenProjectMenuSectionId] = useState27(null);
29893
30091
  const { railSearch } = railQuery;
29894
- const railElementRef = useRef37(null);
29895
- const railActiveConversationRef = useRef37([]);
29896
- const groupedConversationsRef = useRef37(null);
30092
+ const railElementRef = useRef38(null);
30093
+ const railActiveConversationRef = useRef38([]);
30094
+ const groupedConversationsRef = useRef38(null);
29897
30095
  const {
29898
30096
  loadMoreSectionConversations,
29899
30097
  isInteractionLocked,
@@ -30040,6 +30238,9 @@ var AgentGUIConversationRailPane = memo7(
30040
30238
  userProjects
30041
30239
  ]);
30042
30240
  const groupedConversations = groupedConversationResult.groups;
30241
+ const appendProjectRailHeader = groupedConversations.length > 0 && !groupedConversations.some(
30242
+ (section) => section.kind !== "pinned" && !(section.kind === "project" && isConversationRailProjectPinned(section.project))
30243
+ );
30043
30244
  const railViewScopeKey = agentGUIConversationRailViewScopeKey({
30044
30245
  conversationFilter,
30045
30246
  sectionAgentTargetFallbackId,
@@ -30116,7 +30317,7 @@ var AgentGUIConversationRailPane = memo7(
30116
30317
  userProjects
30117
30318
  });
30118
30319
  const projectDragLocked = projectDragBaseLocked || isProjectMovePending;
30119
- useEffect30(() => {
30320
+ useEffect29(() => {
30120
30321
  const cleanupProjectDrag = installProjectDragGlobalListeners();
30121
30322
  const timer = window.setInterval(() => {
30122
30323
  setCurrentTimeMs(Date.now());
@@ -30183,104 +30384,124 @@ var AgentGUIConversationRailPane = memo7(
30183
30384
  children: labels.retrySearch
30184
30385
  }
30185
30386
  )
30186
- ] }) : shouldShowConversationEmptyState ? /* @__PURE__ */ jsx53("div", { className: AgentGUINode_styles_default.emptyState, children: /* @__PURE__ */ jsx53("span", { children: conversationQuery.trim() ? labels.searchNoConversations : conversations.length === 0 ? labels.noConversations : labels.conversationUnavailable }) }) : /* @__PURE__ */ jsx53("fieldset", { className: "contents", disabled: railInteractionsLocked, children: groupedConversations.map((section, sectionIndex) => {
30187
- const projectPath = section.kind === "project" ? section.project?.path ?? "" : "";
30188
- const projectLabel = section.kind === "project" ? section.label : "";
30189
- const isProjectSection = section.kind === "project";
30190
- const showProjectRailHeader = !conversationQuery.trim() && section.kind !== "pinned" && (sectionIndex === 0 || groupedConversations[sectionIndex - 1]?.kind === "pinned");
30191
- const isSectionCollapsed = isProjectSection && railViewState.collapsedSectionIds.has(section.id);
30192
- const sectionPageState = sectionPageStates.get(section.id);
30193
- const searchSectionHasMore = backendSearchActive && sectionIndex === groupedConversations.length - 1 && railSearch.hasMore;
30194
- const activeOverlayConversation = !backendSearchActive && railActiveOverlay?.sectionId === section.id && (!conversationQuery.trim() || filteredConversations.some(
30195
- (conversation) => conversation.id === railActiveOverlay.conversation.id
30196
- )) ? railActiveOverlay.conversation : null;
30197
- const activeOverlayIsCanonical = Boolean(
30198
- activeOverlayConversation && section.items.some(
30199
- (item) => item.projectionSource !== "pending_activation" && item.id === activeOverlayConversation.id
30200
- )
30201
- );
30202
- const activeOverlayCountsTowardTotal = Boolean(
30203
- activeOverlayConversation && activeOverlayConversation.projectionSource !== "pending_activation" && matchesAgentGUIConversationSummaryFilter(
30204
- activeOverlayConversation,
30205
- conversationFilter
30206
- )
30207
- );
30208
- const sectionTotalCount = backendSearchActive ? section.items.length + (searchSectionHasMore ? 1 : 0) : sectionPageState?.totalCount ?? section.items.filter(
30209
- (item) => item.projectionSource !== "pending_activation"
30210
- ).length + (activeOverlayCountsTowardTotal && !activeOverlayIsCanonical ? 1 : 0);
30211
- const sectionHasMore = searchSectionHasMore || !conversationQuery.trim() && sectionPageState?.hasMore === true;
30212
- return /* @__PURE__ */ jsxs37(Fragment14, { children: [
30213
- showProjectRailHeader ? /* @__PURE__ */ jsx53(
30214
- AgentGUIProjectRailHeader,
30215
- {
30216
- disabled: railInteractionsLocked,
30217
- labels,
30218
- selectProjectDirectory,
30219
- workspaceUserProjectI18n
30220
- }
30221
- ) : null,
30222
- /* @__PURE__ */ jsx53(
30223
- AgentGUIConversationRailSection,
30224
- {
30225
- activeConversation: activeOverlayConversation,
30226
- activeConversationCountsTowardTotal: activeOverlayCountsTowardTotal,
30227
- activeConversationId,
30228
- createConversationDisabled,
30229
- currentTimeMs,
30230
- isDeletingConversation,
30231
- isDeletingProjectConversations,
30232
- isRequestingBatchDeletion,
30233
- isConversationSearchActive: Boolean(
30234
- conversationQuery.trim()
30235
- ),
30236
- isLoadingMoreConversations: backendSearchActive ? railSearch.loadingMore : sectionPageState?.isLoading ?? false,
30237
- isRailInteractionLocked: isInteractionLocked,
30238
- projectDragDisabled: projectDragLocked,
30239
- projectDragging: projectDragState !== null && projectDragState.projectId === section.project?.id,
30240
- projectDropIndicator: projectDragState?.indicatorSectionId === section.id ? projectDragState.indicator : null,
30241
- isSectionCollapsed,
30242
- labels,
30243
- pendingDeleteConversationId,
30244
- previewMode,
30245
- projectLabel,
30246
- projectPath,
30247
- registerItemElement: railViewState.registerConversationItemElement,
30248
- section,
30249
- sectionHasMore,
30250
- sectionTotalCount,
30251
- visibleItemLimit: railViewState.visibleItemLimitForSection(
30252
- section.id
30253
- ),
30254
- uiLanguage,
30255
- workspaceId,
30256
- onCancelDeleteConversation,
30257
- onConfirmDeleteConversation,
30258
- onCreateConversation,
30259
- onLoadMoreConversations: backendSearchActive ? railSearch.loadMore : loadMoreSectionConversations,
30260
- onRequestDeleteConversation,
30261
- onRequestRenameConversation,
30262
- onSelectConversation,
30263
- onRequestSectionBatchDeletion: requestSectionBatchDeletion,
30264
- setPendingProjectAction,
30265
- onToggleConversationPinned,
30266
- onMarkConversationUnread,
30267
- onOpenProjectFiles,
30268
- onOpenConversationWindow,
30269
- onToggleProjectSectionCollapsed: railViewState.toggleProjectSectionCollapsed,
30270
- onVisibleItemLimitChange: railViewState.setSectionVisibleItemLimit,
30271
- onProjectDragStart: startProjectDrag,
30272
- onProjectDragEnd: clearProjectDrag,
30273
- onProjectDragOver: updateProjectDropTarget,
30274
- onProjectDrop: dropProject,
30275
- onProjectMenuOpenChange: (open) => {
30276
- setOpenProjectMenuSectionId(
30277
- (current) => open ? section.id : current === section.id ? null : current
30278
- );
30387
+ ] }) : shouldShowConversationEmptyState ? /* @__PURE__ */ jsx53("div", { className: AgentGUINode_styles_default.emptyState, children: /* @__PURE__ */ jsx53("span", { children: conversationQuery.trim() ? labels.searchNoConversations : conversations.length === 0 ? labels.noConversations : labels.conversationUnavailable }) }) : /* @__PURE__ */ jsxs37("fieldset", { className: "contents", disabled: railInteractionsLocked, children: [
30388
+ groupedConversations.map((section, sectionIndex) => {
30389
+ const projectPath = section.kind === "project" ? section.project?.path ?? "" : "";
30390
+ const projectLabel = section.kind === "project" ? section.label : "";
30391
+ const isProjectSection = section.kind === "project";
30392
+ const {
30393
+ showPinnedHeader: showPinnedProjectHeader,
30394
+ showProjectsHeader: showProjectRailHeader
30395
+ } = conversationRailSectionHeaderVisibility(
30396
+ groupedConversations,
30397
+ sectionIndex
30398
+ );
30399
+ const isSectionCollapsed = isProjectSection && railViewState.collapsedSectionIds.has(section.id);
30400
+ const sectionPageState = sectionPageStates.get(section.id);
30401
+ const searchSectionHasMore = backendSearchActive && sectionIndex === groupedConversations.length - 1 && railSearch.hasMore;
30402
+ const activeOverlayConversation = !backendSearchActive && railActiveOverlay?.sectionId === section.id && (!conversationQuery.trim() || filteredConversations.some(
30403
+ (conversation) => conversation.id === railActiveOverlay.conversation.id
30404
+ )) ? railActiveOverlay.conversation : null;
30405
+ const activeOverlayIsCanonical = Boolean(
30406
+ activeOverlayConversation && section.items.some(
30407
+ (item) => item.projectionSource !== "pending_activation" && item.id === activeOverlayConversation.id
30408
+ )
30409
+ );
30410
+ const activeOverlayCountsTowardTotal = Boolean(
30411
+ activeOverlayConversation && activeOverlayConversation.projectionSource !== "pending_activation" && matchesAgentGUIConversationSummaryFilter(
30412
+ activeOverlayConversation,
30413
+ conversationFilter
30414
+ )
30415
+ );
30416
+ const sectionTotalCount = backendSearchActive ? section.items.length + (searchSectionHasMore ? 1 : 0) : sectionPageState?.totalCount ?? section.items.filter(
30417
+ (item) => item.projectionSource !== "pending_activation"
30418
+ ).length + (activeOverlayCountsTowardTotal && !activeOverlayIsCanonical ? 1 : 0);
30419
+ const sectionHasMore = searchSectionHasMore || !conversationQuery.trim() && sectionPageState?.hasMore === true;
30420
+ return /* @__PURE__ */ jsxs37(Fragment14, { children: [
30421
+ showPinnedProjectHeader ? /* @__PURE__ */ jsx53("div", { className: AgentGUINode_styles_default.pinnedProjectRailHeader, children: labels.sectionPinned }) : null,
30422
+ showProjectRailHeader ? /* @__PURE__ */ jsx53(
30423
+ AgentGUIProjectRailHeader,
30424
+ {
30425
+ disabled: railInteractionsLocked || isUserProjectMutationPending,
30426
+ labels,
30427
+ selectProjectDirectory,
30428
+ workspaceUserProjectI18n
30279
30429
  }
30280
- }
30281
- )
30282
- ] }, section.id);
30283
- }) })
30430
+ ) : null,
30431
+ /* @__PURE__ */ jsx53(
30432
+ AgentGUIConversationRailSection,
30433
+ {
30434
+ activeConversation: activeOverlayConversation,
30435
+ activeConversationCountsTowardTotal: activeOverlayCountsTowardTotal,
30436
+ activeConversationId,
30437
+ createConversationDisabled,
30438
+ currentTimeMs,
30439
+ isDeletingConversation,
30440
+ isDeletingProjectConversations,
30441
+ isRequestingBatchDeletion,
30442
+ isConversationSearchActive: Boolean(
30443
+ conversationQuery.trim()
30444
+ ),
30445
+ isLoadingMoreConversations: backendSearchActive ? railSearch.loadingMore : sectionPageState?.isLoading ?? false,
30446
+ isRailInteractionLocked: isInteractionLocked,
30447
+ isProjectActionLocked: () => isInteractionLocked() || isUserProjectMutationPending,
30448
+ projectDragDisabled: projectDragLocked,
30449
+ projectDragging: projectDragState !== null && projectDragState.projectId === section.project?.id,
30450
+ projectDropIndicator: projectDragState?.indicatorSectionId === section.id ? projectDragState.indicator : null,
30451
+ isSectionCollapsed,
30452
+ labels,
30453
+ pendingDeleteConversationId,
30454
+ previewMode,
30455
+ projectLabel,
30456
+ projectPath,
30457
+ registerItemElement: railViewState.registerConversationItemElement,
30458
+ section,
30459
+ sectionHasMore,
30460
+ sectionTotalCount,
30461
+ visibleItemLimit: railViewState.visibleItemLimitForSection(
30462
+ section.id
30463
+ ),
30464
+ uiLanguage,
30465
+ workspaceId,
30466
+ onCancelDeleteConversation,
30467
+ onConfirmDeleteConversation,
30468
+ onCreateConversation,
30469
+ onLoadMoreConversations: backendSearchActive ? railSearch.loadMore : loadMoreSectionConversations,
30470
+ onRequestDeleteConversation,
30471
+ onRequestRenameConversation,
30472
+ onSelectConversation,
30473
+ onRequestSectionBatchDeletion: requestSectionBatchDeletion,
30474
+ setPendingProjectAction,
30475
+ onToggleConversationPinned,
30476
+ onToggleProjectPinned,
30477
+ onMarkConversationUnread,
30478
+ onOpenProjectFiles,
30479
+ onOpenConversationWindow,
30480
+ onToggleProjectSectionCollapsed: railViewState.toggleProjectSectionCollapsed,
30481
+ onVisibleItemLimitChange: railViewState.setSectionVisibleItemLimit,
30482
+ onProjectDragStart: startProjectDrag,
30483
+ onProjectDragEnd: clearProjectDrag,
30484
+ onProjectDragOver: updateProjectDropTarget,
30485
+ onProjectDrop: dropProject,
30486
+ onProjectMenuOpenChange: (open) => {
30487
+ setOpenProjectMenuSectionId(
30488
+ (current) => open ? section.id : current === section.id ? null : current
30489
+ );
30490
+ }
30491
+ }
30492
+ )
30493
+ ] }, section.id);
30494
+ }),
30495
+ appendProjectRailHeader ? /* @__PURE__ */ jsx53(
30496
+ AgentGUIProjectRailHeader,
30497
+ {
30498
+ disabled: railInteractionsLocked || isUserProjectMutationPending,
30499
+ labels,
30500
+ selectProjectDirectory,
30501
+ workspaceUserProjectI18n
30502
+ }
30503
+ ) : null
30504
+ ] })
30284
30505
  }
30285
30506
  ),
30286
30507
  footer ? /* @__PURE__ */ jsx53("div", { className: "shrink-0 pb-2", children: footer }) : null,
@@ -30303,7 +30524,7 @@ var AgentGUIConversationRailPane = memo7(
30303
30524
  );
30304
30525
 
30305
30526
  // agent-gui/agentGuiNode/controller/useAgentGUIConversationRailQuery.ts
30306
- import { useEffect as useEffect31, useMemo as useMemo34, useRef as useRef38 } from "react";
30527
+ import { useEffect as useEffect30, useMemo as useMemo34, useRef as useRef39 } from "react";
30307
30528
 
30308
30529
  // agent-gui/agentGuiNode/controller/agentGuiConversationRailDiagnostics.ts
30309
30530
  var CONVERSATION_RAIL_SLOW_DIAGNOSTIC_THRESHOLD_MS = 250;
@@ -31400,7 +31621,7 @@ function useAgentGUIConversationRailQuery({
31400
31621
  () => runtime.getSessionEngine(workspaceId),
31401
31622
  [runtime, workspaceId]
31402
31623
  );
31403
- const activeConversationIdRef = useRef38(activeConversationId);
31624
+ const activeConversationIdRef = useRef39(activeConversationId);
31404
31625
  activeConversationIdRef.current = activeConversationId;
31405
31626
  const controller = useMemo34(
31406
31627
  () => new AgentGUIConversationRailQueryController({
@@ -31411,8 +31632,8 @@ function useAgentGUIConversationRailQuery({
31411
31632
  }),
31412
31633
  [engine, runtime, workspaceId]
31413
31634
  );
31414
- useEffect31(() => controller.attach(), [controller]);
31415
- useEffect31(() => {
31635
+ useEffect30(() => controller.attach(), [controller]);
31636
+ useEffect30(() => {
31416
31637
  controller.configure({
31417
31638
  conversationFilter,
31418
31639
  previewMode,
@@ -31498,15 +31719,15 @@ var AgentGUIConversationRailController = memo8(
31498
31719
  import {
31499
31720
  memo as memo12,
31500
31721
  useCallback as useCallback51,
31501
- useEffect as useEffect34,
31722
+ useEffect as useEffect33,
31502
31723
  useMemo as useMemo36,
31503
- useRef as useRef41,
31724
+ useRef as useRef42,
31504
31725
  useState as useState33
31505
31726
  } from "react";
31506
31727
  import { ScrollArea as ScrollArea2 } from "@tutti-os/ui-system/components";
31507
31728
 
31508
31729
  // agent-gui/agentGuiNode/view/agentGUIDetailModelHelpers.ts
31509
- import { useRef as useRef39 } from "react";
31730
+ import { useRef as useRef40 } from "react";
31510
31731
  function commandAppSource(command) {
31511
31732
  if (!command || typeof command !== "object" || !("source" in command)) {
31512
31733
  return null;
@@ -31586,7 +31807,7 @@ function slashStatusesEqual(left, right) {
31586
31807
  return (left.agentSessionId ?? null) === (right.agentSessionId ?? null) && (left.baseUrl ?? null) === (right.baseUrl ?? null) && (left.contextWindow?.usedTokens ?? null) === (right.contextWindow?.usedTokens ?? null) && (left.contextWindow?.totalTokens ?? null) === (right.contextWindow?.totalTokens ?? null) && slashStatusLimitsEqual(left.limits, right.limits) && Boolean(left.limitsLoading) === Boolean(right.limitsLoading) && Boolean(left.limitsUnavailable) === Boolean(right.limitsUnavailable);
31587
31808
  }
31588
31809
  function useStableSlashStatus(status) {
31589
- const statusRef = useRef39(null);
31810
+ const statusRef = useRef40(null);
31590
31811
  if (statusRef.current === null || !slashStatusesEqual(statusRef.current, status)) {
31591
31812
  statusRef.current = status;
31592
31813
  }
@@ -31676,7 +31897,7 @@ import { ChevronsDown } from "lucide-react";
31676
31897
  import { cn as cn7 } from "@tutti-os/ui-system";
31677
31898
 
31678
31899
  // agent-gui/agentGuiNode/AgentGoalBanner.tsx
31679
- import { useEffect as useEffect32, useState as useState29 } from "react";
31900
+ import { useEffect as useEffect31, useState as useState29 } from "react";
31680
31901
  import { CirclePause, CirclePlay, Pencil as Pencil2, Target as Target3, Trash2 } from "lucide-react";
31681
31902
  import { jsx as jsx55, jsxs as jsxs38 } from "react/jsx-runtime";
31682
31903
  var RESUMABLE_GOAL_STATUSES = /* @__PURE__ */ new Set([
@@ -31757,7 +31978,7 @@ function AgentGoalBanner({
31757
31978
  const isActive = normalizedStatus === "" || normalizedStatus === "active";
31758
31979
  const serverSeconds = optimistic ? null : typeof durationMs === "number" && durationMs >= 0 ? Math.floor(durationMs / 1e3) : isActive ? 0 : null;
31759
31980
  const [localElapsed, setLocalElapsed] = useState29(0);
31760
- useEffect32(() => {
31981
+ useEffect31(() => {
31761
31982
  setLocalElapsed(0);
31762
31983
  if (!isActive || serverSeconds === null) {
31763
31984
  return;
@@ -32191,9 +32412,9 @@ function setTimelineScrollTopWithUserTransition(element, top) {
32191
32412
  // agent-gui/agentGuiNode/view/useAgentGUIDetailScroll.ts
32192
32413
  import {
32193
32414
  useCallback as useCallback50,
32194
- useEffect as useEffect33,
32415
+ useEffect as useEffect32,
32195
32416
  useLayoutEffect as useLayoutEffect7,
32196
- useRef as useRef40,
32417
+ useRef as useRef41,
32197
32418
  useState as useState31
32198
32419
  } from "react";
32199
32420
  var AGENT_GUI_STICK_TO_BOTTOM_THRESHOLD_PX = 24;
@@ -32215,8 +32436,8 @@ function useAgentGUIDetailScroll(input) {
32215
32436
  } = input;
32216
32437
  const [isTimelineScrolledToTop, setIsTimelineScrolledToTop] = useState31(true);
32217
32438
  const [isTimelineScrolledToBottom, setIsTimelineScrolledToBottom] = useState31(true);
32218
- const bottomLockOwnerRef = useRef40(null);
32219
- const userScrollAwayIntentConversationRef = useRef40(null);
32439
+ const bottomLockOwnerRef = useRef41(null);
32440
+ const userScrollAwayIntentConversationRef = useRef41(null);
32220
32441
  useLayoutEffect7(() => {
32221
32442
  const timeline = timelineRef.current;
32222
32443
  if (!timeline) {
@@ -32422,7 +32643,7 @@ function useAgentGUIDetailScroll(input) {
32422
32643
  timelineConversationId,
32423
32644
  viewModel.rail.activeConversationId
32424
32645
  ]);
32425
- useEffect33(() => {
32646
+ useEffect32(() => {
32426
32647
  const timeline = timelineRef.current;
32427
32648
  const activeConversationId = timelineConversationId;
32428
32649
  if (!timeline || !activeConversationId) {
@@ -33209,11 +33430,11 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
33209
33430
  renderProviderUnavailableState
33210
33431
  }) {
33211
33432
  "use memo";
33212
- const timelineRef = useRef41(null);
33213
- const bottomDockRef = useRef41(null);
33214
- const timelineScrollAnchorRef = useRef41(null);
33215
- const submittedPromptScrollConversationRef = useRef41(null);
33216
- const pendingPrependScrollAnchorRef = useRef41(null);
33433
+ const timelineRef = useRef42(null);
33434
+ const bottomDockRef = useRef42(null);
33435
+ const timelineScrollAnchorRef = useRef42(null);
33436
+ const submittedPromptScrollConversationRef = useRef42(null);
33437
+ const pendingPrependScrollAnchorRef = useRef42(null);
33217
33438
  const [
33218
33439
  bottomDockDismissedPromptRequestId,
33219
33440
  setBottomDockDismissedPromptRequestId
@@ -33563,7 +33784,7 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
33563
33784
  viewModel.composer.drainingQueuedPromptId ?? "",
33564
33785
  viewModel.interaction.isRespondingApproval ? "1" : "0"
33565
33786
  ].join("|");
33566
- useEffect34(() => {
33787
+ useEffect33(() => {
33567
33788
  setBottomDockDismissedPromptRequestId(null);
33568
33789
  }, [activePromptRequestId]);
33569
33790
  const {
@@ -33702,7 +33923,7 @@ var AgentGUIDetailPane = memo12(function AgentGUIDetailPane2({
33702
33923
  });
33703
33924
 
33704
33925
  // agent-gui/agentGuiNode/view/AgentGUIRenameConversationDialog.tsx
33705
- import { memo as memo13, useCallback as useCallback52, useEffect as useEffect35, useRef as useRef42, useState as useState34 } from "react";
33926
+ import { memo as memo13, useCallback as useCallback52, useEffect as useEffect34, useRef as useRef43, useState as useState34 } from "react";
33706
33927
  import { ConfirmationDialog as ConfirmationDialog3, Input as Input2 } from "@tutti-os/ui-system";
33707
33928
  import { jsx as jsx63, jsxs as jsxs45 } from "react/jsx-runtime";
33708
33929
  var AgentGUIRenameConversationDialog = memo13(
@@ -33716,11 +33937,11 @@ var AgentGUIRenameConversationDialog = memo13(
33716
33937
  "use memo";
33717
33938
  const [title, setTitle] = useState34("");
33718
33939
  const [isSaving, setIsSaving] = useState34(false);
33719
- const isSavingRef = useRef42(false);
33720
- const armedPointerActionRef = useRef42(null);
33721
- const inputRef = useRef42(null);
33940
+ const isSavingRef = useRef43(false);
33941
+ const armedPointerActionRef = useRef43(null);
33942
+ const inputRef = useRef43(null);
33722
33943
  const trimmedTitle = title.trim();
33723
- useEffect35(() => {
33944
+ useEffect34(() => {
33724
33945
  if (!open || !conversation) {
33725
33946
  isSavingRef.current = false;
33726
33947
  armedPointerActionRef.current = null;
@@ -33730,7 +33951,7 @@ var AgentGUIRenameConversationDialog = memo13(
33730
33951
  }
33731
33952
  setTitle(conversation.title);
33732
33953
  }, [conversation, open]);
33733
- useEffect35(() => {
33954
+ useEffect34(() => {
33734
33955
  if (!open) {
33735
33956
  return;
33736
33957
  }
@@ -33997,7 +34218,7 @@ function AgentTargetSetupRoot({
33997
34218
  }
33998
34219
 
33999
34220
  // agent-gui/agentGuiNode/view/useAgentGUIWorkspaceReferencePicker.ts
34000
- import { useCallback as useCallback54, useMemo as useMemo38, useRef as useRef43, useState as useState35 } from "react";
34221
+ import { useCallback as useCallback54, useMemo as useMemo38, useRef as useRef44, useState as useState35 } from "react";
34001
34222
  import { createRichTextMentionHref } from "@tutti-os/ui-rich-text/core";
34002
34223
  function useAgentGUIWorkspaceReferencePicker(input) {
34003
34224
  const {
@@ -34012,7 +34233,7 @@ function useAgentGUIWorkspaceReferencePicker(input) {
34012
34233
  } = input;
34013
34234
  const [workspaceReferencePickerOpen, setWorkspaceReferencePickerOpen] = useState35(false);
34014
34235
  const [workspaceReferencePickerTarget, setWorkspaceReferencePickerTarget] = useState35(null);
34015
- const workspaceReferencePickerResolverRef = useRef43(null);
34236
+ const workspaceReferencePickerResolverRef = useRef44(null);
34016
34237
  const emptyReferencePickResult = useMemo38(
34017
34238
  () => ({ files: [], mentionItems: [] }),
34018
34239
  []
@@ -34127,7 +34348,7 @@ function useAgentGUIWorkspaceReferencePicker(input) {
34127
34348
  }
34128
34349
 
34129
34350
  // agent-gui/agentGuiNode/engagement/useAgentGUINodeEngagement.ts
34130
- import { useRef as useRef45 } from "react";
34351
+ import { useRef as useRef46 } from "react";
34131
34352
 
34132
34353
  // agent-gui/agentGuiNode/engagement/projectAgentGUIEngagementContext.ts
34133
34354
  function projectAgentGUIEngagementContext(viewModel, composerReady) {
@@ -34159,7 +34380,7 @@ function createAgentGUIEngagementContextKey(input) {
34159
34380
  }
34160
34381
 
34161
34382
  // agent-gui/agentGuiNode/engagement/useAgentGUIPanelEngagement.ts
34162
- import { useEffect as useEffect36, useRef as useRef44 } from "react";
34383
+ import { useEffect as useEffect35, useRef as useRef45 } from "react";
34163
34384
 
34164
34385
  // agent-gui/agentGuiNode/engagement/AgentGUIPanelEngagementController.ts
34165
34386
  var AGENT_GUI_PANEL_EXPOSURE_DWELL_MS = 1e3;
@@ -34313,10 +34534,10 @@ function documentIsVisible() {
34313
34534
 
34314
34535
  // agent-gui/agentGuiNode/engagement/useAgentGUIPanelEngagement.ts
34315
34536
  function useAgentGUIPanelEngagement(input) {
34316
- const inputRef = useRef44(input);
34317
- const controllerRef = useRef44(null);
34318
- const intersectionRatioRef = useRef44(0);
34319
- const engagementRef = useRef44(null);
34537
+ const inputRef = useRef45(input);
34538
+ const controllerRef = useRef45(null);
34539
+ const intersectionRatioRef = useRef45(0);
34540
+ const engagementRef = useRef45(null);
34320
34541
  inputRef.current = input;
34321
34542
  if (!engagementRef.current) {
34322
34543
  engagementRef.current = {
@@ -34329,7 +34550,7 @@ function useAgentGUIPanelEngagement(input) {
34329
34550
  };
34330
34551
  }
34331
34552
  const engagementEnabled = Boolean(input.onEvent) && !input.previewMode;
34332
- useEffect36(() => {
34553
+ useEffect35(() => {
34333
34554
  const element = input.elementRef.current;
34334
34555
  if (!engagementEnabled || !element) return void 0;
34335
34556
  const controller = new AgentGUIPanelEngagementController({
@@ -34356,7 +34577,7 @@ function useAgentGUIPanelEngagement(input) {
34356
34577
 
34357
34578
  // agent-gui/agentGuiNode/engagement/useAgentGUINodeEngagement.ts
34358
34579
  function useAgentGUINodeEngagement(input) {
34359
- const layoutElementRef = useRef45(null);
34580
+ const layoutElementRef = useRef46(null);
34360
34581
  const projected = projectAgentGUIEngagementContext(
34361
34582
  input.viewModel,
34362
34583
  input.composerReady
@@ -34445,7 +34666,7 @@ function AgentGUINodeView({
34445
34666
  viewModel
34446
34667
  });
34447
34668
  const [providerManagerOpen, setProviderManagerOpen] = useState36(false);
34448
- const railResizeInteractionRef = useRef46(null);
34669
+ const railResizeInteractionRef = useRef47(null);
34449
34670
  const [isRailResizing, setIsRailResizing] = useState36(false);
34450
34671
  const [railResizeWidthPx, setRailResizeWidthPx] = useState36(
34451
34672
  null
@@ -34454,7 +34675,7 @@ function AgentGUINodeView({
34454
34675
  localComposerFocusRequestSequence,
34455
34676
  setLocalComposerFocusRequestSequence
34456
34677
  ] = useState36(0);
34457
- const handledNewConversationRequestSequenceRef = useRef46(
34678
+ const handledNewConversationRequestSequenceRef = useRef47(
34458
34679
  newConversationRequestSequence
34459
34680
  );
34460
34681
  const {
@@ -34485,6 +34706,9 @@ function AgentGUINodeView({
34485
34706
  );
34486
34707
  const removeProject = useStableEventCallback(actions.removeProject);
34487
34708
  const moveProject = useStableEventCallback(actions.moveProject);
34709
+ const toggleProjectPinned = useStableEventCallback(
34710
+ actions.toggleProjectPinned
34711
+ );
34488
34712
  const confirmDeleteProjectConversations = useStableEventCallback(
34489
34713
  actions.confirmDeleteProjectConversations
34490
34714
  );
@@ -34533,7 +34757,7 @@ function AgentGUINodeView({
34533
34757
  viewModel.composer.composerSettings.selectedProjectPath
34534
34758
  ]
34535
34759
  );
34536
- useEffect37(() => {
34760
+ useEffect36(() => {
34537
34761
  if (newConversationRequestSequence === null || handledNewConversationRequestSequenceRef.current === newConversationRequestSequence) {
34538
34762
  return;
34539
34763
  }
@@ -34627,7 +34851,7 @@ function AgentGUINodeView({
34627
34851
  },
34628
34852
  [onConversationRailWidthChanged]
34629
34853
  );
34630
- useEffect37(() => {
34854
+ useEffect36(() => {
34631
34855
  if (isRailResizing || railResizeWidthPx === null) {
34632
34856
  return;
34633
34857
  }
@@ -34746,6 +34970,7 @@ function AgentGUINodeView({
34746
34970
  onMarkConversationUnread: actions.markConversationUnread,
34747
34971
  onRemoveProject: removeProject,
34748
34972
  onMoveProject: moveProject,
34973
+ onToggleProjectPinned: toggleProjectPinned,
34749
34974
  onConfirmDeleteProjectConversations: confirmDeleteProjectConversations,
34750
34975
  onConfirmDeleteConversations: confirmDeleteConversations,
34751
34976
  onRequestDeleteConversation: requestDeleteConversation,
@@ -34771,6 +34996,7 @@ function AgentGUINodeView({
34771
34996
  previewMode,
34772
34997
  removeProject,
34773
34998
  moveProject,
34999
+ toggleProjectPinned,
34774
35000
  requestCreateConversation,
34775
35001
  requestDeleteConversation,
34776
35002
  requestRenameConversation,
@@ -35190,9 +35416,9 @@ function appendDockProbeUsageLines(probe, lines, isLoadingUsage, t) {
35190
35416
  import { Info as Info3 } from "lucide-react";
35191
35417
  import {
35192
35418
  useCallback as useCallback56,
35193
- useEffect as useEffect38,
35419
+ useEffect as useEffect37,
35194
35420
  useLayoutEffect as useLayoutEffect9,
35195
- useRef as useRef47,
35421
+ useRef as useRef48,
35196
35422
  useState as useState37
35197
35423
  } from "react";
35198
35424
  import { createPortal as createPortal5 } from "react-dom";
@@ -35230,8 +35456,8 @@ function AgentProbeInfoPopover({
35230
35456
  onOpen
35231
35457
  }) {
35232
35458
  "use memo";
35233
- const anchorRef = useRef47(null);
35234
- const popoverRef = useRef47(null);
35459
+ const anchorRef = useRef48(null);
35460
+ const popoverRef = useRef48(null);
35235
35461
  const [isOpen, setIsOpen] = useState37(false);
35236
35462
  const [popoverStyle, setPopoverStyle] = useState37(null);
35237
35463
  const openPopover = useCallback56(() => {
@@ -35273,7 +35499,7 @@ function AgentProbeInfoPopover({
35273
35499
  maxWidth: availableWidth
35274
35500
  });
35275
35501
  }, []);
35276
- useEffect38(() => {
35502
+ useEffect37(() => {
35277
35503
  if (!isOpen) {
35278
35504
  return;
35279
35505
  }
@@ -35876,6 +36102,11 @@ function useAgentGUIViewLabels(input) {
35876
36102
  "agentHost.agentGui.projectSectionMoreActions"
35877
36103
  ),
35878
36104
  projectSectionViewFiles: t("agentHost.agentGui.projectSectionViewFiles"),
36105
+ pinProject: t("agentHost.agentGui.pinProject"),
36106
+ unpinProject: t("agentHost.agentGui.unpinProject"),
36107
+ pinnedProjectAccessibleName: (projectLabel) => t("agentHost.agentGui.pinnedProjectAccessibleName", {
36108
+ project: projectLabel
36109
+ }),
35879
36110
  projectRailCreateProject: t(
35880
36111
  "agentHost.agentGui.projectRailCreateProject"
35881
36112
  ),
@@ -36656,7 +36887,7 @@ var AgentGUINode = memo14(function AgentGUINode2({
36656
36887
  workspaceAgentProbes?.isLoadingUsage,
36657
36888
  t
36658
36889
  ]);
36659
- useEffect39(() => {
36890
+ useEffect38(() => {
36660
36891
  if (previewMode || !onAgentProbeDemandChange) {
36661
36892
  return;
36662
36893
  }
@@ -36666,7 +36897,7 @@ var AgentGUINode = memo14(function AgentGUINode2({
36666
36897
  onAgentProbeDemandChange(null, probeSourceId);
36667
36898
  };
36668
36899
  }, [activeProbeProvider, nodeId, onAgentProbeDemandChange, previewMode]);
36669
- useEffect39(() => {
36900
+ useEffect38(() => {
36670
36901
  if (previewMode || !onAgentProbeDemandChange || !railStatusProvider || railStatusProvider === activeProbeProvider) {
36671
36902
  return;
36672
36903
  }
@@ -36917,4 +37148,4 @@ export {
36917
37148
  resolveAgentGUIAgentTarget,
36918
37149
  AgentGUI
36919
37150
  };
36920
- //# sourceMappingURL=chunk-QWKJ646Z.js.map
37151
+ //# sourceMappingURL=chunk-ZXHXR2KT.js.map