@tutti-os/agent-gui 0.0.12 → 0.0.14

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 (76) hide show
  1. package/dist/agent-conversation/index.d.ts +5 -52
  2. package/dist/agent-conversation/index.js +4 -3
  3. package/dist/agent-conversation/index.js.map +1 -1
  4. package/dist/agent-message-center/index.d.ts +15 -5
  5. package/dist/agent-message-center/index.js +47 -28
  6. package/dist/agent-message-center/index.js.map +1 -1
  7. package/dist/{agentConversationVM-BtHYOTgv.d.ts → agentConversationVM-BVe64P2E.d.ts} +1 -1
  8. package/dist/app/renderer/agentactivity.css +111 -134
  9. package/dist/app/renderer/assets/icons/agents/manage-agent-tutti.png +0 -0
  10. package/dist/app/renderer/assets/icons/agents/tutti-doc-rounded.png +0 -0
  11. package/dist/app/renderer/assets/icons/agents/workspace-dock-agent-nexight.png +0 -0
  12. package/dist/chunk-3YZX5EUC.js +1993 -0
  13. package/dist/chunk-3YZX5EUC.js.map +1 -0
  14. package/dist/{chunk-QU4F2RSS.js → chunk-ASAZDEQE.js} +7 -7
  15. package/dist/chunk-ASAZDEQE.js.map +1 -0
  16. package/dist/{chunk-Y3AQGWJA.js → chunk-FSTZDNRM.js} +43 -3
  17. package/dist/chunk-FSTZDNRM.js.map +1 -0
  18. package/dist/{chunk-72YSPOHX.js → chunk-GZHQPPK2.js} +626 -1915
  19. package/dist/chunk-GZHQPPK2.js.map +1 -0
  20. package/dist/{chunk-Y5O7BVGU.js → chunk-HSXDSFKB.js} +10 -1123
  21. package/dist/chunk-HSXDSFKB.js.map +1 -0
  22. package/dist/{chunk-PKCJR6GC.js → chunk-KEKPOVQD.js} +14 -7
  23. package/dist/chunk-KEKPOVQD.js.map +1 -0
  24. package/dist/{chunk-4ASBZ4X7.js → chunk-MTFSQWZ6.js} +2 -2
  25. package/dist/chunk-MU2LODEV.js +1211 -0
  26. package/dist/chunk-MU2LODEV.js.map +1 -0
  27. package/dist/{chunk-R5Q2UDDH.js → chunk-Q75AK47T.js} +2 -2
  28. package/dist/{chunk-PONEQEJ5.js → chunk-RLPVFX7V.js} +137 -31
  29. package/dist/chunk-RLPVFX7V.js.map +1 -0
  30. package/dist/chunk-VDNMTW2E.js +9 -0
  31. package/dist/chunk-VDNMTW2E.js.map +1 -0
  32. package/dist/chunk-WME2V26J.js +1124 -0
  33. package/dist/chunk-WME2V26J.js.map +1 -0
  34. package/dist/chunk-YXSO4ITT.js +10 -0
  35. package/dist/chunk-YXSO4ITT.js.map +1 -0
  36. package/dist/{chunk-3735XYFZ.js → chunk-ZO3SZCIX.js} +54 -3
  37. package/dist/chunk-ZO3SZCIX.js.map +1 -0
  38. package/dist/context-mention-palette/index.d.ts +203 -0
  39. package/dist/context-mention-palette/index.js +30 -0
  40. package/dist/context-mention-provider.d.ts +51 -0
  41. package/dist/context-mention-provider.js +7 -0
  42. package/dist/context-mention-provider.js.map +1 -0
  43. package/dist/i18n/index.d.ts +42 -2
  44. package/dist/i18n/index.js +1 -1
  45. package/dist/index.d.ts +33 -6
  46. package/dist/index.js +2486 -3690
  47. package/dist/index.js.map +1 -1
  48. package/dist/plan-decision-ops.d.ts +2 -2
  49. package/dist/workbench/contribution.js +5 -5
  50. package/dist/workbench/index.d.ts +2 -2
  51. package/dist/workbench/index.js +10 -6
  52. package/dist/workbench/launch.d.ts +19 -2
  53. package/dist/workbench/launch.js +7 -2
  54. package/dist/workbench/types.d.ts +6 -1
  55. package/dist/workbench/types.js +5 -3
  56. package/dist/workspace-agent-generated-files.d.ts +1 -1
  57. package/dist/workspace-agent-generated-files.js +2 -2
  58. package/dist/{workspaceAgentActivityListViewModel-BLLYGuFO.d.ts → workspaceAgentActivityListViewModel-BK_J3aNX.d.ts} +8 -5
  59. package/dist/{workspaceLinkActions-Bwa-phu8.d.ts → workspaceLinkActions-BlLN8Pvz.d.ts} +7 -1
  60. package/package.json +24 -15
  61. package/dist/agent-rich-text-at-provider.d.ts +0 -49
  62. package/dist/agent-rich-text-at-provider.js +0 -7
  63. package/dist/chunk-3735XYFZ.js.map +0 -1
  64. package/dist/chunk-6AZ2KF6R.js +0 -7
  65. package/dist/chunk-6AZ2KF6R.js.map +0 -1
  66. package/dist/chunk-72YSPOHX.js.map +0 -1
  67. package/dist/chunk-KCC3GNPB.js +0 -13
  68. package/dist/chunk-KCC3GNPB.js.map +0 -1
  69. package/dist/chunk-PKCJR6GC.js.map +0 -1
  70. package/dist/chunk-PONEQEJ5.js.map +0 -1
  71. package/dist/chunk-QU4F2RSS.js.map +0 -1
  72. package/dist/chunk-Y3AQGWJA.js.map +0 -1
  73. package/dist/chunk-Y5O7BVGU.js.map +0 -1
  74. /package/dist/{chunk-4ASBZ4X7.js.map → chunk-MTFSQWZ6.js.map} +0 -0
  75. /package/dist/{chunk-R5Q2UDDH.js.map → chunk-Q75AK47T.js.map} +0 -0
  76. /package/dist/{agent-rich-text-at-provider.js.map → context-mention-palette/index.js.map} +0 -0
@@ -0,0 +1,1124 @@
1
+ import {
2
+ PLAN_IMPLEMENTATION_ACTION_FEEDBACK,
3
+ PLAN_IMPLEMENTATION_ACTION_IMPLEMENT,
4
+ PLAN_IMPLEMENTATION_ACTION_SKIP
5
+ } from "./chunk-MKHDRIGN.js";
6
+ import {
7
+ AgentGUIConversation_styles_default,
8
+ MessageSquareMoreIcon,
9
+ extractAgentMcpToolTarget,
10
+ getOptionalAgentHostApi,
11
+ useOptionalAgentHostApi
12
+ } from "./chunk-RLPVFX7V.js";
13
+ import {
14
+ Spinner
15
+ } from "./chunk-HSXDSFKB.js";
16
+ import {
17
+ translate
18
+ } from "./chunk-FSTZDNRM.js";
19
+
20
+ // shared/agentConversation/approvalOptionPresentation.ts
21
+ function approvalOptionDisplayLabel(option, intent = {}) {
22
+ const idToken = normalizeApprovalOptionToken(option.id);
23
+ const kindToken = normalizeApprovalOptionToken(option.kind);
24
+ const label = option.label.trim();
25
+ const specificTranslationKey = approvalOptionSpecificTranslationKey(
26
+ idToken,
27
+ label,
28
+ intent
29
+ );
30
+ if (specificTranslationKey) {
31
+ return translate(specificTranslationKey);
32
+ }
33
+ const providerLabelTranslation = approvalOptionProviderLabelTranslation(label);
34
+ if (providerLabelTranslation) {
35
+ return translate(
36
+ providerLabelTranslation.key,
37
+ providerLabelTranslation.params
38
+ );
39
+ }
40
+ if ((idToken === "allowonce" || kindToken === "allowonce") && isGenericAllowOnceLabel(label)) {
41
+ return translate("agentHost.agentGui.approvalOptions.allowOnce");
42
+ }
43
+ if ((idToken === "allowalways" || idToken === "allowall" || kindToken === "allowalways") && isGenericApprovalLabel(label)) {
44
+ return translate("agentHost.agentGui.approvalOptions.allowAlways");
45
+ }
46
+ if (idToken === "rejectalways" || kindToken === "rejectalways") {
47
+ return translate("agentHost.agentGui.approvalOptions.rejectAlways");
48
+ }
49
+ if (idToken === "rejectonce" || idToken === "reject" || idToken === "deny" || kindToken === "rejectonce" || kindToken === "reject" || kindToken === "deny") {
50
+ return intent.feedback ? translate("agentHost.agentGui.approvalOptions.rejectWithFollowUp") : translate("agentHost.agentGui.approvalOptions.rejectOnce");
51
+ }
52
+ return label || option.id;
53
+ }
54
+ function approvalOptionVisualPresentation(option, intent = {}) {
55
+ const commandPrefix = approvalOptionCommandPrefix(option.label);
56
+ if (commandPrefix) {
57
+ return {
58
+ label: translate(
59
+ "agentHost.agentGui.approvalOptions.allowAlwaysForCommandPrefixLead"
60
+ ),
61
+ commandPrefix
62
+ };
63
+ }
64
+ return {
65
+ label: approvalOptionDisplayLabel(option, intent)
66
+ };
67
+ }
68
+ function normalizeApprovalOptionToken(value) {
69
+ return value.trim().toLowerCase().replace(/[^a-z0-9]+/g, "");
70
+ }
71
+ function approvalOptionSpecificTranslationKey(token, label, intent = {}) {
72
+ const labelToken = normalizeApprovalOptionToken(label);
73
+ switch (token) {
74
+ case "approved":
75
+ return isGenericAllowOnceLabel(label) ? "agentHost.agentGui.approvalOptions.allowOnce" : null;
76
+ case "approvedforsession":
77
+ return labelToken === "allowforthissession" ? "agentHost.agentGui.approvalOptions.allowForSession" : null;
78
+ case "approvedalways":
79
+ return isGenericApprovalLabel(label) ? "agentHost.agentGui.approvalOptions.allowAlways" : null;
80
+ case "bypasspermissions":
81
+ return "agentHost.agentGui.approvalOptions.bypassPermissions";
82
+ case "auto":
83
+ return labelToken === "yesanduseautomode" ? "agentHost.agentGui.approvalOptions.autoMode" : null;
84
+ case "acceptedits":
85
+ return "agentHost.agentGui.approvalOptions.acceptEdits";
86
+ case "default":
87
+ return labelToken === "yesandmanuallyapproveedits" ? "agentHost.agentGui.approvalOptions.manualApproval" : null;
88
+ case "cancel":
89
+ return !intent.feedback && labelToken === "cancel" ? "common.cancel" : null;
90
+ default:
91
+ return null;
92
+ }
93
+ }
94
+ function approvalOptionProviderLabelTranslation(label) {
95
+ const commandPrefix = approvalOptionCommandPrefix(label);
96
+ if (commandPrefix) {
97
+ return {
98
+ key: "agentHost.agentGui.approvalOptions.allowAlwaysForCommandPrefix",
99
+ params: { command: commandPrefix }
100
+ };
101
+ }
102
+ const allowScopeMatch = label.match(/^Yes,\s*and don't ask again for (.+)$/i);
103
+ if (allowScopeMatch?.[1]) {
104
+ return {
105
+ key: "agentHost.agentGui.approvalOptions.allowAlwaysForScope",
106
+ params: { scope: allowScopeMatch[1] }
107
+ };
108
+ }
109
+ const alwaysAllowMatch = label.match(/^Always Allow\s+(.+)$/i);
110
+ if (alwaysAllowMatch?.[1]) {
111
+ return {
112
+ key: "agentHost.agentGui.approvalOptions.alwaysAllowScope",
113
+ params: { scope: alwaysAllowMatch[1] }
114
+ };
115
+ }
116
+ return null;
117
+ }
118
+ function approvalOptionCommandPrefix(label) {
119
+ const commandPrefixMatch = label.match(
120
+ /^Yes,\s*and don't ask again for commands that start with `([^`]+)`$/i
121
+ );
122
+ return commandPrefixMatch?.[1]?.trim() || null;
123
+ }
124
+ function isGenericApprovalLabel(label) {
125
+ const token = normalizeApprovalOptionToken(label);
126
+ return token === "" || token === "allowalways" || token === "allowall" || token === "alwaysallow" || token === "allowanddontaskagain" || token === "yesanddontaskagain";
127
+ }
128
+ function isGenericAllowOnceLabel(label) {
129
+ const token = normalizeApprovalOptionToken(label);
130
+ return token === "" || token === "allow" || token === "allowonce" || token === "yes" || token === "yesproceed" || token === "yesandproceed";
131
+ }
132
+
133
+ // shared/agentConversation/promptToolDetails.ts
134
+ function getPromptToolDetails(input) {
135
+ if (!input) {
136
+ return [];
137
+ }
138
+ const mcpTarget = extractAgentMcpToolTarget({ input });
139
+ const mcpDetails = mcpTarget ? [
140
+ {
141
+ kind: "mcp",
142
+ value: mcpTarget.displayName,
143
+ ...mcpTarget.instruction ? { meta: mcpTarget.instruction } : {}
144
+ }
145
+ ] : [];
146
+ const detailInput = resolveToolDetailInput(input);
147
+ const command = commandStringValue(detailInput.command) ?? commandStringValue(detailInput.cmd);
148
+ if (command) {
149
+ return [
150
+ ...mcpDetails,
151
+ {
152
+ kind: "command",
153
+ value: command,
154
+ ...stringValue(detailInput.description) ? { meta: stringValue(detailInput.description) } : {}
155
+ }
156
+ ];
157
+ }
158
+ const filePath = stringValue(detailInput.file_path) ?? stringValue(detailInput.filePath) ?? stringValue(detailInput.path) ?? stringValue(detailInput.notebook_path);
159
+ if (filePath) {
160
+ const lineRange = formatLineRange(detailInput);
161
+ return [
162
+ ...mcpDetails,
163
+ {
164
+ kind: "path",
165
+ value: filePath,
166
+ ...lineRange ? { meta: lineRange } : {}
167
+ }
168
+ ];
169
+ }
170
+ const query = stringValue(detailInput.query) ?? stringValue(detailInput.search_query) ?? stringValue(detailInput.searchQuery) ?? stringValue(detailInput.pattern);
171
+ if (query) {
172
+ return [
173
+ ...mcpDetails,
174
+ {
175
+ kind: "query",
176
+ value: query
177
+ }
178
+ ];
179
+ }
180
+ return mcpDetails;
181
+ }
182
+ function isPromptRequestIdTitle(value) {
183
+ return /^request(?:id|ID)\s*:/u.test(value.trim());
184
+ }
185
+ function resolveToolDetailInput(input) {
186
+ const toolCall = objectValue(input.toolCall);
187
+ return firstObjectValue(input, [
188
+ "command",
189
+ "cmd",
190
+ "file_path",
191
+ "filePath",
192
+ "path",
193
+ "notebook_path",
194
+ "query",
195
+ "search_query",
196
+ "searchQuery",
197
+ "pattern"
198
+ ]) ?? firstObjectValue(toolCall, [
199
+ "input",
200
+ "rawInput",
201
+ "raw_input",
202
+ "arguments",
203
+ "args"
204
+ ]) ?? toolCall ?? input;
205
+ }
206
+ function firstObjectValue(input, keys) {
207
+ if (!input) {
208
+ return null;
209
+ }
210
+ if (keys.some((key) => stringValue(input[key]))) {
211
+ return input;
212
+ }
213
+ for (const key of keys) {
214
+ const value = objectValue(input[key]);
215
+ if (value) {
216
+ return value;
217
+ }
218
+ }
219
+ return null;
220
+ }
221
+ function formatLineRange(input) {
222
+ const start = numericValue(input.startLine) ?? numericValue(input.start_line);
223
+ const end = numericValue(input.endLine) ?? numericValue(input.end_line);
224
+ if (start === null || end === null) {
225
+ return null;
226
+ }
227
+ return start === end ? `L${start}` : `L${start}-${end}`;
228
+ }
229
+ function stringValue(value) {
230
+ return typeof value === "string" && value.trim() ? value.trim() : null;
231
+ }
232
+ function commandStringValue(value) {
233
+ if (typeof value === "string") {
234
+ return stringValue(value);
235
+ }
236
+ if (!Array.isArray(value)) {
237
+ return null;
238
+ }
239
+ const shellFlag = stringValue(value[value.length - 2]);
240
+ const shellCommand = stringValue(value[value.length - 1]);
241
+ if ((shellFlag === "-c" || shellFlag === "-lc") && shellCommand) {
242
+ return shellCommand;
243
+ }
244
+ const parts = value.flatMap((part) => {
245
+ const text = stringValue(part);
246
+ return text ? [text] : [];
247
+ });
248
+ return parts.length > 0 ? parts.join(" ") : null;
249
+ }
250
+ function objectValue(value) {
251
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
252
+ }
253
+ function numericValue(value) {
254
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
255
+ }
256
+
257
+ // shared/agentConversation/components/AgentInteractivePromptSurface.tsx
258
+ import {
259
+ useCallback,
260
+ useEffect,
261
+ useMemo,
262
+ useRef,
263
+ useState
264
+ } from "react";
265
+ import {
266
+ ShortcutBadge,
267
+ Tooltip,
268
+ TooltipContent,
269
+ TooltipProvider,
270
+ TooltipTrigger
271
+ } from "@tutti-os/ui-system";
272
+
273
+ // shared/agentConversation/interactiveAnswerPayload.ts
274
+ function buildAskUserAnswerPayload(answersByQuestionId) {
275
+ const answers = Object.values(answersByQuestionId).map(
276
+ (value) => Array.isArray(value) ? value.join(", ") : value
277
+ );
278
+ return { answers, answersByQuestionId };
279
+ }
280
+
281
+ // shared/agentConversation/components/AgentInteractivePromptSurface.tsx
282
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
283
+ var COMMAND_TOOLTIP_DELAY_MS = 1e3;
284
+ function AgentInteractivePromptSurface({
285
+ prompt,
286
+ variant = "full",
287
+ edgeGlow = false,
288
+ embedded = false,
289
+ keyboardShortcuts = true,
290
+ isSubmitting,
291
+ onSubmit,
292
+ labels
293
+ }) {
294
+ "use memo";
295
+ if (prompt.kind === "approval") {
296
+ return /* @__PURE__ */ jsx(
297
+ ApprovalPromptSurface,
298
+ {
299
+ prompt,
300
+ embedded,
301
+ edgeGlow,
302
+ keyboardShortcuts,
303
+ isSubmitting,
304
+ onSubmit,
305
+ labels
306
+ }
307
+ );
308
+ }
309
+ if (prompt.kind === "exit-plan") {
310
+ return /* @__PURE__ */ jsx(
311
+ ExitPlanPromptSurface,
312
+ {
313
+ prompt,
314
+ variant,
315
+ embedded,
316
+ edgeGlow,
317
+ isSubmitting,
318
+ onSubmit,
319
+ labels
320
+ }
321
+ );
322
+ }
323
+ if (prompt.kind === "plan-implementation") {
324
+ return /* @__PURE__ */ jsx(
325
+ PlanImplementationSurface,
326
+ {
327
+ prompt,
328
+ variant,
329
+ embedded,
330
+ edgeGlow,
331
+ isSubmitting,
332
+ onSubmit,
333
+ labels
334
+ }
335
+ );
336
+ }
337
+ return /* @__PURE__ */ jsx(
338
+ AskUserPromptSurface,
339
+ {
340
+ prompt,
341
+ variant,
342
+ embedded,
343
+ edgeGlow,
344
+ isSubmitting,
345
+ onSubmit,
346
+ labels
347
+ }
348
+ );
349
+ }
350
+ function CompactAskUserPromptSurface({
351
+ prompt,
352
+ embedded = false,
353
+ edgeGlow = false,
354
+ isSubmitting,
355
+ onSubmit
356
+ }) {
357
+ "use memo";
358
+ const question = prompt.questions[0] ?? null;
359
+ const oneClickable = prompt.questions.length === 1 && question !== null && !question.multiSelect && question.options.length > 0;
360
+ return /* @__PURE__ */ jsx("section", { className: interactivePromptClassName(embedded), children: /* @__PURE__ */ jsx("div", { className: interactivePromptCardClassName(edgeGlow), children: question ? /* @__PURE__ */ jsxs(Fragment, { children: [
361
+ /* @__PURE__ */ jsx("div", { className: AgentGUIConversation_styles_default.interactivePromptHeader, children: /* @__PURE__ */ jsx("span", { className: AgentGUIConversation_styles_default.interactivePromptLead, children: stripPromptTitlePunctuation(question.header) }) }),
362
+ /* @__PURE__ */ jsx("div", { className: AgentGUIConversation_styles_default.interactivePromptQuestion, children: question.question }),
363
+ oneClickable ? /* @__PURE__ */ jsx("div", { className: AgentGUIConversation_styles_default.interactivePromptOptions, children: question.options.map((option) => /* @__PURE__ */ jsxs(
364
+ "button",
365
+ {
366
+ type: "button",
367
+ className: AgentGUIConversation_styles_default.interactiveOptionButton,
368
+ "aria-label": interactiveOptionLabel(
369
+ option.label,
370
+ option.description
371
+ ),
372
+ disabled: isSubmitting,
373
+ onClick: () => onSubmit({
374
+ requestId: prompt.requestId,
375
+ action: "submit",
376
+ payload: {
377
+ ...buildAskUserAnswerPayload({
378
+ [question.id]: option.label
379
+ })
380
+ }
381
+ }),
382
+ children: [
383
+ /* @__PURE__ */ jsx("span", { className: AgentGUIConversation_styles_default.interactiveOptionTitle, children: option.label }),
384
+ option.description ? /* @__PURE__ */ jsx("span", { className: AgentGUIConversation_styles_default.interactiveOptionDescription, children: option.description }) : null
385
+ ]
386
+ },
387
+ option.label
388
+ )) }) : null
389
+ ] }) : null }) });
390
+ }
391
+ function ApprovalPromptSurface({
392
+ prompt,
393
+ embedded = false,
394
+ edgeGlow = false,
395
+ keyboardShortcuts = true,
396
+ isSubmitting,
397
+ onSubmit,
398
+ labels
399
+ }) {
400
+ "use memo";
401
+ const promptDetails = useMemo(
402
+ () => formatToolDetails(prompt.input ?? null),
403
+ [prompt.input]
404
+ );
405
+ const visiblePromptTitle = approvalPromptTitle(
406
+ prompt.title,
407
+ promptDetails.length
408
+ );
409
+ const details = useMemo(
410
+ () => filterDuplicatePromptTitleDetails(promptDetails, visiblePromptTitle),
411
+ [promptDetails, visiblePromptTitle]
412
+ );
413
+ const [submittingOptionId, setSubmittingOptionId] = useState(
414
+ null
415
+ );
416
+ const [pendingFeedbackOptionId, setPendingFeedbackOptionId] = useState(null);
417
+ const [feedback, setFeedback] = useState("");
418
+ const feedbackTextareaRef = useRef(null);
419
+ const agentHostApi = useOptionalAgentHostApi() ?? getOptionalAgentHostApi();
420
+ const isDarwin = isDarwinPlatform(agentHostApi?.meta?.platform);
421
+ const feedbackOptionId = useMemo(
422
+ () => approvalFeedbackOptionId(prompt.options),
423
+ [prompt.options]
424
+ );
425
+ const feedbackValue = feedback.trim();
426
+ useEffect(() => {
427
+ setSubmittingOptionId(null);
428
+ setPendingFeedbackOptionId(null);
429
+ setFeedback("");
430
+ }, [prompt.requestId]);
431
+ useEffect(() => {
432
+ if (pendingFeedbackOptionId !== null) {
433
+ feedbackTextareaRef.current?.focus();
434
+ }
435
+ }, [pendingFeedbackOptionId]);
436
+ const submitOption = useCallback(
437
+ (optionId) => {
438
+ const feedbackOption = feedbackOptionId === optionId;
439
+ if (feedbackOption && pendingFeedbackOptionId !== optionId) {
440
+ setFeedback("");
441
+ setPendingFeedbackOptionId(optionId);
442
+ return;
443
+ }
444
+ setSubmittingOptionId(optionId);
445
+ onSubmit({
446
+ requestId: prompt.requestId,
447
+ ...feedbackOption ? { action: "deny" } : {},
448
+ optionId,
449
+ ...feedbackOption && feedbackValue ? { payload: { denyMessage: feedbackValue } } : {}
450
+ });
451
+ },
452
+ [
453
+ feedbackOptionId,
454
+ feedbackValue,
455
+ onSubmit,
456
+ pendingFeedbackOptionId,
457
+ prompt.requestId
458
+ ]
459
+ );
460
+ useEffect(() => {
461
+ if (!keyboardShortcuts || isSubmitting || submittingOptionId !== null || prompt.options.length === 0) {
462
+ return void 0;
463
+ }
464
+ const handleKeyDown = (event) => {
465
+ if (!isEnterLikeKey(event) || isEditableKeyboardTarget(event.target) || event.isComposing || event.altKey || event.shiftKey) {
466
+ return;
467
+ }
468
+ const optionIndex = event.metaKey || event.ctrlKey ? 1 : 0;
469
+ const option = prompt.options[optionIndex];
470
+ if (!option) {
471
+ return;
472
+ }
473
+ event.preventDefault();
474
+ event.stopPropagation();
475
+ submitOption(option.id);
476
+ };
477
+ window.addEventListener("keydown", handleKeyDown, true);
478
+ return () => window.removeEventListener("keydown", handleKeyDown, true);
479
+ }, [
480
+ isSubmitting,
481
+ keyboardShortcuts,
482
+ prompt.options,
483
+ submitOption,
484
+ submittingOptionId
485
+ ]);
486
+ return /* @__PURE__ */ jsx("section", { className: interactivePromptClassName(embedded), children: /* @__PURE__ */ jsxs("div", { className: interactivePromptCardClassName(edgeGlow), children: [
487
+ /* @__PURE__ */ jsx("div", { className: AgentGUIConversation_styles_default.interactivePromptLead, children: stripPromptTitlePunctuation(labels.approvalLead) }),
488
+ visiblePromptTitle ? /* @__PURE__ */ jsx("div", { className: AgentGUIConversation_styles_default.interactivePromptQuestion, children: visiblePromptTitle }) : null,
489
+ details.length > 0 ? /* @__PURE__ */ jsx("div", { className: AgentGUIConversation_styles_default.interactivePromptOptions, children: details.map((detail) => /* @__PURE__ */ jsxs(
490
+ "div",
491
+ {
492
+ className: AgentGUIConversation_styles_default.interactiveOptionDisplay,
493
+ children: [
494
+ /* @__PURE__ */ jsx("span", { className: AgentGUIConversation_styles_default.interactiveOptionTitle, children: detail.label }),
495
+ /* @__PURE__ */ jsx(PromptDetailValue, { detail }),
496
+ detail.meta ? /* @__PURE__ */ jsx("span", { className: AgentGUIConversation_styles_default.interactiveOptionDescription, children: detail.meta }) : null
497
+ ]
498
+ },
499
+ `${detail.label}:${detail.value}`
500
+ )) }) : null,
501
+ /* @__PURE__ */ jsx("div", { className: AgentGUIConversation_styles_default.interactivePromptOptions, children: prompt.options.map((option, optionIndex) => {
502
+ const showSpinner = submittingOptionId === option.id;
503
+ const optionSupportsFeedback = feedbackOptionId === option.id;
504
+ const optionLabel = approvalOptionDisplayLabel(option, {
505
+ feedback: optionSupportsFeedback
506
+ });
507
+ const optionPresentation = approvalOptionVisualPresentation(
508
+ option,
509
+ { feedback: optionSupportsFeedback }
510
+ );
511
+ const shortcutLabel = approvalOptionShortcutLabel(
512
+ optionIndex,
513
+ isDarwin
514
+ );
515
+ const showFeedbackComposer = pendingFeedbackOptionId === option.id;
516
+ if (showFeedbackComposer) {
517
+ return /* @__PURE__ */ jsxs(
518
+ "div",
519
+ {
520
+ className: AgentGUIConversation_styles_default.interactiveFeedbackComposer,
521
+ children: [
522
+ /* @__PURE__ */ jsx(
523
+ "textarea",
524
+ {
525
+ ref: feedbackTextareaRef,
526
+ value: feedback,
527
+ placeholder: labels.feedbackPlaceholder,
528
+ disabled: isSubmitting || submittingOptionId !== null,
529
+ className: AgentGUIConversation_styles_default.interactivePromptTextarea,
530
+ "aria-label": interactiveOptionLabel(
531
+ optionLabel,
532
+ option.description
533
+ ),
534
+ onChange: (event) => setFeedback(event.currentTarget.value),
535
+ onKeyDown: (event) => {
536
+ if (!keyboardShortcuts || event.key !== "Enter" || !event.metaKey && !event.ctrlKey || event.nativeEvent.isComposing) {
537
+ return;
538
+ }
539
+ event.preventDefault();
540
+ if (!feedbackValue) {
541
+ feedbackTextareaRef.current?.focus();
542
+ return;
543
+ }
544
+ submitOption(option.id);
545
+ }
546
+ }
547
+ ),
548
+ /* @__PURE__ */ jsx(
549
+ "button",
550
+ {
551
+ type: "button",
552
+ className: AgentGUIConversation_styles_default.interactiveFeedbackSendButton,
553
+ disabled: isSubmitting || submittingOptionId !== null || !feedbackValue,
554
+ "aria-label": labels.sendFeedback,
555
+ title: labels.sendFeedback,
556
+ "aria-busy": showSpinner,
557
+ onClick: () => {
558
+ if (!feedbackValue) {
559
+ feedbackTextareaRef.current?.focus();
560
+ return;
561
+ }
562
+ submitOption(option.id);
563
+ },
564
+ children: showSpinner ? /* @__PURE__ */ jsx(InteractiveOptionSpinner, {}) : /* @__PURE__ */ jsx(SendFilledIcon, {})
565
+ }
566
+ )
567
+ ]
568
+ },
569
+ option.id
570
+ );
571
+ }
572
+ return /* @__PURE__ */ jsxs(
573
+ "button",
574
+ {
575
+ type: "button",
576
+ className: AgentGUIConversation_styles_default.interactiveOptionButton,
577
+ "aria-label": interactiveOptionLabel(
578
+ optionLabel,
579
+ option.description
580
+ ),
581
+ disabled: isSubmitting || submittingOptionId !== null,
582
+ onClick: () => submitOption(option.id),
583
+ children: [
584
+ /* @__PURE__ */ jsx("span", { className: AgentGUIConversation_styles_default.interactiveOptionTitle, children: optionPresentation.label }),
585
+ optionPresentation.commandPrefix ? /* @__PURE__ */ jsx(
586
+ CommandTextWithTooltip,
587
+ {
588
+ value: optionPresentation.commandPrefix,
589
+ testId: "agent-interactive-command-prefix-option"
590
+ }
591
+ ) : null,
592
+ option.description ? /* @__PURE__ */ jsx("span", { className: AgentGUIConversation_styles_default.interactiveOptionDescription, children: option.description }) : null,
593
+ keyboardShortcuts && shortcutLabel && !showSpinner ? /* @__PURE__ */ jsx(
594
+ ShortcutBadge,
595
+ {
596
+ className: AgentGUIConversation_styles_default.interactiveOptionShortcut,
597
+ "aria-hidden": "true",
598
+ children: shortcutLabel
599
+ }
600
+ ) : null,
601
+ showSpinner ? /* @__PURE__ */ jsx(InteractiveOptionSpinner, {}) : null
602
+ ]
603
+ },
604
+ option.id
605
+ );
606
+ }) })
607
+ ] }) });
608
+ }
609
+ function ExitPlanPromptSurface({
610
+ prompt,
611
+ variant = "full",
612
+ embedded = false,
613
+ edgeGlow = false,
614
+ isSubmitting,
615
+ onSubmit,
616
+ labels
617
+ }) {
618
+ "use memo";
619
+ const [feedback, setFeedback] = useState("");
620
+ const showFeedbackFooter = variant !== "compact";
621
+ const [submittingOptionId, setSubmittingOptionId] = useState(
622
+ null
623
+ );
624
+ const trimmed = feedback.trim();
625
+ const continueLabel = trimmed === "" ? labels.stayInPlan : labels.sendFeedback;
626
+ useEffect(() => {
627
+ setSubmittingOptionId(null);
628
+ }, [prompt.requestId]);
629
+ return /* @__PURE__ */ jsx("section", { className: interactivePromptClassName(embedded), children: /* @__PURE__ */ jsxs("div", { className: interactivePromptCardClassName(edgeGlow), children: [
630
+ /* @__PURE__ */ jsx("div", { className: AgentGUIConversation_styles_default.interactivePromptLead, children: stripPromptTitlePunctuation(labels.planLead) }),
631
+ /* @__PURE__ */ jsx("div", { className: AgentGUIConversation_styles_default.interactivePromptOptions, children: labels.planModes.map((mode) => {
632
+ const showSpinner = submittingOptionId === mode.id;
633
+ return /* @__PURE__ */ jsxs(
634
+ "button",
635
+ {
636
+ type: "button",
637
+ className: AgentGUIConversation_styles_default.interactiveOptionButton,
638
+ "aria-label": interactiveOptionLabel(
639
+ mode.label,
640
+ mode.description
641
+ ),
642
+ disabled: isSubmitting || submittingOptionId !== null,
643
+ onClick: () => {
644
+ setSubmittingOptionId(mode.id);
645
+ onSubmit({
646
+ requestId: prompt.requestId,
647
+ action: "allow",
648
+ optionId: mode.id
649
+ });
650
+ },
651
+ children: [
652
+ /* @__PURE__ */ jsx("span", { className: AgentGUIConversation_styles_default.interactiveOptionTitle, children: mode.label }),
653
+ /* @__PURE__ */ jsx("span", { className: AgentGUIConversation_styles_default.interactiveOptionDescription, children: mode.description }),
654
+ showSpinner ? /* @__PURE__ */ jsx(InteractiveOptionSpinner, {}) : null
655
+ ]
656
+ },
657
+ mode.id
658
+ );
659
+ }) }),
660
+ showFeedbackFooter ? /* @__PURE__ */ jsxs("div", { className: AgentGUIConversation_styles_default.interactivePromptFooter, children: [
661
+ /* @__PURE__ */ jsx(
662
+ "textarea",
663
+ {
664
+ value: feedback,
665
+ placeholder: labels.feedbackPlaceholder,
666
+ disabled: isSubmitting,
667
+ className: AgentGUIConversation_styles_default.interactivePromptTextarea,
668
+ onChange: (event) => setFeedback(event.currentTarget.value)
669
+ }
670
+ ),
671
+ /* @__PURE__ */ jsx("div", { className: AgentGUIConversation_styles_default.interactivePromptActions, children: /* @__PURE__ */ jsx(
672
+ "button",
673
+ {
674
+ type: "button",
675
+ disabled: isSubmitting,
676
+ onClick: () => onSubmit({
677
+ requestId: prompt.requestId,
678
+ action: "deny",
679
+ payload: trimmed ? { denyMessage: trimmed } : void 0
680
+ }),
681
+ children: continueLabel
682
+ }
683
+ ) })
684
+ ] }) : null
685
+ ] }) });
686
+ }
687
+ function PlanImplementationSurface({
688
+ prompt,
689
+ variant = "full",
690
+ embedded = false,
691
+ edgeGlow = false,
692
+ isSubmitting,
693
+ onSubmit,
694
+ labels
695
+ }) {
696
+ "use memo";
697
+ const [feedback, setFeedback] = useState("");
698
+ const trimmed = feedback.trim();
699
+ const continueLabel = trimmed === "" ? labels.planImplementationSkip : labels.planImplementationSend;
700
+ const showFeedbackFooter = variant !== "compact";
701
+ return /* @__PURE__ */ jsx("section", { className: interactivePromptClassName(embedded), children: /* @__PURE__ */ jsxs("div", { className: interactivePromptCardClassName(edgeGlow), children: [
702
+ /* @__PURE__ */ jsx("div", { className: AgentGUIConversation_styles_default.interactivePromptLead, children: stripPromptTitlePunctuation(labels.planImplementationLead) }),
703
+ /* @__PURE__ */ jsx("div", { className: AgentGUIConversation_styles_default.interactivePromptOptions, children: /* @__PURE__ */ jsx(
704
+ "button",
705
+ {
706
+ type: "button",
707
+ className: AgentGUIConversation_styles_default.interactiveOptionButton,
708
+ "data-testid": "agent-plan-implementation-implement",
709
+ disabled: isSubmitting,
710
+ onClick: () => onSubmit({
711
+ requestId: prompt.requestId,
712
+ action: PLAN_IMPLEMENTATION_ACTION_IMPLEMENT
713
+ }),
714
+ children: /* @__PURE__ */ jsx("span", { className: AgentGUIConversation_styles_default.interactiveOptionTitle, children: labels.planImplementationConfirm })
715
+ }
716
+ ) }),
717
+ showFeedbackFooter ? /* @__PURE__ */ jsxs("div", { className: AgentGUIConversation_styles_default.interactivePromptFooter, children: [
718
+ /* @__PURE__ */ jsx(
719
+ "textarea",
720
+ {
721
+ value: feedback,
722
+ placeholder: labels.planImplementationFeedbackPlaceholder,
723
+ disabled: isSubmitting,
724
+ className: AgentGUIConversation_styles_default.interactivePromptTextarea,
725
+ "data-testid": "agent-plan-implementation-feedback",
726
+ onChange: (event) => setFeedback(event.currentTarget.value)
727
+ }
728
+ ),
729
+ /* @__PURE__ */ jsx("div", { className: AgentGUIConversation_styles_default.interactivePromptActions, children: /* @__PURE__ */ jsx(
730
+ "button",
731
+ {
732
+ type: "button",
733
+ "data-testid": "agent-plan-implementation-continue",
734
+ disabled: isSubmitting,
735
+ onClick: () => onSubmit({
736
+ requestId: prompt.requestId,
737
+ action: trimmed === "" ? PLAN_IMPLEMENTATION_ACTION_SKIP : PLAN_IMPLEMENTATION_ACTION_FEEDBACK,
738
+ payload: trimmed ? { text: trimmed } : void 0
739
+ }),
740
+ children: continueLabel
741
+ }
742
+ ) })
743
+ ] }) : null
744
+ ] }) });
745
+ }
746
+ function AskUserPromptSurface({
747
+ prompt,
748
+ variant = "full",
749
+ embedded = false,
750
+ edgeGlow = false,
751
+ isSubmitting,
752
+ onSubmit,
753
+ labels
754
+ }) {
755
+ "use memo";
756
+ if (variant === "compact") {
757
+ return /* @__PURE__ */ jsx(
758
+ CompactAskUserPromptSurface,
759
+ {
760
+ prompt,
761
+ embedded,
762
+ edgeGlow,
763
+ isSubmitting,
764
+ onSubmit,
765
+ labels
766
+ }
767
+ );
768
+ }
769
+ return /* @__PURE__ */ jsx(
770
+ FullAskUserPromptSurface,
771
+ {
772
+ prompt,
773
+ embedded,
774
+ edgeGlow,
775
+ isSubmitting,
776
+ onSubmit,
777
+ labels
778
+ }
779
+ );
780
+ }
781
+ function FullAskUserPromptSurface({
782
+ prompt,
783
+ embedded = false,
784
+ edgeGlow = false,
785
+ isSubmitting,
786
+ onSubmit,
787
+ labels
788
+ }) {
789
+ "use memo";
790
+ const [index, setIndex] = useState(0);
791
+ const [selectedByQuestionId, setSelectedByQuestionId] = useState({});
792
+ const [freeTextByQuestionId, setFreeTextByQuestionId] = useState({});
793
+ const question = prompt.questions[index] ?? null;
794
+ const selected = question ? selectedByQuestionId[question.id] ?? [] : [];
795
+ const freeText = question ? freeTextByQuestionId[question.id] ?? "" : "";
796
+ const canAdvance = question !== null && (selected.length > 0 || freeText.trim() !== "" || question.options.length === 0);
797
+ const isLast = index >= prompt.questions.length - 1;
798
+ const payload = useMemo(() => {
799
+ const answersByQuestionId = {};
800
+ for (const current of prompt.questions) {
801
+ const chosen = selectedByQuestionId[current.id] ?? [];
802
+ const other = (freeTextByQuestionId[current.id] ?? "").trim();
803
+ if (current.multiSelect) {
804
+ const value2 = other ? [...chosen, other] : chosen;
805
+ if (value2.length > 0) {
806
+ answersByQuestionId[current.id] = value2;
807
+ }
808
+ continue;
809
+ }
810
+ const value = other || chosen[0];
811
+ if (value) {
812
+ answersByQuestionId[current.id] = value;
813
+ }
814
+ }
815
+ return buildAskUserAnswerPayload(answersByQuestionId);
816
+ }, [freeTextByQuestionId, prompt.questions, selectedByQuestionId]);
817
+ if (!question) {
818
+ return /* @__PURE__ */ jsx("section", { className: interactivePromptClassName(embedded), children: /* @__PURE__ */ jsx("div", { className: interactivePromptCardClassName(edgeGlow), children: /* @__PURE__ */ jsxs(
819
+ "div",
820
+ {
821
+ className: `${AgentGUIConversation_styles_default.interactivePromptLead} inline-flex items-center gap-1.5`,
822
+ children: [
823
+ /* @__PURE__ */ jsx(
824
+ MessageSquareMoreIcon,
825
+ {
826
+ size: 15,
827
+ active: true,
828
+ "aria-hidden": "true",
829
+ className: "shrink-0"
830
+ }
831
+ ),
832
+ stripPromptTitlePunctuation(labels.waitingForAnswer)
833
+ ]
834
+ }
835
+ ) }) });
836
+ }
837
+ return /* @__PURE__ */ jsx("section", { className: interactivePromptClassName(embedded), children: /* @__PURE__ */ jsxs("div", { className: interactivePromptCardClassName(edgeGlow), children: [
838
+ /* @__PURE__ */ jsxs("div", { className: AgentGUIConversation_styles_default.interactivePromptHeader, children: [
839
+ /* @__PURE__ */ jsx("span", { className: AgentGUIConversation_styles_default.interactivePromptLead, children: stripPromptTitlePunctuation(question.header) }),
840
+ /* @__PURE__ */ jsxs("span", { className: AgentGUIConversation_styles_default.interactivePromptMeta, children: [
841
+ index + 1,
842
+ "/",
843
+ prompt.questions.length
844
+ ] })
845
+ ] }),
846
+ /* @__PURE__ */ jsx("div", { className: AgentGUIConversation_styles_default.interactivePromptQuestion, children: question.question }),
847
+ question.options.length > 0 ? /* @__PURE__ */ jsx("div", { className: AgentGUIConversation_styles_default.interactivePromptOptions, children: question.options.map((option) => {
848
+ const active = selected.includes(option.label);
849
+ return /* @__PURE__ */ jsxs(
850
+ "button",
851
+ {
852
+ type: "button",
853
+ className: AgentGUIConversation_styles_default.interactiveOptionButton,
854
+ "data-active": active,
855
+ "aria-label": interactiveOptionLabel(
856
+ option.label,
857
+ option.description
858
+ ),
859
+ disabled: isSubmitting,
860
+ onClick: () => {
861
+ setSelectedByQuestionId((current) => {
862
+ const existing = current[question.id] ?? [];
863
+ const next = question.multiSelect ? existing.includes(option.label) ? existing.filter((value) => value !== option.label) : [...existing, option.label] : existing.includes(option.label) ? [] : [option.label];
864
+ return { ...current, [question.id]: next };
865
+ });
866
+ },
867
+ children: [
868
+ /* @__PURE__ */ jsx("span", { className: AgentGUIConversation_styles_default.interactiveOptionTitle, children: option.label }),
869
+ /* @__PURE__ */ jsx("span", { className: AgentGUIConversation_styles_default.interactiveOptionDescription, children: option.description })
870
+ ]
871
+ },
872
+ option.label
873
+ );
874
+ }) }) : null,
875
+ /* @__PURE__ */ jsx(
876
+ "textarea",
877
+ {
878
+ value: freeText,
879
+ placeholder: labels.answerPlaceholder,
880
+ disabled: isSubmitting,
881
+ className: AgentGUIConversation_styles_default.interactivePromptTextarea,
882
+ onChange: (event) => {
883
+ const value = event.currentTarget.value;
884
+ setFreeTextByQuestionId((current) => ({
885
+ ...current,
886
+ [question.id]: value
887
+ }));
888
+ }
889
+ }
890
+ ),
891
+ /* @__PURE__ */ jsxs("div", { className: AgentGUIConversation_styles_default.interactivePromptActions, children: [
892
+ /* @__PURE__ */ jsx(
893
+ "button",
894
+ {
895
+ type: "button",
896
+ disabled: isSubmitting || index === 0,
897
+ onClick: () => setIndex((current) => Math.max(current - 1, 0)),
898
+ children: labels.previousQuestion
899
+ }
900
+ ),
901
+ isLast ? /* @__PURE__ */ jsx(
902
+ "button",
903
+ {
904
+ type: "button",
905
+ disabled: isSubmitting || Object.keys(payload.answersByQuestionId).length === 0,
906
+ onClick: () => onSubmit({
907
+ requestId: prompt.requestId,
908
+ action: "submit",
909
+ payload: { ...payload }
910
+ }),
911
+ children: labels.submitAnswers
912
+ }
913
+ ) : /* @__PURE__ */ jsx(
914
+ "button",
915
+ {
916
+ type: "button",
917
+ disabled: isSubmitting || !canAdvance,
918
+ onClick: () => setIndex(
919
+ (current) => Math.min(current + 1, prompt.questions.length - 1)
920
+ ),
921
+ children: labels.nextQuestion
922
+ }
923
+ )
924
+ ] })
925
+ ] }) });
926
+ }
927
+ function isEnterLikeKey(event) {
928
+ return event.key === "Enter" || event.code === "Enter" || event.code === "NumpadEnter";
929
+ }
930
+ function isEditableKeyboardTarget(target) {
931
+ if (!(target instanceof HTMLElement)) {
932
+ return false;
933
+ }
934
+ const tagName = target.tagName.toLowerCase();
935
+ return tagName === "input" || tagName === "textarea" || tagName === "select" || target.isContentEditable;
936
+ }
937
+ function approvalOptionShortcutLabel(optionIndex, isDarwin) {
938
+ if (optionIndex === 0) {
939
+ return translate("agentHost.agentGui.shortcutEnter");
940
+ }
941
+ if (optionIndex === 1) {
942
+ return isDarwin ? translate("agentHost.agentGui.shortcutCmdEnter") : translate("agentHost.agentGui.shortcutCtrEnter");
943
+ }
944
+ return null;
945
+ }
946
+ function isDarwinPlatform(platform) {
947
+ if (platform) {
948
+ return platform === "darwin";
949
+ }
950
+ if (typeof navigator === "undefined") {
951
+ return false;
952
+ }
953
+ const userAgentPlatform = "userAgentData" in navigator ? navigator.userAgentData?.platform : void 0;
954
+ const navigatorPlatform = userAgentPlatform ?? navigator.platform ?? "";
955
+ return /mac/i.test(navigatorPlatform);
956
+ }
957
+ function InteractiveOptionSpinner() {
958
+ "use memo";
959
+ return /* @__PURE__ */ jsx(
960
+ Spinner,
961
+ {
962
+ className: AgentGUIConversation_styles_default.interactiveOptionSpinner,
963
+ testId: "agent-interactive-option-spinner"
964
+ }
965
+ );
966
+ }
967
+ function SendFilledIcon() {
968
+ "use memo";
969
+ return /* @__PURE__ */ jsx(
970
+ "svg",
971
+ {
972
+ width: "24",
973
+ height: "24",
974
+ viewBox: "0 0 24 24",
975
+ fill: "none",
976
+ "aria-hidden": "true",
977
+ children: /* @__PURE__ */ jsx(
978
+ "path",
979
+ {
980
+ d: "M2.74311 8.80587C2.84592 8.40096 3.14571 8.08844 3.54551 7.97033L18.5197 3.51569C18.9336 3.39383 19.3809 3.5054 19.6881 3.81262C19.9951 4.11984 20.1076 4.56798 19.9857 4.9817L15.5311 19.9559C15.413 20.3557 15.1005 20.6555 14.6956 20.7583C14.2895 20.8597 13.869 20.7438 13.5721 20.4469L10.455 15.1823C10.8585 14.6483 12.1563 12.9094 14.3475 9.96528C14.6086 9.70419 14.6382 9.31168 14.4138 9.08692C14.1891 8.86221 13.796 8.8913 13.5348 9.15252L8.31088 13.0423L3.05316 9.92799C2.7562 9.63104 2.64049 9.21071 2.74311 8.80587Z",
981
+ fill: "currentColor"
982
+ }
983
+ )
984
+ }
985
+ );
986
+ }
987
+ function interactivePromptClassName(embedded) {
988
+ return embedded ? `${AgentGUIConversation_styles_default.interactivePrompt} agent-gui-conversation__interactive-prompt--embedded` : AgentGUIConversation_styles_default.interactivePrompt;
989
+ }
990
+ function interactivePromptCardClassName(edgeGlow) {
991
+ return edgeGlow ? `${AgentGUIConversation_styles_default.interactivePromptCard} agent-gui-edge-glow` : AgentGUIConversation_styles_default.interactivePromptCard;
992
+ }
993
+ function formatToolDetails(input) {
994
+ return getPromptToolDetails(input).map((detail) => ({
995
+ kind: detail.kind,
996
+ label: promptToolDetailLabel(detail.kind),
997
+ value: detail.value,
998
+ ...detail.meta ? { meta: detail.meta } : {}
999
+ }));
1000
+ }
1001
+ function PromptDetailValue({
1002
+ detail
1003
+ }) {
1004
+ "use memo";
1005
+ if (detail.kind !== "command") {
1006
+ return /* @__PURE__ */ jsx("span", { className: AgentGUIConversation_styles_default.interactiveOptionDescription, children: detail.value });
1007
+ }
1008
+ return /* @__PURE__ */ jsx(
1009
+ CommandTextWithTooltip,
1010
+ {
1011
+ value: detail.value,
1012
+ testId: "agent-interactive-command-detail"
1013
+ }
1014
+ );
1015
+ }
1016
+ function CommandTextWithTooltip({
1017
+ value,
1018
+ testId
1019
+ }) {
1020
+ "use memo";
1021
+ return /* @__PURE__ */ jsx(TooltipProvider, { delayDuration: COMMAND_TOOLTIP_DELAY_MS, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
1022
+ /* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
1023
+ "span",
1024
+ {
1025
+ className: `${AgentGUIConversation_styles_default.interactiveOptionDescription} ${AgentGUIConversation_styles_default.interactiveOptionCommandDescription}`,
1026
+ "data-agent-interactive-command-detail": testId === "agent-interactive-command-detail" ? "true" : void 0,
1027
+ "data-agent-interactive-command-prefix-option": testId === "agent-interactive-command-prefix-option" ? "true" : void 0,
1028
+ children: value
1029
+ }
1030
+ ) }),
1031
+ /* @__PURE__ */ jsx(TooltipContent, { className: AgentGUIConversation_styles_default.interactiveOptionCommandTooltip, children: value })
1032
+ ] }) });
1033
+ }
1034
+ function promptToolDetailLabel(kind) {
1035
+ switch (kind) {
1036
+ case "command":
1037
+ return translate("agentHost.agentTool.details.command");
1038
+ case "mcp":
1039
+ return translate("agentHost.agentTool.details.mcp");
1040
+ case "path":
1041
+ return translate("agentHost.agentTool.details.path");
1042
+ case "query":
1043
+ return translate("agentHost.agentTool.details.query");
1044
+ }
1045
+ }
1046
+ function filterDuplicatePromptTitleDetails(details, title) {
1047
+ const normalizedTitle = normalizePromptDetailText(title);
1048
+ if (!normalizedTitle) {
1049
+ return details;
1050
+ }
1051
+ return details.filter(
1052
+ (detail) => normalizePromptDetailText(detail.value) !== normalizedTitle
1053
+ );
1054
+ }
1055
+ function normalizePromptDetailText(value) {
1056
+ return value?.trim() ?? "";
1057
+ }
1058
+ function isApprovalFeedbackOption(option) {
1059
+ return isDenyApprovalOptionToken(option.id) || isDenyApprovalOptionToken(option.kind);
1060
+ }
1061
+ function approvalFeedbackOptionId(options) {
1062
+ const explicitFeedbackOption = options.find(
1063
+ (option) => isExplicitFeedbackDenyApprovalOption(option)
1064
+ );
1065
+ if (explicitFeedbackOption) {
1066
+ return explicitFeedbackOption.id;
1067
+ }
1068
+ return options.find(isApprovalFeedbackOption)?.id ?? null;
1069
+ }
1070
+ function isExplicitFeedbackDenyApprovalOption(option) {
1071
+ for (const value of [option.id, option.kind]) {
1072
+ switch (normalizeApprovalOptionToken(value ?? "")) {
1073
+ case "abort":
1074
+ case "cancel":
1075
+ case "cancelled":
1076
+ case "canceled":
1077
+ case "denywithfeedback":
1078
+ case "rejectwithfeedback":
1079
+ return true;
1080
+ default:
1081
+ break;
1082
+ }
1083
+ }
1084
+ return false;
1085
+ }
1086
+ function isDenyApprovalOptionToken(value) {
1087
+ switch (normalizeApprovalOptionToken(value ?? "")) {
1088
+ case "abort":
1089
+ case "cancel":
1090
+ case "cancelled":
1091
+ case "canceled":
1092
+ case "deny":
1093
+ case "denied":
1094
+ case "reject":
1095
+ case "rejected":
1096
+ case "rejectonce":
1097
+ case "disallow":
1098
+ case "decline":
1099
+ case "declined":
1100
+ case "no":
1101
+ return true;
1102
+ default:
1103
+ return false;
1104
+ }
1105
+ }
1106
+ function approvalPromptTitle(value, detailCount) {
1107
+ const title = value.trim();
1108
+ return title && detailCount === 0 && !isPromptRequestIdTitle(title) ? title : null;
1109
+ }
1110
+ function stripPromptTitlePunctuation(value) {
1111
+ return value.trim().replace(/[.。]+$/u, "");
1112
+ }
1113
+ function interactiveOptionLabel(label, description) {
1114
+ const trimmedDescription = description?.trim();
1115
+ return trimmedDescription ? `${label} ${trimmedDescription}` : label;
1116
+ }
1117
+
1118
+ export {
1119
+ approvalOptionDisplayLabel,
1120
+ getPromptToolDetails,
1121
+ isPromptRequestIdTitle,
1122
+ AgentInteractivePromptSurface
1123
+ };
1124
+ //# sourceMappingURL=chunk-WME2V26J.js.map