@tutti-os/agent-gui 0.0.44 → 0.0.45

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 (47) hide show
  1. package/dist/agent-conversation/index.js +5 -4
  2. package/dist/agent-conversation/index.js.map +1 -1
  3. package/dist/agent-message-center/index.js +17 -11
  4. package/dist/agent-message-center/index.js.map +1 -1
  5. package/dist/app/renderer/agentactivity.css +99 -54
  6. package/dist/{chunk-GMLK2EFU.js → chunk-62QOR3TC.js} +4 -97
  7. package/dist/chunk-62QOR3TC.js.map +1 -0
  8. package/dist/{chunk-5UD2YEBX.js → chunk-AMNXH4DJ.js} +47 -14
  9. package/dist/{chunk-5UD2YEBX.js.map → chunk-AMNXH4DJ.js.map} +1 -1
  10. package/dist/{chunk-25VZHG6G.js → chunk-CZ7PS3DU.js} +4 -4
  11. package/dist/{chunk-ZORA4UAT.js → chunk-D6IYEVDT.js} +2 -2
  12. package/dist/chunk-EIC7XS3C.js +71 -0
  13. package/dist/chunk-EIC7XS3C.js.map +1 -0
  14. package/dist/chunk-FJG2EH4V.js +317 -0
  15. package/dist/chunk-FJG2EH4V.js.map +1 -0
  16. package/dist/{chunk-J4MU53PH.js → chunk-NZ2BGOJU.js} +2 -2
  17. package/dist/chunk-OL54R6OL.js +99 -0
  18. package/dist/chunk-OL54R6OL.js.map +1 -0
  19. package/dist/{chunk-ZTQKIJ5J.js → chunk-QT45WUPQ.js} +71 -20
  20. package/dist/chunk-QT45WUPQ.js.map +1 -0
  21. package/dist/{chunk-SF2PE7M6.js → chunk-UGV6JTWM.js} +4 -4
  22. package/dist/{chunk-IGXC7NRW.js → chunk-VFQR7AZI.js} +10 -63
  23. package/dist/chunk-VFQR7AZI.js.map +1 -0
  24. package/dist/{chunk-64OSXJRE.js → chunk-ZG3WZSMV.js} +2 -2
  25. package/dist/context-mention-palette/index.js +7 -6
  26. package/dist/i18n/index.d.ts +2 -2
  27. package/dist/i18n/index.js +2 -1
  28. package/dist/index.d.ts +1 -5
  29. package/dist/index.js +157 -232
  30. package/dist/index.js.map +1 -1
  31. package/dist/uiSettings-BQS9r2eo.d.ts +6 -0
  32. package/dist/workbench/contribution.js +1 -1
  33. package/dist/workbench/index.d.ts +3 -0
  34. package/dist/workbench/index.js +13 -2
  35. package/dist/workbench/sessionTitle.d.ts +28 -0
  36. package/dist/workbench/sessionTitle.js +14 -0
  37. package/dist/workbench/sessionTitle.js.map +1 -0
  38. package/dist/workspace-agent-generated-files.js +3 -2
  39. package/package.json +19 -12
  40. package/dist/chunk-GMLK2EFU.js.map +0 -1
  41. package/dist/chunk-IGXC7NRW.js.map +0 -1
  42. package/dist/chunk-ZTQKIJ5J.js.map +0 -1
  43. /package/dist/{chunk-25VZHG6G.js.map → chunk-CZ7PS3DU.js.map} +0 -0
  44. /package/dist/{chunk-ZORA4UAT.js.map → chunk-D6IYEVDT.js.map} +0 -0
  45. /package/dist/{chunk-J4MU53PH.js.map → chunk-NZ2BGOJU.js.map} +0 -0
  46. /package/dist/{chunk-SF2PE7M6.js.map → chunk-UGV6JTWM.js.map} +0 -0
  47. /package/dist/{chunk-64OSXJRE.js.map → chunk-ZG3WZSMV.js.map} +0 -0
@@ -0,0 +1,317 @@
1
+ import {
2
+ normalizeAgentTitleText
3
+ } from "./chunk-GCBDIQDX.js";
4
+ import {
5
+ translateInUiLanguage
6
+ } from "./chunk-VFQR7AZI.js";
7
+
8
+ // shared/utils/agentSessionMentionText.ts
9
+ import {
10
+ isRichTextMentionHref,
11
+ parseRichTextMentionHref
12
+ } from "@tutti-os/ui-rich-text/core";
13
+ var MARKDOWN_LINK_PATTERN = /\[((?:\\.|[^\]\\])*)\]\(([^)\s]+)\)/g;
14
+ var MARKDOWN_LABEL_ESCAPE_PATTERN = /\\([\\[\]()])/g;
15
+ var SESSION_MENTION_DISPLAY_PREFIX_BY_LANGUAGE = {
16
+ "zh-CN": "@\u4F1A\u8BDD \xB7 ",
17
+ en: "@session \xB7 "
18
+ };
19
+ var PLAIN_SESSION_AGENT_LABELS = [
20
+ "Claude Code",
21
+ "Gemini CLI",
22
+ "Hermes Agent",
23
+ "OpenClaw",
24
+ "Nexight",
25
+ "Gemini",
26
+ "Hermes",
27
+ "Codex"
28
+ ];
29
+ function formatAgentSessionMentionText(value, options = {}) {
30
+ const trimmed = value?.trim() ?? "";
31
+ if (!trimmed) {
32
+ return "";
33
+ }
34
+ const sessionMentionDisplayPrefix = sessionMentionDisplayPrefixForLanguage(
35
+ options.language
36
+ );
37
+ const withSessionMentionsNormalized = trimmed.replace(
38
+ MARKDOWN_LINK_PATTERN,
39
+ (fullMatch, rawLabel, href) => {
40
+ const label = unescapeMarkdownLabel(rawLabel);
41
+ const mention = parseRichTextMentionHref(href, label);
42
+ if (!mention) {
43
+ return isRichTextMentionHref(href) ? label : fullMatch;
44
+ }
45
+ const providerId = mention.providerId.trim().toLowerCase();
46
+ const displayLabel = label || mention.label;
47
+ if (providerId === "agent-session") {
48
+ return formatSessionLabel(displayLabel, sessionMentionDisplayPrefix);
49
+ }
50
+ if (providerId === "workspace-issue") {
51
+ return formatIssueLabel(displayLabel);
52
+ }
53
+ return displayLabel;
54
+ }
55
+ );
56
+ const normalized = normalizeAgentTitleText(withSessionMentionsNormalized);
57
+ if (isPlainSessionMentionText(normalized, sessionMentionDisplayPrefix)) {
58
+ return formatSessionLabel(normalized, sessionMentionDisplayPrefix);
59
+ }
60
+ return normalized;
61
+ }
62
+ function isPlainSessionMentionText(value, sessionMentionDisplayPrefix) {
63
+ const trimmed = value.trim();
64
+ if (!trimmed.startsWith("@") || trimmed.startsWith(sessionMentionDisplayPrefix)) {
65
+ return false;
66
+ }
67
+ return PLAIN_SESSION_AGENT_LABELS.some((agentLabel) => {
68
+ const ampersandSeparator = ` & ${agentLabel}`;
69
+ const ampersandIndex = trimmed.indexOf(ampersandSeparator);
70
+ if (ampersandIndex > 1) {
71
+ const trailing = trimmed.slice(
72
+ ampersandIndex + ampersandSeparator.length
73
+ );
74
+ if (trailing === "" || trailing.startsWith(" ")) {
75
+ return true;
76
+ }
77
+ }
78
+ const dottedSeparator = ` \xB7 ${agentLabel} \xB7 `;
79
+ return trimmed.indexOf(dottedSeparator) > 1;
80
+ });
81
+ }
82
+ function sessionMentionDisplayPrefixForLanguage(language) {
83
+ return SESSION_MENTION_DISPLAY_PREFIX_BY_LANGUAGE[language ?? "en"];
84
+ }
85
+ function formatSessionLabel(label, sessionMentionDisplayPrefix) {
86
+ const normalizedLabel = label.trim().replace(/^@+/, "").trim();
87
+ return normalizedLabel ? `${sessionMentionDisplayPrefix}${normalizedLabel}` : label.trim();
88
+ }
89
+ function formatIssueLabel(label) {
90
+ const normalizedLabel = label.trim().replace(/^@+/, "").trim();
91
+ return normalizedLabel ? `@Task \xB7 ${normalizedLabel}` : label.trim();
92
+ }
93
+ function unescapeMarkdownLabel(label) {
94
+ return label.replace(MARKDOWN_LABEL_ESCAPE_PATTERN, "$1");
95
+ }
96
+
97
+ // contexts/settings/domain/agentSettings.providerMeta.ts
98
+ var AGENT_PROVIDER_LABEL = {
99
+ "claude-code": "Claude Code",
100
+ codex: "Codex",
101
+ nexight: "Nexight",
102
+ opencode: "OpenCode",
103
+ gemini: "Gemini CLI",
104
+ openclaw: "OpenClaw",
105
+ hermes: "Hermes Agent"
106
+ };
107
+
108
+ // shared/agentConversationTitleProjection.ts
109
+ function normalizeAgentGUIProviderIdentity(provider) {
110
+ switch (provider?.trim().toLowerCase() ?? "") {
111
+ case "claude-code":
112
+ case "claude":
113
+ case "claude code":
114
+ return "claude-code";
115
+ case "codex":
116
+ return "codex";
117
+ case "nexight":
118
+ case "tutti":
119
+ return "nexight";
120
+ case "gemini":
121
+ return "gemini";
122
+ case "hermes":
123
+ return "hermes";
124
+ case "openclaw":
125
+ return "openclaw";
126
+ default:
127
+ return "unknown";
128
+ }
129
+ }
130
+ function resolveAgentGUIProviderIdentity(input) {
131
+ const candidates = [
132
+ input.sessionProvider,
133
+ input.workspaceSessionProvider,
134
+ input.conversationProvider,
135
+ timelineProviderHint(input.timelineItems ?? [])
136
+ ];
137
+ for (const candidate of candidates) {
138
+ const normalized = normalizeAgentGUIProviderIdentity(candidate);
139
+ if (normalized !== "unknown") {
140
+ return normalized;
141
+ }
142
+ }
143
+ return "unknown";
144
+ }
145
+ function resolveAgentGUIConversationTitle(title, provider) {
146
+ const normalizedTitle = stripAgentGUITitleTrailingPeriod(
147
+ normalizeAgentTitleText(title)
148
+ );
149
+ if (normalizedTitle) {
150
+ return {
151
+ title: normalizedTitle,
152
+ titleFallback: null
153
+ };
154
+ }
155
+ if (provider === "unknown") {
156
+ return {
157
+ title: "",
158
+ titleFallback: "generic-agent"
159
+ };
160
+ }
161
+ return {
162
+ title: AGENT_PROVIDER_LABEL[provider],
163
+ titleFallback: null
164
+ };
165
+ }
166
+ function resolveAgentGUIConversationDisplayTitle(input, fallbackAgentLabel) {
167
+ if (input.title) {
168
+ return stripAgentGUITitleTrailingPeriod(
169
+ normalizeAgentTitleText(input.title)
170
+ );
171
+ }
172
+ if (input.titleFallback === "generic-agent") {
173
+ return stripAgentGUITitleTrailingPeriod(fallbackAgentLabel);
174
+ }
175
+ return "";
176
+ }
177
+ function formatAgentGUIConversationPlainTitle(input, options = {}) {
178
+ return formatAgentSessionMentionText(
179
+ resolveAgentGUIConversationDisplayTitle(
180
+ input,
181
+ options.fallbackAgentLabel ?? "Agent"
182
+ ),
183
+ {
184
+ language: options.language
185
+ }
186
+ );
187
+ }
188
+ function resolveAgentGUIDockConversationTitle(input) {
189
+ return resolveAgentGUIExplicitConversationTitle(input);
190
+ }
191
+ function resolveAgentGUIExplicitConversationTitle(input) {
192
+ if (input.titleFallback) {
193
+ return null;
194
+ }
195
+ const title = stripAgentGUITitleTrailingPeriod(
196
+ normalizeAgentTitleText(input.title)
197
+ );
198
+ if (!title) {
199
+ return null;
200
+ }
201
+ if (isAgentGUIUntitledTaskTitle(title)) {
202
+ return null;
203
+ }
204
+ if (input.provider !== "unknown" && title === AGENT_PROVIDER_LABEL[input.provider]) {
205
+ return null;
206
+ }
207
+ return title;
208
+ }
209
+ function resolveAgentGUIProviderDisplayLabel(provider, fallbackAgentLabel) {
210
+ const resolvedProvider = normalizeAgentGUIProviderIdentity(provider);
211
+ if (resolvedProvider === "unknown") {
212
+ return fallbackAgentLabel;
213
+ }
214
+ return AGENT_PROVIDER_LABEL[resolvedProvider];
215
+ }
216
+ function firstAgentGUIUserMessageTitle(messages) {
217
+ const userMessage = [...messages].filter(
218
+ (message) => messageRole(message) === "user" && messageText(message).length > 0
219
+ ).sort(compareMessagesAscending)[0];
220
+ return userMessage ? messageText(userMessage) : "";
221
+ }
222
+ function messageRole(message) {
223
+ const role = message.role?.trim().toLowerCase();
224
+ if (role === "user") {
225
+ return "user";
226
+ }
227
+ if (role === "assistant" || role === "agent") {
228
+ return "agent";
229
+ }
230
+ const kind = message.kind?.trim().toLowerCase() ?? "";
231
+ if (kind === "message.user") {
232
+ return "user";
233
+ }
234
+ if (kind === "message.assistant" || kind === "message.agent") {
235
+ return "agent";
236
+ }
237
+ return null;
238
+ }
239
+ function messageText(message) {
240
+ const payload = message.payload;
241
+ const displayPrompt = typeof payload?.displayPrompt === "string" ? payload.displayPrompt : "";
242
+ const text = typeof payload?.text === "string" ? payload.text : "";
243
+ const content = typeof payload?.content === "string" ? payload.content : "";
244
+ return normalizeAgentTitleText(displayPrompt || text || content);
245
+ }
246
+ function compareMessagesAscending(left, right) {
247
+ const leftTime = left.occurredAtUnixMs ?? left.completedAtUnixMs ?? left.startedAtUnixMs ?? 0;
248
+ const rightTime = right.occurredAtUnixMs ?? right.completedAtUnixMs ?? right.startedAtUnixMs ?? 0;
249
+ const timeDiff = leftTime - rightTime;
250
+ if (timeDiff !== 0) {
251
+ return timeDiff;
252
+ }
253
+ const sequenceDiff = messageSequence(left) - messageSequence(right) || (left.messageId ?? "").localeCompare(right.messageId ?? "");
254
+ return sequenceDiff;
255
+ }
256
+ function messageSequence(message) {
257
+ const numericId = typeof message.id === "number" && Number.isFinite(message.id) ? message.id : 0;
258
+ return message.version ?? numericId;
259
+ }
260
+ function stripAgentGUITitleTrailingPeriod(title) {
261
+ return title.trimEnd().replace(/[.。]+$/u, "").trimEnd();
262
+ }
263
+ function isAgentGUIUntitledTaskTitle(title) {
264
+ return localizedAgentGUIUntitledTaskLabels().has(compactTitleText(title));
265
+ }
266
+ function localizedAgentGUIUntitledTaskLabels() {
267
+ return new Set(
268
+ ["en", "zh-CN"].map(
269
+ (language) => compactTitleText(
270
+ translateInUiLanguage(
271
+ language,
272
+ "agentHost.workspaceAgentsUntitledTask"
273
+ )
274
+ )
275
+ ).filter(Boolean)
276
+ );
277
+ }
278
+ function timelineProviderHint(timelineItems) {
279
+ for (const item of timelineItems) {
280
+ if (isUserTimelineItem(item)) {
281
+ continue;
282
+ }
283
+ const normalized = normalizeAgentGUIProviderIdentity(item.actorId);
284
+ if (normalized !== "unknown") {
285
+ return normalized;
286
+ }
287
+ }
288
+ return null;
289
+ }
290
+ function isUserTimelineItem(item) {
291
+ const role = item.role?.trim().toLowerCase();
292
+ if (role === "user") {
293
+ return true;
294
+ }
295
+ const actorType = item.actorType.trim().toLowerCase();
296
+ if (actorType === "user") {
297
+ return true;
298
+ }
299
+ return item.itemType.trim().toLowerCase() === "message.user";
300
+ }
301
+ function compactTitleText(value) {
302
+ return value.trim().replace(/\s+/g, " ");
303
+ }
304
+
305
+ export {
306
+ AGENT_PROVIDER_LABEL,
307
+ formatAgentSessionMentionText,
308
+ normalizeAgentGUIProviderIdentity,
309
+ resolveAgentGUIProviderIdentity,
310
+ resolveAgentGUIConversationTitle,
311
+ formatAgentGUIConversationPlainTitle,
312
+ resolveAgentGUIDockConversationTitle,
313
+ resolveAgentGUIExplicitConversationTitle,
314
+ resolveAgentGUIProviderDisplayLabel,
315
+ firstAgentGUIUserMessageTitle
316
+ };
317
+ //# sourceMappingURL=chunk-FJG2EH4V.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../shared/utils/agentSessionMentionText.ts","../contexts/settings/domain/agentSettings.providerMeta.ts","../shared/agentConversationTitleProjection.ts"],"sourcesContent":["import type { UiLanguage } from \"../../contexts/settings/domain/agentSettings\";\nimport { normalizeAgentTitleText } from \"./agentTitleText.ts\";\nimport {\n isRichTextMentionHref,\n parseRichTextMentionHref\n} from \"@tutti-os/ui-rich-text/core\";\n\nconst MARKDOWN_LINK_PATTERN = /\\[((?:\\\\.|[^\\]\\\\])*)\\]\\(([^)\\s]+)\\)/g;\nconst MARKDOWN_LABEL_ESCAPE_PATTERN = /\\\\([\\\\[\\]()])/g;\nconst SESSION_MENTION_DISPLAY_PREFIX_BY_LANGUAGE: Record<UiLanguage, string> = {\n \"zh-CN\": \"@会话 · \",\n en: \"@session · \"\n};\nconst PLAIN_SESSION_AGENT_LABELS = [\n \"Claude Code\",\n \"Gemini CLI\",\n \"Hermes Agent\",\n \"OpenClaw\",\n \"Nexight\",\n \"Gemini\",\n \"Hermes\",\n \"Codex\"\n] as const;\n\nexport interface FormatAgentSessionMentionTextOptions {\n language?: UiLanguage;\n}\n\nexport function formatAgentSessionMentionText(\n value: string | null | undefined,\n options: FormatAgentSessionMentionTextOptions = {}\n): string {\n const trimmed = value?.trim() ?? \"\";\n if (!trimmed) {\n return \"\";\n }\n const sessionMentionDisplayPrefix = sessionMentionDisplayPrefixForLanguage(\n options.language\n );\n\n const withSessionMentionsNormalized = trimmed.replace(\n MARKDOWN_LINK_PATTERN,\n (fullMatch, rawLabel: string, href: string) => {\n const label = unescapeMarkdownLabel(rawLabel);\n const mention = parseRichTextMentionHref(href, label);\n if (!mention) {\n return isRichTextMentionHref(href) ? label : fullMatch;\n }\n const providerId = mention.providerId.trim().toLowerCase();\n const displayLabel = label || mention.label;\n if (providerId === \"agent-session\") {\n return formatSessionLabel(displayLabel, sessionMentionDisplayPrefix);\n }\n if (providerId === \"workspace-issue\") {\n return formatIssueLabel(displayLabel);\n }\n return displayLabel;\n }\n );\n const normalized = normalizeAgentTitleText(withSessionMentionsNormalized);\n if (isPlainSessionMentionText(normalized, sessionMentionDisplayPrefix)) {\n return formatSessionLabel(normalized, sessionMentionDisplayPrefix);\n }\n return normalized;\n}\n\nfunction isPlainSessionMentionText(\n value: string,\n sessionMentionDisplayPrefix: string\n): boolean {\n const trimmed = value.trim();\n if (\n !trimmed.startsWith(\"@\") ||\n trimmed.startsWith(sessionMentionDisplayPrefix)\n ) {\n return false;\n }\n\n return PLAIN_SESSION_AGENT_LABELS.some((agentLabel) => {\n const ampersandSeparator = ` & ${agentLabel}`;\n const ampersandIndex = trimmed.indexOf(ampersandSeparator);\n if (ampersandIndex > 1) {\n const trailing = trimmed.slice(\n ampersandIndex + ampersandSeparator.length\n );\n if (trailing === \"\" || trailing.startsWith(\" \")) {\n return true;\n }\n }\n\n const dottedSeparator = ` · ${agentLabel} · `;\n return trimmed.indexOf(dottedSeparator) > 1;\n });\n}\n\nfunction sessionMentionDisplayPrefixForLanguage(\n language: UiLanguage | undefined\n): string {\n return SESSION_MENTION_DISPLAY_PREFIX_BY_LANGUAGE[language ?? \"en\"];\n}\n\nfunction formatSessionLabel(\n label: string,\n sessionMentionDisplayPrefix: string\n): string {\n const normalizedLabel = label.trim().replace(/^@+/, \"\").trim();\n return normalizedLabel\n ? `${sessionMentionDisplayPrefix}${normalizedLabel}`\n : label.trim();\n}\n\nfunction formatIssueLabel(label: string): string {\n const normalizedLabel = label.trim().replace(/^@+/, \"\").trim();\n return normalizedLabel ? `@Task · ${normalizedLabel}` : label.trim();\n}\n\nfunction unescapeMarkdownLabel(label: string): string {\n return label.replace(MARKDOWN_LABEL_ESCAPE_PATTERN, \"$1\");\n}\n","import type { AgentProvider } from \"./agentSettings\";\n\nexport const AGENT_PROVIDER_LABEL: Record<AgentProvider, string> = {\n \"claude-code\": \"Claude Code\",\n codex: \"Codex\",\n nexight: \"Nexight\",\n opencode: \"OpenCode\",\n gemini: \"Gemini CLI\",\n openclaw: \"OpenClaw\",\n hermes: \"Hermes Agent\"\n};\n\nexport interface AgentProviderCapabilities {\n runtimeObservation: \"jsonl\" | \"provider-api\" | \"none\";\n experimental: boolean;\n}\n\nexport const AGENT_PROVIDER_CAPABILITIES: Record<\n AgentProvider,\n AgentProviderCapabilities\n> = {\n \"claude-code\": {\n runtimeObservation: \"jsonl\",\n experimental: false\n },\n codex: {\n runtimeObservation: \"jsonl\",\n experimental: false\n },\n nexight: {\n runtimeObservation: \"jsonl\",\n experimental: false\n },\n opencode: {\n runtimeObservation: \"provider-api\",\n experimental: false\n },\n gemini: {\n runtimeObservation: \"none\",\n experimental: false\n },\n openclaw: {\n runtimeObservation: \"jsonl\",\n experimental: false\n },\n hermes: {\n runtimeObservation: \"jsonl\",\n experimental: false\n }\n};\n","import { AGENT_PROVIDER_LABEL } from \"../contexts/settings/domain/agentSettings.providerMeta.ts\";\nimport type { UiLanguage } from \"../contexts/settings/domain/agentSettings.ts\";\nimport { translateInUiLanguage } from \"../i18n/runtime.ts\";\nimport type { AgentGUIProvider } from \"../types.ts\";\nimport type { WorkspaceAgentActivityTimelineItem } from \"./workspaceAgentActivityTypes.ts\";\nimport { formatAgentSessionMentionText } from \"./utils/agentSessionMentionText.ts\";\nimport { normalizeAgentTitleText } from \"./utils/agentTitleText.ts\";\n\nexport type AgentGUIResolvedProvider = AgentGUIProvider | \"unknown\";\nexport type AgentGUIConversationTitleFallback = \"generic-agent\" | null;\n\nexport interface AgentGUIConversationPlainTitleOptions {\n fallbackAgentLabel?: string;\n language?: UiLanguage;\n}\n\nexport interface AgentGUIConversationTitleMessage {\n id?: number | string | null;\n messageId?: string | null;\n version?: number | null;\n role?: string | null;\n kind?: string | null;\n payload?: {\n content?: unknown;\n displayPrompt?: unknown;\n text?: unknown;\n } | null;\n occurredAtUnixMs?: number | null;\n completedAtUnixMs?: number | null;\n startedAtUnixMs?: number | null;\n}\n\nexport function normalizeAgentGUIProviderIdentity(\n provider: string | null | undefined\n): AgentGUIResolvedProvider {\n switch (provider?.trim().toLowerCase() ?? \"\") {\n case \"claude-code\":\n case \"claude\":\n case \"claude code\":\n return \"claude-code\";\n case \"codex\":\n return \"codex\";\n case \"nexight\":\n case \"tutti\":\n return \"nexight\";\n case \"gemini\":\n return \"gemini\";\n case \"hermes\":\n return \"hermes\";\n case \"openclaw\":\n return \"openclaw\";\n default:\n return \"unknown\";\n }\n}\n\nexport function resolveAgentGUIProviderIdentity(input: {\n sessionProvider?: string | null;\n workspaceSessionProvider?: string | null;\n conversationProvider?: string | null;\n timelineItems?: readonly WorkspaceAgentActivityTimelineItem[];\n}): AgentGUIResolvedProvider {\n const candidates = [\n input.sessionProvider,\n input.workspaceSessionProvider,\n input.conversationProvider,\n timelineProviderHint(input.timelineItems ?? [])\n ];\n for (const candidate of candidates) {\n const normalized = normalizeAgentGUIProviderIdentity(candidate);\n if (normalized !== \"unknown\") {\n return normalized;\n }\n }\n return \"unknown\";\n}\n\nexport function resolveAgentGUIConversationTitle(\n title: string | null | undefined,\n provider: AgentGUIResolvedProvider\n): {\n title: string;\n titleFallback: AgentGUIConversationTitleFallback;\n} {\n const normalizedTitle = stripAgentGUITitleTrailingPeriod(\n normalizeAgentTitleText(title)\n );\n if (normalizedTitle) {\n return {\n title: normalizedTitle,\n titleFallback: null\n };\n }\n if (provider === \"unknown\") {\n return {\n title: \"\",\n titleFallback: \"generic-agent\"\n };\n }\n return {\n title: AGENT_PROVIDER_LABEL[provider],\n titleFallback: null\n };\n}\n\nexport function resolveAgentGUIConversationDisplayTitle(\n input: {\n title: string;\n titleFallback?: AgentGUIConversationTitleFallback;\n },\n fallbackAgentLabel: string\n): string {\n if (input.title) {\n return stripAgentGUITitleTrailingPeriod(\n normalizeAgentTitleText(input.title)\n );\n }\n if (input.titleFallback === \"generic-agent\") {\n return stripAgentGUITitleTrailingPeriod(fallbackAgentLabel);\n }\n return \"\";\n}\n\nexport function formatAgentGUIConversationPlainTitle(\n input: {\n title: string;\n titleFallback?: AgentGUIConversationTitleFallback;\n },\n options: AgentGUIConversationPlainTitleOptions = {}\n): string {\n return formatAgentSessionMentionText(\n resolveAgentGUIConversationDisplayTitle(\n input,\n options.fallbackAgentLabel ?? \"Agent\"\n ),\n {\n language: options.language\n }\n );\n}\n\nexport function resolveAgentGUIDockConversationTitle(input: {\n provider: AgentGUIResolvedProvider;\n title: string;\n titleFallback?: AgentGUIConversationTitleFallback;\n}): string | null {\n return resolveAgentGUIExplicitConversationTitle(input);\n}\n\nexport function resolveAgentGUIExplicitConversationTitle(input: {\n provider: AgentGUIResolvedProvider;\n title: string;\n titleFallback?: AgentGUIConversationTitleFallback;\n}): string | null {\n if (input.titleFallback) {\n return null;\n }\n\n const title = stripAgentGUITitleTrailingPeriod(\n normalizeAgentTitleText(input.title)\n );\n if (!title) {\n return null;\n }\n if (isAgentGUIUntitledTaskTitle(title)) {\n return null;\n }\n\n if (\n input.provider !== \"unknown\" &&\n title === AGENT_PROVIDER_LABEL[input.provider]\n ) {\n return null;\n }\n\n return title;\n}\n\nexport function resolveAgentGUIProviderDisplayLabel(\n provider: string | null | undefined,\n fallbackAgentLabel: string\n): string {\n const resolvedProvider = normalizeAgentGUIProviderIdentity(provider);\n if (resolvedProvider === \"unknown\") {\n return fallbackAgentLabel;\n }\n return AGENT_PROVIDER_LABEL[resolvedProvider];\n}\n\nexport function firstAgentGUIUserMessageTitle(\n messages: readonly AgentGUIConversationTitleMessage[]\n): string {\n const userMessage = [...messages]\n .filter(\n (message) =>\n messageRole(message) === \"user\" && messageText(message).length > 0\n )\n .sort(compareMessagesAscending)[0];\n return userMessage ? messageText(userMessage) : \"\";\n}\n\nfunction messageRole(\n message: AgentGUIConversationTitleMessage\n): \"user\" | \"agent\" | null {\n const role = message.role?.trim().toLowerCase();\n if (role === \"user\") {\n return \"user\";\n }\n if (role === \"assistant\" || role === \"agent\") {\n return \"agent\";\n }\n const kind = message.kind?.trim().toLowerCase() ?? \"\";\n if (kind === \"message.user\") {\n return \"user\";\n }\n if (kind === \"message.assistant\" || kind === \"message.agent\") {\n return \"agent\";\n }\n return null;\n}\n\nfunction messageText(message: AgentGUIConversationTitleMessage): string {\n const payload = message.payload;\n const displayPrompt =\n typeof payload?.displayPrompt === \"string\" ? payload.displayPrompt : \"\";\n const text = typeof payload?.text === \"string\" ? payload.text : \"\";\n const content = typeof payload?.content === \"string\" ? payload.content : \"\";\n return normalizeAgentTitleText(displayPrompt || text || content);\n}\n\nfunction compareMessagesAscending(\n left: AgentGUIConversationTitleMessage,\n right: AgentGUIConversationTitleMessage\n): number {\n const leftTime =\n left.occurredAtUnixMs ??\n left.completedAtUnixMs ??\n left.startedAtUnixMs ??\n 0;\n const rightTime =\n right.occurredAtUnixMs ??\n right.completedAtUnixMs ??\n right.startedAtUnixMs ??\n 0;\n const timeDiff = leftTime - rightTime;\n if (timeDiff !== 0) {\n return timeDiff;\n }\n const sequenceDiff =\n messageSequence(left) - messageSequence(right) ||\n (left.messageId ?? \"\").localeCompare(right.messageId ?? \"\");\n return sequenceDiff;\n}\n\nfunction messageSequence(message: AgentGUIConversationTitleMessage): number {\n const numericId =\n typeof message.id === \"number\" && Number.isFinite(message.id)\n ? message.id\n : 0;\n return message.version ?? numericId;\n}\n\nfunction stripAgentGUITitleTrailingPeriod(title: string): string {\n return title\n .trimEnd()\n .replace(/[.。]+$/u, \"\")\n .trimEnd();\n}\n\nfunction isAgentGUIUntitledTaskTitle(title: string): boolean {\n return localizedAgentGUIUntitledTaskLabels().has(compactTitleText(title));\n}\n\nfunction localizedAgentGUIUntitledTaskLabels(): Set<string> {\n return new Set(\n ([\"en\", \"zh-CN\"] as const)\n .map((language) =>\n compactTitleText(\n translateInUiLanguage(\n language,\n \"agentHost.workspaceAgentsUntitledTask\"\n )\n )\n )\n .filter(Boolean)\n );\n}\n\nfunction timelineProviderHint(\n timelineItems: readonly WorkspaceAgentActivityTimelineItem[]\n): string | null {\n for (const item of timelineItems) {\n if (isUserTimelineItem(item)) {\n continue;\n }\n const normalized = normalizeAgentGUIProviderIdentity(item.actorId);\n if (normalized !== \"unknown\") {\n return normalized;\n }\n }\n return null;\n}\n\nfunction isUserTimelineItem(item: WorkspaceAgentActivityTimelineItem): boolean {\n const role = item.role?.trim().toLowerCase();\n if (role === \"user\") {\n return true;\n }\n const actorType = item.actorType.trim().toLowerCase();\n if (actorType === \"user\") {\n return true;\n }\n return item.itemType.trim().toLowerCase() === \"message.user\";\n}\n\nfunction compactTitleText(value: string): string {\n return value.trim().replace(/\\s+/g, \" \");\n}\n"],"mappings":"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","names":[]}
@@ -14,7 +14,7 @@ import {
14
14
  } from "./chunk-MTFSQWZ6.js";
15
15
  import {
16
16
  translate
17
- } from "./chunk-IGXC7NRW.js";
17
+ } from "./chunk-EIC7XS3C.js";
18
18
 
19
19
  // shared/managedAgentProviders.ts
20
20
  function normalizeManagedAgentProvider(provider) {
@@ -113,4 +113,4 @@ export {
113
113
  userAvatarPlaceholderUrl,
114
114
  workspaceAgentActivityStatusLabel
115
115
  };
116
- //# sourceMappingURL=chunk-J4MU53PH.js.map
116
+ //# sourceMappingURL=chunk-NZ2BGOJU.js.map
@@ -0,0 +1,99 @@
1
+ import {
2
+ firstAgentGUIUserMessageTitle,
3
+ formatAgentGUIConversationPlainTitle,
4
+ formatAgentSessionMentionText,
5
+ normalizeAgentGUIProviderIdentity,
6
+ resolveAgentGUIExplicitConversationTitle
7
+ } from "./chunk-FJG2EH4V.js";
8
+
9
+ // workbench/sessionTitle.ts
10
+ function formatAgentGuiSessionPlainTitle(title, options = {}) {
11
+ return formatAgentSessionMentionText(title, { language: options.language });
12
+ }
13
+ function formatAgentGuiConversationPlainTitle(conversation, options = {}) {
14
+ return formatAgentGUIConversationPlainTitle(conversation, options);
15
+ }
16
+ function resolveAgentGuiWorkbenchSessionTitle({
17
+ agentSessionId,
18
+ fallbackTitle,
19
+ language,
20
+ provider,
21
+ snapshot
22
+ }) {
23
+ const normalizedAgentSessionId = agentSessionId?.trim() ?? "";
24
+ if (!normalizedAgentSessionId) {
25
+ return { agentSessionId: null, source: "none", title: null };
26
+ }
27
+ const session = snapshot.sessions.find(
28
+ (item) => item.agentSessionId === normalizedAgentSessionId
29
+ );
30
+ const sessionMessages = snapshot.sessionMessagesById[normalizedAgentSessionId] ?? [];
31
+ const normalizedProvider = normalizeAgentGUIProviderIdentity(
32
+ session?.provider ?? provider
33
+ );
34
+ const snapshotTitle = resolveDisplayableSnapshotSessionTitle({
35
+ messages: sessionMessages,
36
+ provider: normalizedProvider,
37
+ sessionTitle: session?.title ?? "",
38
+ language
39
+ });
40
+ if (snapshotTitle) {
41
+ return {
42
+ agentSessionId: normalizedAgentSessionId,
43
+ source: "snapshot",
44
+ title: snapshotTitle
45
+ };
46
+ }
47
+ if (session || sessionMessages.length > 0) {
48
+ return {
49
+ agentSessionId: normalizedAgentSessionId,
50
+ source: "none",
51
+ title: null
52
+ };
53
+ }
54
+ const fallbackDisplayTitle = formatAgentGuiConversationPlainTitle(
55
+ { title: fallbackTitle ?? "", titleFallback: null },
56
+ { language }
57
+ );
58
+ return fallbackDisplayTitle ? {
59
+ agentSessionId: normalizedAgentSessionId,
60
+ source: "fallback",
61
+ title: fallbackDisplayTitle
62
+ } : {
63
+ agentSessionId: normalizedAgentSessionId,
64
+ source: "none",
65
+ title: null
66
+ };
67
+ }
68
+ function resolveDisplayableSnapshotSessionTitle(input) {
69
+ const explicitSessionTitle = explicitConversationTitle({
70
+ language: input.language,
71
+ provider: input.provider,
72
+ title: input.sessionTitle
73
+ });
74
+ if (explicitSessionTitle) {
75
+ return explicitSessionTitle;
76
+ }
77
+ return explicitConversationTitle({
78
+ language: input.language,
79
+ provider: input.provider,
80
+ title: firstAgentGUIUserMessageTitle(input.messages)
81
+ });
82
+ }
83
+ function explicitConversationTitle(input) {
84
+ return resolveAgentGUIExplicitConversationTitle({
85
+ provider: input.provider,
86
+ title: formatAgentGuiConversationPlainTitle(
87
+ { title: input.title ?? "", titleFallback: null },
88
+ { language: input.language }
89
+ ),
90
+ titleFallback: null
91
+ }) ?? "";
92
+ }
93
+
94
+ export {
95
+ formatAgentGuiSessionPlainTitle,
96
+ formatAgentGuiConversationPlainTitle,
97
+ resolveAgentGuiWorkbenchSessionTitle
98
+ };
99
+ //# sourceMappingURL=chunk-OL54R6OL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../workbench/sessionTitle.ts"],"sourcesContent":["import type {\n AgentActivityMessage,\n AgentActivitySnapshot\n} from \"@tutti-os/agent-activity-core\";\nimport type { UiLanguage } from \"../contexts/settings/domain/agentSettings\";\nimport {\n firstAgentGUIUserMessageTitle,\n formatAgentGUIConversationPlainTitle,\n normalizeAgentGUIProviderIdentity,\n resolveAgentGUIExplicitConversationTitle,\n type AgentGUIResolvedProvider\n} from \"../shared/agentConversationTitleProjection.ts\";\nimport { formatAgentSessionMentionText } from \"../shared/utils/agentSessionMentionText.ts\";\nimport type { AgentGuiWorkbenchProvider } from \"./types.ts\";\n\nexport interface AgentGuiSessionTitleFormatOptions {\n fallbackAgentLabel?: string;\n language?: UiLanguage;\n}\n\nexport interface ResolveAgentGuiWorkbenchSessionTitleInput extends AgentGuiSessionTitleFormatOptions {\n agentSessionId?: string | null;\n fallbackTitle?: string | null;\n provider: AgentGuiWorkbenchProvider | string;\n snapshot: AgentActivitySnapshot;\n}\n\nexport interface AgentGuiWorkbenchSessionTitleResult {\n agentSessionId: string | null;\n source: \"snapshot\" | \"fallback\" | \"none\";\n title: string | null;\n}\n\nexport function formatAgentGuiSessionPlainTitle(\n title: string | null | undefined,\n options: AgentGuiSessionTitleFormatOptions = {}\n): string {\n return formatAgentSessionMentionText(title, { language: options.language });\n}\n\nexport function formatAgentGuiConversationPlainTitle(\n conversation: {\n title: string;\n titleFallback?: \"generic-agent\" | null;\n },\n options: AgentGuiSessionTitleFormatOptions = {}\n): string {\n return formatAgentGUIConversationPlainTitle(conversation, options);\n}\n\nexport function resolveAgentGuiWorkbenchSessionTitle({\n agentSessionId,\n fallbackTitle,\n language,\n provider,\n snapshot\n}: ResolveAgentGuiWorkbenchSessionTitleInput): AgentGuiWorkbenchSessionTitleResult {\n const normalizedAgentSessionId = agentSessionId?.trim() ?? \"\";\n if (!normalizedAgentSessionId) {\n return { agentSessionId: null, source: \"none\", title: null };\n }\n\n const session = snapshot.sessions.find(\n (item) => item.agentSessionId === normalizedAgentSessionId\n );\n const sessionMessages =\n snapshot.sessionMessagesById[normalizedAgentSessionId] ?? [];\n const normalizedProvider = normalizeAgentGUIProviderIdentity(\n session?.provider ?? provider\n );\n const snapshotTitle = resolveDisplayableSnapshotSessionTitle({\n messages: sessionMessages,\n provider: normalizedProvider,\n sessionTitle: session?.title ?? \"\",\n language\n });\n if (snapshotTitle) {\n return {\n agentSessionId: normalizedAgentSessionId,\n source: \"snapshot\",\n title: snapshotTitle\n };\n }\n\n if (session || sessionMessages.length > 0) {\n return {\n agentSessionId: normalizedAgentSessionId,\n source: \"none\",\n title: null\n };\n }\n\n const fallbackDisplayTitle = formatAgentGuiConversationPlainTitle(\n { title: fallbackTitle ?? \"\", titleFallback: null },\n { language }\n );\n return fallbackDisplayTitle\n ? {\n agentSessionId: normalizedAgentSessionId,\n source: \"fallback\",\n title: fallbackDisplayTitle\n }\n : {\n agentSessionId: normalizedAgentSessionId,\n source: \"none\",\n title: null\n };\n}\n\nfunction resolveDisplayableSnapshotSessionTitle(input: {\n messages: readonly AgentActivityMessage[];\n provider: AgentGUIResolvedProvider;\n sessionTitle: string;\n language?: UiLanguage;\n}): string {\n const explicitSessionTitle = explicitConversationTitle({\n language: input.language,\n provider: input.provider,\n title: input.sessionTitle\n });\n if (explicitSessionTitle) {\n return explicitSessionTitle;\n }\n return explicitConversationTitle({\n language: input.language,\n provider: input.provider,\n title: firstAgentGUIUserMessageTitle(input.messages)\n });\n}\n\nfunction explicitConversationTitle(input: {\n language?: UiLanguage;\n provider: AgentGUIResolvedProvider;\n title: string | null | undefined;\n}): string {\n return (\n resolveAgentGUIExplicitConversationTitle({\n provider: input.provider,\n title: formatAgentGuiConversationPlainTitle(\n { title: input.title ?? \"\", titleFallback: null },\n { language: input.language }\n ),\n titleFallback: null\n }) ?? \"\"\n );\n}\n"],"mappings":";;;;;;;;;AAiCO,SAAS,gCACd,OACA,UAA6C,CAAC,GACtC;AACR,SAAO,8BAA8B,OAAO,EAAE,UAAU,QAAQ,SAAS,CAAC;AAC5E;AAEO,SAAS,qCACd,cAIA,UAA6C,CAAC,GACtC;AACR,SAAO,qCAAqC,cAAc,OAAO;AACnE;AAEO,SAAS,qCAAqC;AAAA,EACnD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmF;AACjF,QAAM,2BAA2B,gBAAgB,KAAK,KAAK;AAC3D,MAAI,CAAC,0BAA0B;AAC7B,WAAO,EAAE,gBAAgB,MAAM,QAAQ,QAAQ,OAAO,KAAK;AAAA,EAC7D;AAEA,QAAM,UAAU,SAAS,SAAS;AAAA,IAChC,CAAC,SAAS,KAAK,mBAAmB;AAAA,EACpC;AACA,QAAM,kBACJ,SAAS,oBAAoB,wBAAwB,KAAK,CAAC;AAC7D,QAAM,qBAAqB;AAAA,IACzB,SAAS,YAAY;AAAA,EACvB;AACA,QAAM,gBAAgB,uCAAuC;AAAA,IAC3D,UAAU;AAAA,IACV,UAAU;AAAA,IACV,cAAc,SAAS,SAAS;AAAA,IAChC;AAAA,EACF,CAAC;AACD,MAAI,eAAe;AACjB,WAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,WAAW,gBAAgB,SAAS,GAAG;AACzC,WAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,QAAQ;AAAA,MACR,OAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,uBAAuB;AAAA,IAC3B,EAAE,OAAO,iBAAiB,IAAI,eAAe,KAAK;AAAA,IAClD,EAAE,SAAS;AAAA,EACb;AACA,SAAO,uBACH;AAAA,IACE,gBAAgB;AAAA,IAChB,QAAQ;AAAA,IACR,OAAO;AAAA,EACT,IACA;AAAA,IACE,gBAAgB;AAAA,IAChB,QAAQ;AAAA,IACR,OAAO;AAAA,EACT;AACN;AAEA,SAAS,uCAAuC,OAKrC;AACT,QAAM,uBAAuB,0BAA0B;AAAA,IACrD,UAAU,MAAM;AAAA,IAChB,UAAU,MAAM;AAAA,IAChB,OAAO,MAAM;AAAA,EACf,CAAC;AACD,MAAI,sBAAsB;AACxB,WAAO;AAAA,EACT;AACA,SAAO,0BAA0B;AAAA,IAC/B,UAAU,MAAM;AAAA,IAChB,UAAU,MAAM;AAAA,IAChB,OAAO,8BAA8B,MAAM,QAAQ;AAAA,EACrD,CAAC;AACH;AAEA,SAAS,0BAA0B,OAIxB;AACT,SACE,yCAAyC;AAAA,IACvC,UAAU,MAAM;AAAA,IAChB,OAAO;AAAA,MACL,EAAE,OAAO,MAAM,SAAS,IAAI,eAAe,KAAK;AAAA,MAChD,EAAE,UAAU,MAAM,SAAS;AAAA,IAC7B;AAAA,IACA,eAAe;AAAA,EACjB,CAAC,KAAK;AAEV;","names":[]}
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  translate,
7
7
  useTranslation
8
- } from "./chunk-IGXC7NRW.js";
8
+ } from "./chunk-EIC7XS3C.js";
9
9
  import {
10
10
  resolveAgentWorkspaceFileVisualKind
11
11
  } from "./chunk-PJP5BUU6.js";
@@ -204,13 +204,17 @@ import {
204
204
  useEffect,
205
205
  useState as useState2
206
206
  } from "react";
207
+ import { createPortal } from "react-dom";
207
208
  import {
209
+ Button,
208
210
  ToastProvider,
209
211
  ToastRoot,
210
212
  ToastTitle,
211
- ToastViewport
213
+ ToastViewport,
214
+ CopyIcon,
215
+ DownloadIcon,
216
+ RestoreIcon
212
217
  } from "@tutti-os/ui-system";
213
- import { CopyIcon, DownloadIcon } from "lucide-react";
214
218
  import Zoom from "react-medium-image-zoom";
215
219
 
216
220
  // app/renderer/lib/utils.ts
@@ -498,12 +502,20 @@ function ZoomableImage({
498
502
  )
499
503
  }
500
504
  ) : null,
501
- cloneElement(buttonUnzoom, {
502
- className: cn(
503
- buttonUnzoom.props.className,
504
- "nodrag tsh-desktop-no-drag"
505
- )
506
- })
505
+ /* @__PURE__ */ jsx2(
506
+ Button,
507
+ {
508
+ asChild: true,
509
+ className: "tsh-zoom-dialog__icon-button nodrag tsh-desktop-no-drag",
510
+ size: "icon",
511
+ variant: "chrome",
512
+ children: cloneElement(
513
+ buttonUnzoom,
514
+ void 0,
515
+ /* @__PURE__ */ jsx2(RestoreIcon, { "aria-hidden": "true", className: "size-4" })
516
+ )
517
+ }
518
+ )
507
519
  ] });
508
520
  };
509
521
  return /* @__PURE__ */ jsxs2(Fragment, { children: [
@@ -550,18 +562,21 @@ function ZoomableImage({
550
562
  )
551
563
  }
552
564
  ) : null,
553
- copyStatus ? /* @__PURE__ */ jsx2(
554
- ImageCopyStatusToast,
555
- {
556
- busy: copyStatus.busy,
557
- message: copyStatus.message,
558
- variant: copyStatus.variant,
559
- onOpenChange: (open) => {
560
- if (!open) {
561
- setCopyStatus(null);
565
+ copyStatus ? createPortal(
566
+ /* @__PURE__ */ jsx2(
567
+ ImageCopyStatusToast,
568
+ {
569
+ busy: copyStatus.busy,
570
+ message: copyStatus.message,
571
+ variant: copyStatus.variant,
572
+ onOpenChange: (open) => {
573
+ if (!open) {
574
+ setCopyStatus(null);
575
+ }
562
576
  }
563
577
  }
564
- }
578
+ ),
579
+ document.body
565
580
  ) : null
566
581
  ] });
567
582
  }
@@ -602,6 +617,42 @@ function ImageActionButtons({
602
617
  onCopy,
603
618
  onDownload
604
619
  }) {
620
+ if (!itemRole) {
621
+ return /* @__PURE__ */ jsxs2(Fragment, { children: [
622
+ /* @__PURE__ */ jsx2(
623
+ Button,
624
+ {
625
+ "aria-label": copyLabel,
626
+ className: "tsh-zoom-dialog__icon-button",
627
+ size: "icon",
628
+ title: copyLabel,
629
+ variant: "chrome",
630
+ onClick: (event) => {
631
+ event.preventDefault();
632
+ event.stopPropagation();
633
+ onCopy();
634
+ },
635
+ children: /* @__PURE__ */ jsx2(CopyIcon, { "aria-hidden": "true", className: "size-4" })
636
+ }
637
+ ),
638
+ /* @__PURE__ */ jsx2(
639
+ Button,
640
+ {
641
+ "aria-label": downloadLabel,
642
+ className: "tsh-zoom-dialog__icon-button",
643
+ size: "icon",
644
+ title: downloadLabel,
645
+ variant: "chrome",
646
+ onClick: (event) => {
647
+ event.preventDefault();
648
+ event.stopPropagation();
649
+ onDownload();
650
+ },
651
+ children: /* @__PURE__ */ jsx2(DownloadIcon, { "aria-hidden": "true", className: "size-4" })
652
+ }
653
+ )
654
+ ] });
655
+ }
605
656
  return /* @__PURE__ */ jsxs2(Fragment, { children: [
606
657
  /* @__PURE__ */ jsxs2(
607
658
  "button",
@@ -3210,4 +3261,4 @@ export {
3210
3261
  CustomScrollArea,
3211
3262
  MessageSquareMoreIcon
3212
3263
  };
3213
- //# sourceMappingURL=chunk-ZTQKIJ5J.js.map
3264
+ //# sourceMappingURL=chunk-QT45WUPQ.js.map