@truefoundry/trueforge-ui 0.3.0-rc.2 → 0.3.0-rc.3

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 (107) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/README.md +17 -9
  3. package/dist/{AgentCodeSnippets-637HQUXD.js → AgentCodeSnippets-N546FNNS.js} +38 -23
  4. package/dist/AgentCodeSnippets-N546FNNS.js.map +1 -0
  5. package/dist/AgentMetricChart-YWJYVYYA.js +15 -0
  6. package/dist/{AgentOverview-3FJ5EE6N.js → AgentOverview-VF74XC7I.js} +7 -7
  7. package/dist/{AgentSessionEventTimeline-VELWUYPR.js → AgentSessionEventTimeline-RFR6LQMY.js} +8 -8
  8. package/dist/{AgentSessionEventTimeline-VELWUYPR.js.map → AgentSessionEventTimeline-RFR6LQMY.js.map} +1 -1
  9. package/dist/{AgentSessionEventTimelineChart-CUKETHWM.js → AgentSessionEventTimelineChart-27CQF6FX.js} +12 -12
  10. package/dist/AgentSessionEventTimelineChart-27CQF6FX.js.map +1 -0
  11. package/dist/{AgentSessions-T7MOGOTZ.js → AgentSessions-4IVX2SGD.js} +36 -12
  12. package/dist/AgentSessions-4IVX2SGD.js.map +1 -0
  13. package/dist/{ConnectorSettings-ESZ2RSRG.js → ConnectorSettings-R5VEP7BO.js} +156 -116
  14. package/dist/ConnectorSettings-R5VEP7BO.js.map +1 -0
  15. package/dist/{DockLayout-NLFNU6F2.js → DockLayout-F44RWGEY.js} +10 -10
  16. package/dist/{DrawerLayout-PR3SMKA6.js → DrawerLayout-SQ323AVM.js} +13 -11
  17. package/dist/DrawerLayout-SQ323AVM.js.map +1 -0
  18. package/dist/{ModelSettings-LYW64IRR.js → ModelSettings-6QLS63HM.js} +10 -10
  19. package/dist/{ModelSettings-LYW64IRR.js.map → ModelSettings-6QLS63HM.js.map} +1 -1
  20. package/dist/OpenUiFenceBlock-4ROX3G4X.js +9 -0
  21. package/dist/{SandboxSettings-DF64LHYI.js → SandboxSettings-OLKDXIQS.js} +9 -9
  22. package/dist/SchedulesPage-TMOTK6DR.js +15 -0
  23. package/dist/{SettingsBuilder-LSXK2VN4.js → SettingsBuilder-GISAH2WU.js} +8 -8
  24. package/dist/{ShellRouteSync-B22IAV2W.js → ShellRouteSync-EN33DUQ7.js} +157 -22
  25. package/dist/ShellRouteSync-EN33DUQ7.js.map +1 -0
  26. package/dist/{SidebarLayout-XW6LXB7R.js → SidebarLayout-35K4AKTC.js} +74 -53
  27. package/dist/SidebarLayout-35K4AKTC.js.map +1 -0
  28. package/dist/{SkillSettings-64VXUO6J.js → SkillSettings-JSX2BTII.js} +18 -13
  29. package/dist/SkillSettings-JSX2BTII.js.map +1 -0
  30. package/dist/{TrueForgeUIWithRouter-3TSLV22Q.js → TrueForgeUIWithRouter-6VCR7ES3.js} +9 -9
  31. package/dist/{WidgetLayout-Q5P7PYSJ.js → WidgetLayout-RKBSN2FZ.js} +10 -10
  32. package/dist/{chunk-YQO2NMJ3.js → chunk-2O5EJ6QS.js} +4096 -2825
  33. package/dist/chunk-2O5EJ6QS.js.map +1 -0
  34. package/dist/chunk-6WCIL3H2.js +517 -0
  35. package/dist/chunk-6WCIL3H2.js.map +1 -0
  36. package/dist/{chunk-SQGT43Z3.js → chunk-73FQVITT.js} +21 -4
  37. package/dist/chunk-73FQVITT.js.map +1 -0
  38. package/dist/{chunk-QC42MLAK.js → chunk-7AAO4UDQ.js} +4 -3
  39. package/dist/chunk-7AAO4UDQ.js.map +1 -0
  40. package/dist/{chunk-LGRHHFHN.js → chunk-F5QVQIBH.js} +166 -45
  41. package/dist/chunk-F5QVQIBH.js.map +1 -0
  42. package/dist/{chunk-I3AL54MA.js → chunk-GIPFF6FZ.js} +28 -24
  43. package/dist/chunk-GIPFF6FZ.js.map +1 -0
  44. package/dist/{chunk-GXYAOAK5.js → chunk-GSJAYYLR.js} +219 -162
  45. package/dist/chunk-GSJAYYLR.js.map +1 -0
  46. package/dist/{chunk-VJ7BZGAF.js → chunk-J5BPHEDT.js} +2 -2
  47. package/dist/chunk-KR7WYHVF.js +195 -0
  48. package/dist/chunk-KR7WYHVF.js.map +1 -0
  49. package/dist/{chunk-VUMGMGKZ.js → chunk-LUG7E6BL.js} +52 -8
  50. package/dist/chunk-LUG7E6BL.js.map +1 -0
  51. package/dist/chunk-LXJMINS6.js +587 -0
  52. package/dist/chunk-LXJMINS6.js.map +1 -0
  53. package/dist/{chunk-FQK2XVVE.js → chunk-PT4EENB3.js} +224 -72
  54. package/dist/chunk-PT4EENB3.js.map +1 -0
  55. package/dist/{chunk-H6WTY5PM.js → chunk-Q6TCT7ZJ.js} +17 -227
  56. package/dist/chunk-Q6TCT7ZJ.js.map +1 -0
  57. package/dist/{chunk-5I2COQNL.js → chunk-XLFOXQKZ.js} +13 -11
  58. package/dist/chunk-XLFOXQKZ.js.map +1 -0
  59. package/dist/{chunk-G2TUAD65.js → chunk-XY6LZQES.js} +235 -108
  60. package/dist/chunk-XY6LZQES.js.map +1 -0
  61. package/dist/{createTrueFoundryServer-CmZnBh_l.d.ts → createTrueFoundryServer-B_FYhSdn.d.ts} +8 -5
  62. package/dist/index.d.ts +291 -89
  63. package/dist/index.js +63 -488
  64. package/dist/index.js.map +1 -1
  65. package/dist/plugins/trueforge-agent-server-adapter/index.d.ts +36 -13
  66. package/dist/plugins/trueforge-agent-server-adapter/index.js +69 -35
  67. package/dist/plugins/trueforge-agent-server-adapter/index.js.map +1 -1
  68. package/dist/styles.css +1 -1
  69. package/package.json +3 -3
  70. package/dist/AgentCodeSnippets-637HQUXD.js.map +0 -1
  71. package/dist/AgentMetricChart-4FYECRIN.js +0 -15
  72. package/dist/AgentSessionEventTimelineChart-CUKETHWM.js.map +0 -1
  73. package/dist/AgentSessions-T7MOGOTZ.js.map +0 -1
  74. package/dist/ConnectorSettings-ESZ2RSRG.js.map +0 -1
  75. package/dist/DrawerLayout-PR3SMKA6.js.map +0 -1
  76. package/dist/OpenUiFenceBlock-JEPNPJ7U.js +0 -9
  77. package/dist/SchedulesPage-WQU4H25F.js +0 -15
  78. package/dist/ShellRouteSync-B22IAV2W.js.map +0 -1
  79. package/dist/SidebarLayout-XW6LXB7R.js.map +0 -1
  80. package/dist/SkillSettings-64VXUO6J.js.map +0 -1
  81. package/dist/chunk-5I2COQNL.js.map +0 -1
  82. package/dist/chunk-BWHOZFIV.js +0 -587
  83. package/dist/chunk-BWHOZFIV.js.map +0 -1
  84. package/dist/chunk-FQK2XVVE.js.map +0 -1
  85. package/dist/chunk-G2TUAD65.js.map +0 -1
  86. package/dist/chunk-GXYAOAK5.js.map +0 -1
  87. package/dist/chunk-H6WTY5PM.js.map +0 -1
  88. package/dist/chunk-I3AL54MA.js.map +0 -1
  89. package/dist/chunk-LGRHHFHN.js.map +0 -1
  90. package/dist/chunk-NHHSZB5N.js +0 -74
  91. package/dist/chunk-NHHSZB5N.js.map +0 -1
  92. package/dist/chunk-QC42MLAK.js.map +0 -1
  93. package/dist/chunk-SFZNIO6U.js +0 -18
  94. package/dist/chunk-SFZNIO6U.js.map +0 -1
  95. package/dist/chunk-SQGT43Z3.js.map +0 -1
  96. package/dist/chunk-VUMGMGKZ.js.map +0 -1
  97. package/dist/chunk-YQO2NMJ3.js.map +0 -1
  98. /package/dist/{AgentMetricChart-4FYECRIN.js.map → AgentMetricChart-YWJYVYYA.js.map} +0 -0
  99. /package/dist/{AgentOverview-3FJ5EE6N.js.map → AgentOverview-VF74XC7I.js.map} +0 -0
  100. /package/dist/{DockLayout-NLFNU6F2.js.map → DockLayout-F44RWGEY.js.map} +0 -0
  101. /package/dist/{OpenUiFenceBlock-JEPNPJ7U.js.map → OpenUiFenceBlock-4ROX3G4X.js.map} +0 -0
  102. /package/dist/{SandboxSettings-DF64LHYI.js.map → SandboxSettings-OLKDXIQS.js.map} +0 -0
  103. /package/dist/{SchedulesPage-WQU4H25F.js.map → SchedulesPage-TMOTK6DR.js.map} +0 -0
  104. /package/dist/{SettingsBuilder-LSXK2VN4.js.map → SettingsBuilder-GISAH2WU.js.map} +0 -0
  105. /package/dist/{TrueForgeUIWithRouter-3TSLV22Q.js.map → TrueForgeUIWithRouter-6VCR7ES3.js.map} +0 -0
  106. /package/dist/{WidgetLayout-Q5P7PYSJ.js.map → WidgetLayout-RKBSN2FZ.js.map} +0 -0
  107. /package/dist/{chunk-VJ7BZGAF.js.map → chunk-J5BPHEDT.js.map} +0 -0
@@ -5,6 +5,7 @@ import {
5
5
  } from "./chunk-BSIPI3KV.js";
6
6
  import {
7
7
  ASK_USER_CUSTOM_OPTION,
8
+ ApprovalFocusProvider,
8
9
  AssistantMessageContainer,
9
10
  Button,
10
11
  ComposerAttachmentsContainer,
@@ -13,31 +14,105 @@ import {
13
14
  UserMessageContainer,
14
15
  isNewChatView,
15
16
  preloadMarkdownOpenUI,
17
+ useActiveSessionCanManage,
16
18
  useMCPAuth,
19
+ useOptionalApprovalFocus,
17
20
  useSlot,
18
21
  useSlotIsDefault
19
- } from "./chunk-YQO2NMJ3.js";
22
+ } from "./chunk-2O5EJ6QS.js";
20
23
  import {
21
24
  DraftCatalogProvider,
22
25
  useDraftCatalog
23
- } from "./chunk-H6WTY5PM.js";
26
+ } from "./chunk-Q6TCT7ZJ.js";
24
27
  import {
25
28
  useOptionalCatalogServer,
26
29
  useOptionalServer,
27
30
  useOptionalShellMode
28
- } from "./chunk-FQK2XVVE.js";
31
+ } from "./chunk-PT4EENB3.js";
29
32
  import {
30
33
  useAui,
31
34
  useAuiState
32
35
  } from "./chunk-M6MHLVSO.js";
33
36
 
37
+ // src/hooks/useApprovalNav.ts
38
+ import { useTrueFoundryApprovals } from "@truefoundry/assistant-ui-runtime";
39
+ import { useCallback, useEffect, useRef, useState } from "react";
40
+ function useApprovalNav() {
41
+ const { pending } = useTrueFoundryApprovals();
42
+ const focusApi = useOptionalApprovalFocus();
43
+ const [selection, setSelection] = useState({
44
+ approvalId: null,
45
+ index: 0
46
+ });
47
+ const focusedIdRef = useRef(null);
48
+ const count = pending.length;
49
+ const matchedIndex = selection.approvalId == null ? -1 : pending.findIndex((item) => item.approvalId === selection.approvalId);
50
+ const safeIndex = matchedIndex >= 0 ? matchedIndex : count === 0 ? 0 : Math.min(selection.index, count - 1);
51
+ const currentId = pending[safeIndex]?.approvalId;
52
+ useEffect(() => {
53
+ const approvalId = currentId ?? null;
54
+ if (selection.approvalId === approvalId && selection.index === safeIndex) return;
55
+ setSelection({ approvalId, index: safeIndex });
56
+ }, [currentId, safeIndex, selection.approvalId, selection.index]);
57
+ useEffect(() => {
58
+ if (currentId == null || focusApi == null) {
59
+ if (currentId == null) focusedIdRef.current = null;
60
+ return;
61
+ }
62
+ if (focusedIdRef.current === currentId) return;
63
+ focusedIdRef.current = currentId;
64
+ focusApi.focus(currentId);
65
+ }, [currentId, focusApi]);
66
+ const goPrev = useCallback(() => {
67
+ const index = Math.max(0, safeIndex - 1);
68
+ setSelection({ approvalId: pending[index]?.approvalId ?? null, index });
69
+ }, [pending, safeIndex]);
70
+ const goNext = useCallback(() => {
71
+ const index = Math.min(Math.max(count - 1, 0), safeIndex + 1);
72
+ setSelection({ approvalId: pending[index]?.approvalId ?? null, index });
73
+ }, [count, pending, safeIndex]);
74
+ const focusCurrent = useCallback(() => {
75
+ if (currentId == null || focusApi == null) return;
76
+ focusApi.focus(currentId);
77
+ }, [currentId, focusApi]);
78
+ return {
79
+ count,
80
+ index: safeIndex,
81
+ canPrev: safeIndex > 0,
82
+ canNext: safeIndex < count - 1,
83
+ goPrev,
84
+ goNext,
85
+ focusCurrent
86
+ };
87
+ }
88
+
89
+ // src/containers/ApprovalNavContainer.tsx
90
+ import { jsx } from "react/jsx-runtime";
91
+ function ApprovalNavContainer() {
92
+ const ApprovalNavBanner = useSlot("ApprovalNavBanner");
93
+ const { count, index, canPrev, canNext, goPrev, goNext, focusCurrent } = useApprovalNav();
94
+ if (count === 0) return null;
95
+ return /* @__PURE__ */ jsx(
96
+ ApprovalNavBanner,
97
+ {
98
+ total: count,
99
+ current: index + 1,
100
+ canPrev,
101
+ canNext,
102
+ onPrev: goPrev,
103
+ onNext: goNext,
104
+ onFocusCurrent: focusCurrent
105
+ }
106
+ );
107
+ }
108
+
34
109
  // src/containers/AskUserContainer.tsx
35
110
  import { useThreadIsRunning } from "@assistant-ui/core/react";
36
111
  import { useTrueFoundryToolResponses } from "@truefoundry/assistant-ui-runtime";
37
- import { useCallback, useEffect, useMemo, useState } from "react";
38
- import { jsx } from "react/jsx-runtime";
112
+ import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useState as useState2 } from "react";
113
+ import { jsx as jsx2 } from "react/jsx-runtime";
39
114
  var EMPTY_ANSWER = { radioValue: "", custom: "" };
40
- function AskUserContainer() {
115
+ function AskUserContainer({ disabled = false }) {
41
116
  const AskUserPrompt = useSlot("AskUserPrompt");
42
117
  const { pending, respond } = useTrueFoundryToolResponses();
43
118
  const isRunning = useThreadIsRunning();
@@ -52,16 +127,16 @@ function AskUserContainer() {
52
127
  ],
53
128
  [item]
54
129
  );
55
- const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
56
- const [answers, setAnswers] = useState({});
57
- useEffect(() => {
130
+ const [currentQuestionIndex, setCurrentQuestionIndex] = useState2(0);
131
+ const [answers, setAnswers] = useState2({});
132
+ useEffect2(() => {
58
133
  setCurrentQuestionIndex(0);
59
134
  setAnswers({});
60
135
  }, [item?.toolCallId]);
61
136
  const safeIndex = Math.min(currentQuestionIndex, Math.max(questions.length - 1, 0));
62
137
  const currentQuestion = questions[safeIndex];
63
138
  const currentAnswer = currentQuestion == null ? EMPTY_ANSWER : answers[currentQuestion.id] ?? EMPTY_ANSWER;
64
- const getResponseForQuestion = useCallback(
139
+ const getResponseForQuestion = useCallback2(
65
140
  (questionId) => {
66
141
  const answer = answers[questionId] ?? EMPTY_ANSWER;
67
142
  return answer.radioValue === ASK_USER_CUSTOM_OPTION ? answer.custom.trim() : answer.radioValue.trim();
@@ -73,9 +148,9 @@ function AskUserContainer() {
73
148
  [getResponseForQuestion, questions]
74
149
  );
75
150
  const selectedResponse = currentAnswer.radioValue === ASK_USER_CUSTOM_OPTION ? currentAnswer.custom.trim() : currentAnswer.radioValue.trim();
76
- const isSubmitDisabled = isRunning || currentQuestion == null || selectedResponse.length === 0;
151
+ const isSubmitDisabled = isRunning || disabled || currentQuestion == null || selectedResponse.length === 0;
77
152
  const isSubmitAllDisabled = isSubmitDisabled || !allQuestionsAnswered;
78
- const onCurrentAnswerChange = useCallback((questionId, update) => {
153
+ const onCurrentAnswerChange = useCallback2((questionId, update) => {
79
154
  setAnswers((previous) => ({
80
155
  ...previous,
81
156
  [questionId]: {
@@ -84,18 +159,18 @@ function AskUserContainer() {
84
159
  }
85
160
  }));
86
161
  }, []);
87
- const onSubmit = useCallback(() => {
88
- if (item == null || !allQuestionsAnswered) return;
162
+ const onSubmit = useCallback2(() => {
163
+ if (disabled || item == null || !allQuestionsAnswered) return;
89
164
  const content = getResponseForQuestion(item.toolCallId);
90
165
  if (!content) return;
91
166
  respond({ toolCallId: item.toolCallId, content });
92
- }, [allQuestionsAnswered, getResponseForQuestion, item, respond]);
167
+ }, [allQuestionsAnswered, disabled, getResponseForQuestion, item, respond]);
93
168
  if (item == null || currentQuestion == null) return null;
94
- return /* @__PURE__ */ jsx(
169
+ return /* @__PURE__ */ jsx2(
95
170
  AskUserPrompt,
96
171
  {
97
172
  questions,
98
- readOnly: isRunning,
173
+ readOnly: isRunning || disabled,
99
174
  currentQuestion,
100
175
  currentQuestionIndex: safeIndex,
101
176
  currentAnswer,
@@ -114,7 +189,7 @@ function AskUserContainer() {
114
189
 
115
190
  // src/hooks/useComposerPauseView.ts
116
191
  import { useAuiState as useAuiState2 } from "@assistant-ui/react";
117
- import { useTrueFoundryToolResponses as useTrueFoundryToolResponses2 } from "@truefoundry/assistant-ui-runtime";
192
+ import { useTrueFoundryApprovals as useTrueFoundryApprovals2, useTrueFoundryToolResponses as useTrueFoundryToolResponses2 } from "@truefoundry/assistant-ui-runtime";
118
193
  function threadHasPendingMcpAuth(s) {
119
194
  const messages = s.thread.messages;
120
195
  const last = messages[messages.length - 1];
@@ -125,6 +200,7 @@ function threadHasPendingMcpAuth(s) {
125
200
  function useComposerPauseView() {
126
201
  const mcpPending = useAuiState2(threadHasPendingMcpAuth);
127
202
  const { pending: toolResponsesPending } = useTrueFoundryToolResponses2();
203
+ const { pending: approvalsPending } = useTrueFoundryApprovals2();
128
204
  const customActionRenderers = useOptionalCustomActionRenderers();
129
205
  if (mcpPending) {
130
206
  return { kind: "mcp" };
@@ -137,38 +213,41 @@ function useComposerPauseView() {
137
213
  }
138
214
  return { kind: "ask-user" };
139
215
  }
216
+ if (approvalsPending.length > 0) {
217
+ return { kind: "approval" };
218
+ }
140
219
  return { kind: "compose" };
141
220
  }
142
221
 
143
222
  // src/containers/CustomActionContainer.tsx
144
223
  import { useThreadIsRunning as useThreadIsRunning2 } from "@assistant-ui/core/react";
145
224
  import { useTrueFoundryToolResponses as useTrueFoundryToolResponses3 } from "@truefoundry/assistant-ui-runtime";
146
- import { useCallback as useCallback2 } from "react";
147
- import { jsx as jsx2 } from "react/jsx-runtime";
148
- function CustomActionContainer() {
225
+ import { useCallback as useCallback3 } from "react";
226
+ import { jsx as jsx3 } from "react/jsx-runtime";
227
+ function CustomActionContainer({ disabled = false }) {
149
228
  const renderers = useOptionalCustomActionRenderers();
150
229
  const { pending, respond } = useTrueFoundryToolResponses3();
151
230
  const isRunning = useThreadIsRunning2();
152
231
  const item = pending[0];
153
- const onSubmit = useCallback2(
232
+ const onSubmit = useCallback3(
154
233
  (content) => {
155
- if (item == null) return;
234
+ if (disabled || item == null) return;
156
235
  const trimmed = content.trim();
157
236
  if (!trimmed) return;
158
237
  respond({ toolCallId: item.toolCallId, content: trimmed });
159
238
  },
160
- [item, respond]
239
+ [disabled, item, respond]
161
240
  );
162
241
  if (item == null || item.toolName == null) return null;
163
242
  const Renderer = renderers?.[item.toolName];
164
243
  if (Renderer == null) return null;
165
- return /* @__PURE__ */ jsx2(Renderer, { args: item.args ?? {}, disabled: isRunning, onSubmit });
244
+ return /* @__PURE__ */ jsx3(Renderer, { args: item.args ?? {}, disabled: isRunning || disabled, onSubmit });
166
245
  }
167
246
 
168
247
  // src/containers/McpAuthContainer.tsx
169
248
  import { useThreadIsRunning as useThreadIsRunning3 } from "@assistant-ui/core/react";
170
249
  import { useTrueFoundryMcpAuth } from "@truefoundry/assistant-ui-runtime";
171
- import { jsx as jsx3 } from "react/jsx-runtime";
250
+ import { jsx as jsx4 } from "react/jsx-runtime";
172
251
  function CatalogMcpAuthPrompt({ servers, onContinue, readOnly }) {
173
252
  const McpAuthPrompt = useSlot("McpAuthPrompt");
174
253
  const { handleAuthorize } = useMCPAuth();
@@ -180,16 +259,25 @@ function CatalogMcpAuthPrompt({ servers, onContinue, readOnly }) {
180
259
  }
181
260
  });
182
261
  };
183
- return /* @__PURE__ */ jsx3(McpAuthPrompt, { servers, onConnect: handleConnect, onContinue, readOnly });
262
+ return /* @__PURE__ */ jsx4(McpAuthPrompt, { servers, onConnect: handleConnect, onContinue, readOnly });
184
263
  }
185
- function McpAuthContainer() {
264
+ function McpAuthContainer({ disabled = false }) {
186
265
  const McpAuthPrompt = useSlot("McpAuthPrompt");
187
266
  const { pending, resume } = useTrueFoundryMcpAuth();
188
267
  const isRunning = useThreadIsRunning3();
189
268
  const catalog = useOptionalCatalogServer();
190
269
  if (!pending) return null;
191
270
  if (catalog) {
192
- return /* @__PURE__ */ jsx3(CatalogMcpAuthPrompt, { servers: pending.mcpServers, onContinue: () => void resume(), readOnly: isRunning });
271
+ return /* @__PURE__ */ jsx4(
272
+ CatalogMcpAuthPrompt,
273
+ {
274
+ servers: pending.mcpServers,
275
+ onContinue: () => {
276
+ if (!disabled) void resume();
277
+ },
278
+ readOnly: isRunning || disabled
279
+ }
280
+ );
193
281
  }
194
282
  const handleConnect = (serverId) => {
195
283
  const server = pending.mcpServers.find((s) => s.id === serverId);
@@ -197,13 +285,15 @@ function McpAuthContainer() {
197
285
  window.open(server.authUrl, "_blank", "noopener,noreferrer");
198
286
  }
199
287
  };
200
- return /* @__PURE__ */ jsx3(
288
+ return /* @__PURE__ */ jsx4(
201
289
  McpAuthPrompt,
202
290
  {
203
291
  servers: pending.mcpServers,
204
292
  onConnect: handleConnect,
205
- onContinue: () => void resume(),
206
- readOnly: isRunning
293
+ onContinue: () => {
294
+ if (!disabled) void resume();
295
+ },
296
+ readOnly: isRunning || disabled
207
297
  }
208
298
  );
209
299
  }
@@ -211,26 +301,42 @@ function McpAuthContainer() {
211
301
  // src/containers/ComposerContainer.tsx
212
302
  import { ComposerPrimitive, useAui as useAui2, useAuiState as useAuiState3 } from "@assistant-ui/react";
213
303
  import { useTrueFoundryAgentSpec, useTrueFoundryCancel } from "@truefoundry/assistant-ui-runtime";
214
- import { useRef } from "react";
215
- import { Fragment, jsx as jsx4, jsxs } from "react/jsx-runtime";
216
- function ComposerBody({ placeholder }) {
304
+ import { useRef as useRef2 } from "react";
305
+ import { Fragment, jsx as jsx5, jsxs } from "react/jsx-runtime";
306
+ function canSubmitComposer({
307
+ disabled,
308
+ hasText,
309
+ hasAttachments,
310
+ requiresModel,
311
+ hasModel
312
+ }) {
313
+ return !disabled && (hasText || hasAttachments) && (!requiresModel || hasModel);
314
+ }
315
+ function ComposerBody({
316
+ placeholder,
317
+ forceDisabled = false,
318
+ connectedToBanner = false
319
+ }) {
217
320
  const ComposerShell = useSlot("ComposerShell");
218
321
  const aui = useAui2();
219
322
  const shell = useOptionalShellMode();
220
323
  const hasText = useAuiState3((s) => s.composer.text.trim().length > 0);
324
+ const hasAttachments = useAuiState3((s) => s.composer.attachments.length > 0);
221
325
  const { agentSpec } = useTrueFoundryAgentSpec();
222
326
  const requiresModel = shell == null || shell.mode.status === "active" && shell.mode.isMutable;
223
327
  const hasModel = Boolean(agentSpec?.model?.name?.trim());
224
328
  const { isBusy, send, resetBusy } = useComposerBusyState();
329
+ const canManageSession = useActiveSessionCanManage();
225
330
  const cancel = useTrueFoundryCancel();
226
- const fileInputRef = useRef(null);
227
- const canSubmit = !isBusy && hasText && (!requiresModel || hasModel);
331
+ const fileInputRef = useRef2(null);
332
+ const disabled = isBusy || forceDisabled || !canManageSession;
333
+ const canSubmit = canSubmitComposer({ disabled, hasText, hasAttachments, requiresModel, hasModel });
228
334
  const submit = () => {
229
335
  if (!canSubmit) return;
230
336
  send(() => aui.composer().send());
231
337
  };
232
338
  return /* @__PURE__ */ jsxs(Fragment, { children: [
233
- /* @__PURE__ */ jsx4(
339
+ /* @__PURE__ */ jsx5(
234
340
  "input",
235
341
  {
236
342
  ref: fileInputRef,
@@ -248,13 +354,13 @@ function ComposerBody({ placeholder }) {
248
354
  }
249
355
  }
250
356
  ),
251
- /* @__PURE__ */ jsx4(
357
+ /* @__PURE__ */ jsx5(
252
358
  ComposerPrimitive.AttachmentDropzone,
253
359
  {
254
- disabled: isBusy,
360
+ disabled,
255
361
  "data-slot": "aui_composer-attachment-dropzone",
256
362
  className: "w-full rounded-[0.75rem] transition-[box-shadow] data-[dragging=true]:ring-focus-ring/20 data-[dragging=true]:ring-3",
257
- children: /* @__PURE__ */ jsx4(
363
+ children: /* @__PURE__ */ jsx5(
258
364
  ComposerPrimitive.Root,
259
365
  {
260
366
  "data-slot": "aui_composer-root",
@@ -263,30 +369,34 @@ function ComposerBody({ placeholder }) {
263
369
  event.preventDefault();
264
370
  submit();
265
371
  },
266
- children: /* @__PURE__ */ jsx4(
372
+ children: /* @__PURE__ */ jsx5(
267
373
  ComposerShell,
268
374
  {
269
- attachments: /* @__PURE__ */ jsx4(ComposerAttachmentsContainer, {}),
270
- input: /* @__PURE__ */ jsx4(
375
+ className: connectedToBanner ? (
376
+ // Banner owns the top accent; composer keeps its normal chrome without a shared blue frame.
377
+ "rounded-t-none border-t-0 focus-within:ring-0"
378
+ ) : void 0,
379
+ attachments: /* @__PURE__ */ jsx5(ComposerAttachmentsContainer, {}),
380
+ input: /* @__PURE__ */ jsx5(
271
381
  ComposerPrimitive.Input,
272
382
  {
273
383
  "data-slot": "aui_composer-input",
274
384
  placeholder,
275
- disabled: isBusy,
385
+ disabled,
276
386
  submitMode: "enter",
277
387
  "aria-label": "Message input",
278
388
  className: "text-text-primary placeholder:text-text-secondary/80 max-h-[10lh] min-h-10 w-full resize-none overflow-y-auto rounded-lg border-none bg-transparent px-1 py-1 text-base leading-normal shadow-none outline-none disabled:cursor-not-allowed"
279
389
  }
280
390
  ),
281
- disabled: isBusy,
391
+ disabled,
282
392
  canSubmit,
283
- isRunning: isBusy,
393
+ isRunning: isBusy && !forceDisabled,
284
394
  onSubmit: submit,
285
- onCancel: () => {
395
+ onCancel: canManageSession ? () => {
286
396
  resetBusy();
287
397
  void cancel();
288
- },
289
- onAttach: () => fileInputRef.current?.click()
398
+ } : void 0,
399
+ onAttach: canManageSession ? () => fileInputRef.current?.click() : void 0
290
400
  }
291
401
  )
292
402
  }
@@ -295,10 +405,11 @@ function ComposerBody({ placeholder }) {
295
405
  )
296
406
  ] });
297
407
  }
298
- function ComposerContainer({
299
- placeholder = "Ask anything... (Shift+Enter for new line)"
408
+ function ComposerWithOptionalDraft({
409
+ placeholder,
410
+ forceDisabled = false,
411
+ connectedToBanner = false
300
412
  }) {
301
- const pauseView = useComposerPauseView();
302
413
  const shell = useOptionalShellMode();
303
414
  const parentLeftSection = useSlot("ComposerLeftSection");
304
415
  const parentRightSection = useSlot("ComposerRightSection");
@@ -307,42 +418,55 @@ function ComposerContainer({
307
418
  const DraftComposerLeftSection = useSlot("DraftComposerLeftSection");
308
419
  const DraftComposerRightSection = useSlot("DraftComposerRightSection");
309
420
  const canMutateSpec = shell?.mode.status === "active" && shell.mode.isMutable;
310
- if (pauseView.kind === "mcp") {
311
- return /* @__PURE__ */ jsx4(McpAuthContainer, {});
312
- }
313
- if (pauseView.kind === "custom") {
314
- return /* @__PURE__ */ jsx4(CustomActionContainer, {});
315
- }
316
- if (pauseView.kind === "ask-user") {
317
- return /* @__PURE__ */ jsx4(AskUserContainer, {});
318
- }
319
421
  if (canMutateSpec) {
320
- return /* @__PURE__ */ jsx4(DraftCatalogProvider, { children: /* @__PURE__ */ jsx4(
422
+ return /* @__PURE__ */ jsx5(DraftCatalogProvider, { children: /* @__PURE__ */ jsx5(
321
423
  SlotsProvider,
322
424
  {
323
425
  overrides: {
324
426
  ComposerLeftSection: usesDefaultLeftSection ? DraftComposerLeftSection : parentLeftSection,
325
427
  ComposerRightSection: usesDefaultRightSection ? DraftComposerRightSection : parentRightSection
326
428
  },
327
- children: /* @__PURE__ */ jsx4(ComposerBody, { placeholder })
429
+ children: /* @__PURE__ */ jsx5(ComposerBody, { placeholder, forceDisabled, connectedToBanner })
328
430
  }
329
431
  ) });
330
432
  }
331
- return /* @__PURE__ */ jsx4(ComposerBody, { placeholder });
433
+ return /* @__PURE__ */ jsx5(ComposerBody, { placeholder, forceDisabled, connectedToBanner });
434
+ }
435
+ function ComposerContainer({
436
+ placeholder = "Ask anything... (Shift+Enter for new line)"
437
+ }) {
438
+ const pauseView = useComposerPauseView();
439
+ const canManageSession = useActiveSessionCanManage();
440
+ if (pauseView.kind === "mcp") {
441
+ return /* @__PURE__ */ jsx5(McpAuthContainer, { disabled: !canManageSession });
442
+ }
443
+ if (pauseView.kind === "custom") {
444
+ return /* @__PURE__ */ jsx5(CustomActionContainer, { disabled: !canManageSession });
445
+ }
446
+ if (pauseView.kind === "ask-user") {
447
+ return /* @__PURE__ */ jsx5(AskUserContainer, { disabled: !canManageSession });
448
+ }
449
+ if (pauseView.kind === "approval") {
450
+ return /* @__PURE__ */ jsxs("div", { "data-slot": "aui_composer-approval-pause", className: "flex w-full flex-col", children: [
451
+ /* @__PURE__ */ jsx5(ApprovalNavContainer, {}),
452
+ /* @__PURE__ */ jsx5(ComposerWithOptionalDraft, { placeholder, forceDisabled: true, connectedToBanner: true })
453
+ ] });
454
+ }
455
+ return /* @__PURE__ */ jsx5(ComposerWithOptionalDraft, { placeholder });
332
456
  }
333
457
 
334
458
  // src/containers/HistoryLoaderContainer.tsx
335
459
  import { useTrueFoundryHistoryPagination } from "@truefoundry/assistant-ui-runtime";
336
- import { useCallback as useCallback3, useEffect as useEffect2, useRef as useRef2, useState as useState2 } from "react";
337
- import { jsx as jsx5 } from "react/jsx-runtime";
460
+ import { useCallback as useCallback4, useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
461
+ import { jsx as jsx6 } from "react/jsx-runtime";
338
462
  var TOP_THRESHOLD_PX = 200;
339
463
  var VIEWPORT_SELECTOR = '[data-slot="aui_thread-viewport"]';
340
464
  function HistoryLoaderContainer() {
341
465
  const HistoryLoader = useSlot("HistoryLoader");
342
466
  const { hasOlderHistory, isLoadingOlderHistory, loadOlderHistory } = useTrueFoundryHistoryPagination();
343
- const [sentinel, setSentinel] = useState2(null);
344
- const inflightRef = useRef2(false);
345
- const maybeLoadOlder = useCallback3(async () => {
467
+ const [sentinel, setSentinel] = useState3(null);
468
+ const inflightRef = useRef3(false);
469
+ const maybeLoadOlder = useCallback4(async () => {
346
470
  if (inflightRef.current) return;
347
471
  inflightRef.current = true;
348
472
  const viewport = sentinel?.closest(VIEWPORT_SELECTOR) ?? null;
@@ -362,7 +486,7 @@ function HistoryLoaderContainer() {
362
486
  inflightRef.current = false;
363
487
  }
364
488
  }, [sentinel, loadOlderHistory]);
365
- useEffect2(() => {
489
+ useEffect3(() => {
366
490
  if (sentinel == null || !hasOlderHistory) return;
367
491
  const viewport = sentinel.closest(VIEWPORT_SELECTOR);
368
492
  const observer = new IntersectionObserver(
@@ -377,60 +501,61 @@ function HistoryLoaderContainer() {
377
501
  return () => observer.disconnect();
378
502
  }, [sentinel, hasOlderHistory, maybeLoadOlder]);
379
503
  if (!hasOlderHistory) return null;
380
- return /* @__PURE__ */ jsx5(HistoryLoader, { ref: setSentinel, isLoading: isLoadingOlderHistory });
504
+ return /* @__PURE__ */ jsx6(HistoryLoader, { ref: setSentinel, isLoading: isLoadingOlderHistory });
381
505
  }
382
506
 
383
507
  // src/containers/ResumeUnavailableContainer.tsx
384
508
  import { useTrueFoundryResumeUnavailable } from "@truefoundry/assistant-ui-runtime";
385
- import { jsx as jsx6 } from "react/jsx-runtime";
509
+ import { jsx as jsx7 } from "react/jsx-runtime";
386
510
  function ResumeUnavailableContainer() {
387
511
  const ResumeUnavailable = useSlot("ResumeUnavailable");
388
512
  const resumeUnavailable = useTrueFoundryResumeUnavailable();
389
513
  if (!resumeUnavailable) return null;
390
- return /* @__PURE__ */ jsx6(ResumeUnavailable, {});
514
+ return /* @__PURE__ */ jsx7(ResumeUnavailable, {});
391
515
  }
392
516
 
393
517
  // src/containers/UserEditComposerContainer.tsx
394
518
  import { useComposerCancel, useComposerSend, useThreadIsRunning as useThreadIsRunning4 } from "@assistant-ui/core/react";
395
519
  import { ComposerPrimitive as ComposerPrimitive2, MessagePrimitive, useAuiState as useAuiState4 } from "@assistant-ui/react";
396
- import { jsx as jsx7, jsxs as jsxs2 } from "react/jsx-runtime";
520
+ import { jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
397
521
  function ReadOnlyMessageAttachments() {
398
522
  const hasAttachments = useAuiState4((s) => (s.message.attachments?.length ?? 0) > 0);
399
523
  if (!hasAttachments) {
400
524
  return null;
401
525
  }
402
- return /* @__PURE__ */ jsx7("div", { className: "pointer-events-none mb-2 opacity-90", children: /* @__PURE__ */ jsx7(MessageAttachmentsContainer, {}) });
526
+ return /* @__PURE__ */ jsx8("div", { className: "pointer-events-none mb-2 opacity-90", children: /* @__PURE__ */ jsx8(MessageAttachmentsContainer, {}) });
403
527
  }
404
528
  function UserEditComposerContainer() {
405
529
  const UserMessageEdit = useSlot("UserMessageEdit");
406
530
  const MessageTimestamp = useSlot("MessageTimestamp");
407
531
  const isRunning = useThreadIsRunning4();
532
+ const canManageSession = useActiveSessionCanManage();
408
533
  const createdAt = useAuiState4((s) => s.message.createdAt);
409
534
  const { cancel, disabled: cancelDisabled } = useComposerCancel();
410
535
  const { disabled: sendDisabled } = useComposerSend();
411
- return /* @__PURE__ */ jsx7(MessagePrimitive.Root, { "data-role": "user", children: /* @__PURE__ */ jsx7(
536
+ return /* @__PURE__ */ jsx8(MessagePrimitive.Root, { "data-role": "user", children: /* @__PURE__ */ jsx8(
412
537
  ComposerPrimitive2.Root,
413
538
  {
414
539
  "data-slot": "aui_user-edit-composer-root",
415
540
  className: "fade-in slide-in-from-bottom-1 animate-in flex w-full justify-end px-2 duration-150",
416
- children: /* @__PURE__ */ jsx7(
541
+ children: /* @__PURE__ */ jsx8(
417
542
  UserMessageEdit,
418
543
  {
419
- timestamp: /* @__PURE__ */ jsx7(MessageTimestamp, { createdAt }),
420
- attachments: /* @__PURE__ */ jsx7(ReadOnlyMessageAttachments, {}),
421
- input: /* @__PURE__ */ jsx7("div", { className: "mt-1 rounded border border-border bg-secondary-bg p-2 text-text-primary", children: /* @__PURE__ */ jsx7(
544
+ timestamp: /* @__PURE__ */ jsx8(MessageTimestamp, { createdAt }),
545
+ attachments: /* @__PURE__ */ jsx8(ReadOnlyMessageAttachments, {}),
546
+ input: /* @__PURE__ */ jsx8("div", { className: "mt-1 rounded border border-border bg-secondary-bg p-2 text-text-primary", children: /* @__PURE__ */ jsx8(
422
547
  ComposerPrimitive2.Input,
423
548
  {
424
549
  "data-slot": "aui_user-edit-input",
425
- disabled: isRunning,
550
+ disabled: isRunning || !canManageSession,
426
551
  submitMode: "enter",
427
552
  "aria-label": "Edit message",
428
553
  className: "max-h-32 min-h-10 w-full resize-none border-none bg-transparent p-0 text-base leading-[1.34] outline-none focus:shadow-none"
429
554
  }
430
555
  ) }),
431
556
  footer: /* @__PURE__ */ jsxs2("div", { className: "flex items-center justify-end gap-2", children: [
432
- /* @__PURE__ */ jsx7(Button.Secondary, { type: "button", disabled: cancelDisabled, onClick: cancel, children: "Cancel" }),
433
- /* @__PURE__ */ jsx7(ComposerPrimitive2.Send, { asChild: true, children: /* @__PURE__ */ jsx7(Button.Primary, { type: "submit", disabled: sendDisabled || isRunning, children: "Save & Rerun" }) })
557
+ /* @__PURE__ */ jsx8(Button.Secondary, { type: "button", disabled: cancelDisabled, onClick: cancel, children: "Cancel" }),
558
+ /* @__PURE__ */ jsx8(ComposerPrimitive2.Send, { asChild: true, children: /* @__PURE__ */ jsx8(Button.Primary, { type: "submit", disabled: sendDisabled || isRunning || !canManageSession, children: "Save & Rerun" }) })
434
559
  ] })
435
560
  }
436
561
  )
@@ -440,23 +565,23 @@ function UserEditComposerContainer() {
440
565
 
441
566
  // src/containers/ThreadContainer.tsx
442
567
  import { ThreadPrimitive, useAuiState as useAuiState5 } from "@assistant-ui/react";
443
- import { useEffect as useEffect4 } from "react";
568
+ import { useEffect as useEffect5 } from "react";
444
569
 
445
570
  // src/hooks/useSyncSessionTitle.ts
446
571
  import { useThreadIsRunning as useThreadIsRunning5 } from "@assistant-ui/core/react";
447
- import { useEffect as useEffect3, useRef as useRef3 } from "react";
572
+ import { useEffect as useEffect4, useRef as useRef4 } from "react";
448
573
  function useSyncSessionTitle() {
449
574
  const server = useOptionalServer();
450
575
  const aui = useAui();
451
576
  const remoteId = useAuiState((s) => s.threadListItem.remoteId);
452
577
  const title = useAuiState((s) => s.threadListItem.title);
453
578
  const isRunning = useThreadIsRunning5();
454
- const wasRunningRef = useRef3(false);
455
- const syncedRemoteIdRef = useRef3(void 0);
456
- useEffect3(() => {
579
+ const wasRunningRef = useRef4(false);
580
+ const syncedRemoteIdRef = useRef4(void 0);
581
+ useEffect4(() => {
457
582
  syncedRemoteIdRef.current = void 0;
458
583
  }, [remoteId]);
459
- useEffect3(() => {
584
+ useEffect4(() => {
460
585
  const finishedTurn = wasRunningRef.current && !isRunning;
461
586
  wasRunningRef.current = isRunning;
462
587
  if (!finishedTurn || server == null || remoteId == null) {
@@ -484,22 +609,22 @@ function useSyncSessionTitle() {
484
609
  }
485
610
 
486
611
  // src/containers/ThreadContainer.tsx
487
- import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs3 } from "react/jsx-runtime";
612
+ import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs3 } from "react/jsx-runtime";
488
613
  function AnimatedMessageShell({ children }) {
489
- return /* @__PURE__ */ jsx8("div", { className: "animate-in fade-in slide-in-from-bottom-1 fill-mode-both duration-200", children });
614
+ return /* @__PURE__ */ jsx9("div", { className: "animate-in fade-in slide-in-from-bottom-1 fill-mode-both duration-200", children });
490
615
  }
491
616
  function ThreadMessage({ isEditing }) {
492
617
  const role = useAuiState5((s) => s.message.role);
493
618
  if (role === "user") {
494
619
  if (isEditing) {
495
- return /* @__PURE__ */ jsx8(UserEditComposerContainer, {});
620
+ return /* @__PURE__ */ jsx9(UserEditComposerContainer, {});
496
621
  }
497
- return /* @__PURE__ */ jsx8(UserMessageContainer, {});
622
+ return /* @__PURE__ */ jsx9(UserMessageContainer, {});
498
623
  }
499
- return /* @__PURE__ */ jsx8(AssistantMessageContainer, {});
624
+ return /* @__PURE__ */ jsx9(AssistantMessageContainer, {});
500
625
  }
501
626
  function ThreadContainer({ composer }) {
502
- useEffect4(() => {
627
+ useEffect5(() => {
503
628
  void preloadMarkdownOpenUI();
504
629
  }, []);
505
630
  useSyncSessionTitle();
@@ -514,32 +639,34 @@ function ThreadContainer({ composer }) {
514
639
  const isEmpty = useAuiState5(isNewChatView);
515
640
  const isLoading = useAuiState5((s) => s.thread.isLoading);
516
641
  const welcomeHeading = shell?.mode.status === "active" ? shell.mode.agentName != null && shell.mode.agentName.length > 0 ? shell.mode.agentName : shell.mode.isMutable && shell.mode.isCreateAgent ? "Start building a new Agent" : void 0 : void 0;
517
- return /* @__PURE__ */ jsx8(ComposerBusyProvider, { children: /* @__PURE__ */ jsx8(ThreadPrimitive.Root, { asChild: true, children: /* @__PURE__ */ jsxs3(ThreadRootShell, { children: [
518
- /* @__PURE__ */ jsx8(ThreadPrimitive.Viewport, { asChild: true, autoScroll: true, children: /* @__PURE__ */ jsxs3(ThreadViewportShell, { isEmpty, children: [
519
- isEmpty && /* @__PURE__ */ jsx8(WelcomeScreen, { heading: welcomeHeading }),
642
+ return /* @__PURE__ */ jsx9(ComposerBusyProvider, { children: /* @__PURE__ */ jsx9(ApprovalFocusProvider, { children: /* @__PURE__ */ jsx9(ThreadPrimitive.Root, { asChild: true, children: /* @__PURE__ */ jsxs3(ThreadRootShell, { children: [
643
+ /* @__PURE__ */ jsx9(ThreadPrimitive.Viewport, { asChild: true, autoScroll: true, children: /* @__PURE__ */ jsxs3(ThreadViewportShell, { isEmpty, children: [
644
+ isEmpty && /* @__PURE__ */ jsx9(WelcomeScreen, { heading: welcomeHeading }),
520
645
  isEmpty && !isLoading && composer,
521
- isLoading ? /* @__PURE__ */ jsx8(MessageListSkeleton, {}) : !isEmpty && /* @__PURE__ */ jsxs3(Fragment2, { children: [
522
- /* @__PURE__ */ jsx8(HistoryLoaderContainer, {}),
646
+ isLoading ? /* @__PURE__ */ jsx9(MessageListSkeleton, {}) : !isEmpty && /* @__PURE__ */ jsxs3(Fragment2, { children: [
647
+ /* @__PURE__ */ jsx9(HistoryLoaderContainer, {}),
523
648
  /* @__PURE__ */ jsxs3(MessageGroup, { children: [
524
- /* @__PURE__ */ jsx8(ThreadPrimitive.Messages, { children: ({ message }) => /* @__PURE__ */ jsx8(AnimatedMessageShell, { children: /* @__PURE__ */ jsx8(ThreadMessage, { isEditing: message.role === "user" && message.composer.isEditing }) }) }),
525
- /* @__PURE__ */ jsx8(ResumeUnavailableContainer, {})
649
+ /* @__PURE__ */ jsx9(ThreadPrimitive.Messages, { children: ({ message }) => /* @__PURE__ */ jsx9(AnimatedMessageShell, { children: /* @__PURE__ */ jsx9(ThreadMessage, { isEditing: message.role === "user" && message.composer.isEditing }) }) }),
650
+ /* @__PURE__ */ jsx9(ResumeUnavailableContainer, {})
526
651
  ] })
527
652
  ] })
528
653
  ] }) }),
529
654
  !isLoading && !isEmpty && /* @__PURE__ */ jsxs3(ThreadComposerAreaShell, { isEmpty, children: [
530
- /* @__PURE__ */ jsx8(ThreadPrimitive.ScrollToBottom, { asChild: true, children: /* @__PURE__ */ jsx8(ScrollToBottomButton, {}) }),
655
+ /* @__PURE__ */ jsx9(ThreadPrimitive.ScrollToBottom, { asChild: true, children: /* @__PURE__ */ jsx9(ScrollToBottomButton, {}) }),
531
656
  composer
532
657
  ] })
533
- ] }) }) });
658
+ ] }) }) }) });
534
659
  }
535
660
 
536
661
  // src/containers/Thread.tsx
537
- import { jsx as jsx9 } from "react/jsx-runtime";
662
+ import { jsx as jsx10 } from "react/jsx-runtime";
538
663
  function Thread() {
539
- return /* @__PURE__ */ jsx9(ThreadContainer, { composer: /* @__PURE__ */ jsx9(ComposerContainer, {}) });
664
+ return /* @__PURE__ */ jsx10(ThreadContainer, { composer: /* @__PURE__ */ jsx10(ComposerContainer, {}) });
540
665
  }
541
666
 
542
667
  export {
668
+ useApprovalNav,
669
+ ApprovalNavContainer,
543
670
  AskUserContainer,
544
671
  threadHasPendingMcpAuth,
545
672
  useComposerPauseView,
@@ -552,4 +679,4 @@ export {
552
679
  ThreadContainer,
553
680
  Thread
554
681
  };
555
- //# sourceMappingURL=chunk-G2TUAD65.js.map
682
+ //# sourceMappingURL=chunk-XY6LZQES.js.map