@tutti-os/agent-gui 0.0.99 → 0.0.101

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 (95) hide show
  1. package/dist/{AgentGUI-Bkk2TRS0.d.ts → AgentGUI-FECh2x1p.d.ts} +19 -37
  2. package/dist/agent-conversation/index.d.ts +4 -4
  3. package/dist/agent-conversation/index.js +8 -9
  4. package/dist/agent-conversation/index.js.map +1 -1
  5. package/dist/agent-gui.d.ts +5 -4
  6. package/dist/agent-gui.js +19 -19
  7. package/dist/agent-message-center/index.d.ts +4 -6
  8. package/dist/agent-message-center/index.js +13 -52
  9. package/dist/agent-message-center/index.js.map +1 -1
  10. package/dist/agent-title-text.js +1 -1
  11. package/dist/{agentConversationVM-C335TR6S.d.ts → agentConversationVM-BzHZhwFP.d.ts} +1 -1
  12. package/dist/{agentGuiNodeTypes-DAsluxjv.d.ts → agentGuiNodeTypes-BH3lz6gn.d.ts} +21 -5
  13. package/dist/app/renderer/agentactivity.css +142 -72
  14. package/dist/chunk-2RQM7PJN.js +16 -0
  15. package/dist/chunk-2RQM7PJN.js.map +1 -0
  16. package/dist/{chunk-FSKGEGGX.js → chunk-4E3QCW6L.js} +17 -3
  17. package/dist/chunk-4E3QCW6L.js.map +1 -0
  18. package/dist/{chunk-63BE6RGM.js → chunk-4YCCATI4.js} +14 -374
  19. package/dist/chunk-4YCCATI4.js.map +1 -0
  20. package/dist/{chunk-IYEXLOUE.js → chunk-4YVKAPKW.js} +5 -8
  21. package/dist/chunk-4YVKAPKW.js.map +1 -0
  22. package/dist/{chunk-MRRICFWA.js → chunk-D7HMQLBO.js} +159 -55
  23. package/dist/chunk-D7HMQLBO.js.map +1 -0
  24. package/dist/{chunk-OTRZBTFQ.js → chunk-DWUVRWXD.js} +2 -2
  25. package/dist/{chunk-RHTZAODZ.js → chunk-E5AD46HP.js} +2 -2
  26. package/dist/{chunk-3NOJFKDV.js → chunk-EUW6VPIK.js} +414 -49
  27. package/dist/chunk-EUW6VPIK.js.map +1 -0
  28. package/dist/{chunk-Y35GDLP2.js → chunk-F5UR6EJG.js} +2 -17
  29. package/dist/chunk-F5UR6EJG.js.map +1 -0
  30. package/dist/{chunk-J7ZYAUPC.js → chunk-FAE7CXZO.js} +8 -6
  31. package/dist/chunk-FAE7CXZO.js.map +1 -0
  32. package/dist/{chunk-CPUEPDF7.js → chunk-GCW57WYQ.js} +646 -595
  33. package/dist/chunk-GCW57WYQ.js.map +1 -0
  34. package/dist/{chunk-4ROALW3K.js → chunk-KAV2WHTG.js} +82 -61
  35. package/dist/chunk-KAV2WHTG.js.map +1 -0
  36. package/dist/chunk-MIJXEELH.js +96 -0
  37. package/dist/chunk-MIJXEELH.js.map +1 -0
  38. package/dist/{chunk-T6PEJFRP.js → chunk-MJOQP2ED.js} +392 -452
  39. package/dist/chunk-MJOQP2ED.js.map +1 -0
  40. package/dist/{chunk-QWGJ5TEG.js → chunk-QY22OBJS.js} +28 -30
  41. package/dist/chunk-QY22OBJS.js.map +1 -0
  42. package/dist/{chunk-SPZJCTBV.js → chunk-TDVYZEUI.js} +348 -322
  43. package/dist/chunk-TDVYZEUI.js.map +1 -0
  44. package/dist/{chunk-MASXZENX.js → chunk-UESYITH6.js} +21 -2
  45. package/dist/chunk-UESYITH6.js.map +1 -0
  46. package/dist/{chunk-PLCHNOXL.js → chunk-VQOPBBBI.js} +1288 -1141
  47. package/dist/chunk-VQOPBBBI.js.map +1 -0
  48. package/dist/{chunk-7M77BK6K.js → chunk-ZPKPIHMZ.js} +196 -156
  49. package/dist/chunk-ZPKPIHMZ.js.map +1 -0
  50. package/dist/context-mention-palette/index.d.ts +5 -1
  51. package/dist/context-mention-palette/index.js +10 -11
  52. package/dist/contribution-CTVBPN0R.d.ts +119 -0
  53. package/dist/i18n/index.d.ts +16 -2
  54. package/dist/i18n/index.js +2 -2
  55. package/dist/index.d.ts +8 -7
  56. package/dist/index.js +21 -20
  57. package/dist/index.js.map +1 -1
  58. package/dist/mention-search.d.ts +18 -6
  59. package/dist/mention-search.js +8 -9
  60. package/dist/workbench/contribution.d.ts +6 -107
  61. package/dist/workbench/contribution.js +7 -3
  62. package/dist/workbench/index.d.ts +6 -4
  63. package/dist/workbench/index.js +27 -21
  64. package/dist/workbench/launch.d.ts +13 -5
  65. package/dist/workbench/launch.js +1 -1
  66. package/dist/workbench/sessionTitle.d.ts +5 -7
  67. package/dist/workbench/sessionTitle.js +3 -4
  68. package/dist/workbench/state.js +3 -1
  69. package/dist/workspace-agent-generated-files.d.ts +8 -13
  70. package/dist/workspace-agent-generated-files.js +6 -21
  71. package/dist/{workspaceAgentActivityListTypes-C7gPWYiA.d.ts → workspaceAgentActivityListTypes-DZfS_HgG.d.ts} +3 -26
  72. package/package.json +14 -14
  73. package/dist/chunk-3NOJFKDV.js.map +0 -1
  74. package/dist/chunk-4ROALW3K.js.map +0 -1
  75. package/dist/chunk-63BE6RGM.js.map +0 -1
  76. package/dist/chunk-7M77BK6K.js.map +0 -1
  77. package/dist/chunk-CPUEPDF7.js.map +0 -1
  78. package/dist/chunk-FSKGEGGX.js.map +0 -1
  79. package/dist/chunk-GAD6Y3BF.js +0 -88
  80. package/dist/chunk-GAD6Y3BF.js.map +0 -1
  81. package/dist/chunk-GCBDIQDX.js +0 -22
  82. package/dist/chunk-GCBDIQDX.js.map +0 -1
  83. package/dist/chunk-IYEXLOUE.js.map +0 -1
  84. package/dist/chunk-J7ZYAUPC.js.map +0 -1
  85. package/dist/chunk-MASXZENX.js.map +0 -1
  86. package/dist/chunk-MRRICFWA.js.map +0 -1
  87. package/dist/chunk-PLCHNOXL.js.map +0 -1
  88. package/dist/chunk-QWGJ5TEG.js.map +0 -1
  89. package/dist/chunk-SPZJCTBV.js.map +0 -1
  90. package/dist/chunk-T6PEJFRP.js.map +0 -1
  91. package/dist/chunk-Y35GDLP2.js.map +0 -1
  92. package/dist/chunk-Y5M6Q6WX.js +0 -25
  93. package/dist/chunk-Y5M6Q6WX.js.map +0 -1
  94. /package/dist/{chunk-OTRZBTFQ.js.map → chunk-DWUVRWXD.js.map} +0 -0
  95. /package/dist/{chunk-RHTZAODZ.js.map → chunk-E5AD46HP.js.map} +0 -0
@@ -4,11 +4,11 @@ import {
4
4
  } from "./chunk-LUGELG5V.js";
5
5
  import {
6
6
  managedAgentRoundedIconUrl
7
- } from "./chunk-MASXZENX.js";
7
+ } from "./chunk-UESYITH6.js";
8
8
  import {
9
9
  translate,
10
10
  useTranslation
11
- } from "./chunk-RHTZAODZ.js";
11
+ } from "./chunk-E5AD46HP.js";
12
12
  import {
13
13
  getAgentCustomMentionKind
14
14
  } from "./chunk-5X7YDOC6.js";
@@ -37,85 +37,453 @@ import { CloseIcon } from "@tutti-os/ui-system/icons";
37
37
  // agent-gui/agentGuiNode/agentRichText/agentRichTextCaretAnchor.ts
38
38
  var AGENT_RICH_TEXT_CARET_ANCHOR = "\u200B";
39
39
 
40
- // agent-gui/agentGuiNode/agentRichText/AgentMentionNodeView.tsx
41
- import { jsx, jsxs } from "react/jsx-runtime";
42
- function parseFileCountAttr(value) {
43
- const parsed = typeof value === "string" ? Number.parseInt(value.trim(), 10) : Number.NaN;
44
- return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
40
+ // agent-gui/agentGuiNode/agentRichText/agentMentionMarkdown.ts
41
+ import {
42
+ createRichTextLinkMarkdown,
43
+ createRichTextMarkdownLink,
44
+ createRichTextMentionHref,
45
+ createRichTextMentionMarkdown,
46
+ isRichTextMentionHref,
47
+ parseRichTextMentionHref
48
+ } from "@tutti-os/ui-rich-text/core";
49
+ function dirnameFromPath(path) {
50
+ const parts = path.split("/").filter(Boolean);
51
+ if (parts.length <= 1) {
52
+ return path.startsWith("/") ? "/" : "";
53
+ }
54
+ return `/${parts.slice(0, -1).join("/")}`;
45
55
  }
46
- var AgentMentionTooltipProviderContext = createContext(true);
47
- function attrString(attrs, key) {
48
- const value = attrs[key];
49
- return typeof value === "string" ? value : "";
56
+ function normalizeAgentSessionMentionTitle(value) {
57
+ const trimmed = value.trim();
58
+ const withoutMentionPrefix = trimmed.replace(/^@+/, "").trim();
59
+ return withoutMentionPrefix || trimmed;
50
60
  }
51
- function normalizeKind(value) {
52
- if (value === "session" || value === "agent-session") {
53
- return "session";
61
+ function createAgentSessionMentionHref(input) {
62
+ const label = normalizeAgentSessionMarkdownLabel(input.label);
63
+ const agentTargetId = input.agentTargetId?.trim() ?? "";
64
+ return createRichTextMentionHref({
65
+ providerId: "agent-session",
66
+ entityId: input.agentSessionId,
67
+ label,
68
+ scope: {
69
+ ...agentTargetId ? { agentTargetId } : {},
70
+ workspaceId: input.workspaceId
71
+ }
72
+ });
73
+ }
74
+ function createAgentSessionMarkdownLink(input) {
75
+ const label = normalizeAgentSessionMarkdownLabel(input.label);
76
+ const href = createAgentSessionMentionHref({
77
+ agentSessionId: input.agentSessionId,
78
+ agentTargetId: input.agentTargetId,
79
+ label,
80
+ workspaceId: input.workspaceId
81
+ });
82
+ return createRichTextMarkdownLink({
83
+ href,
84
+ label: input.withAtPrefix ? `@${label}` : label
85
+ });
86
+ }
87
+ function formatAgentMentionMarkdown(item) {
88
+ if (item.kind === "file") {
89
+ const label = item.name.trim().startsWith("@") ? item.name : `@${item.name}`;
90
+ return createRichTextLinkMarkdown({
91
+ kind: "file",
92
+ name: label,
93
+ path: item.href
94
+ });
54
95
  }
55
- if (value === "workspace-issue") {
56
- return "workspace-issue";
96
+ if (item.kind === "workspace-reference") {
97
+ return createRichTextMentionMarkdown({
98
+ providerId: "workspace-reference",
99
+ entityId: item.targetId,
100
+ label: item.name,
101
+ scope: {
102
+ workspaceId: item.workspaceId,
103
+ source: item.source,
104
+ ...item.groupId?.trim() ? { groupId: item.groupId.trim() } : {},
105
+ ...item.fileCount > 0 ? { count: String(item.fileCount) } : {}
106
+ }
107
+ });
57
108
  }
58
- if (value === "workspace-app") {
59
- return "workspace-app";
109
+ if (item.kind === "session") {
110
+ return createAgentSessionMarkdownLink({
111
+ agentSessionId: item.targetId,
112
+ agentTargetId: item.agentTargetId ?? agentSessionTargetIdFromHref(item.href),
113
+ label: item.title.trim() || item.name,
114
+ workspaceId: item.workspaceId,
115
+ withAtPrefix: true
116
+ });
60
117
  }
61
- if (value === "workspace-reference") {
62
- return "workspace-reference";
118
+ if (item.kind === "agent-target") {
119
+ return createRichTextMentionMarkdown({
120
+ providerId: "agent-target",
121
+ entityId: item.targetId,
122
+ label: item.name,
123
+ scope: { workspaceId: item.workspaceId }
124
+ });
63
125
  }
64
- if (value === "workspace-app-factory") {
65
- return "workspace-app-factory";
126
+ const identity = parseRichTextMentionHref(item.href, item.name);
127
+ return identity ? createRichTextMentionMarkdown(identity) : "";
128
+ }
129
+ function normalizeAgentSessionMarkdownLabel(value) {
130
+ return value.trim().replace(/^@+/, "").trim();
131
+ }
132
+ function agentSessionTargetIdFromHref(href) {
133
+ const mention = parseRichTextMentionHref(href, "");
134
+ const agentTargetId = mention?.scope?.agentTargetId?.trim() ?? "";
135
+ return agentTargetId || void 0;
136
+ }
137
+ function parseMentionFileCount(value) {
138
+ const parsed = typeof value === "number" ? value : typeof value === "string" ? Number.parseInt(value.trim(), 10) : Number.NaN;
139
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
140
+ }
141
+ function parseAgentMentionMarkdown(value, start = 0) {
142
+ if (!value.startsWith("[", start)) {
143
+ return null;
66
144
  }
67
- if (value === "agent-target") {
68
- return "agent-target";
145
+ let index = start + 1;
146
+ const prefixedMention = value[index] === "@";
147
+ if (prefixedMention) {
148
+ index += 1;
69
149
  }
70
- if (value === "custom") {
71
- return "custom";
150
+ let name = "";
151
+ while (index < value.length) {
152
+ const current = value[index];
153
+ if (current === "\\") {
154
+ const escaped = value[index + 1];
155
+ if (escaped === "\\" || escaped === "[" || escaped === "]") {
156
+ name += escaped;
157
+ index += 2;
158
+ continue;
159
+ }
160
+ name += current;
161
+ index += 1;
162
+ continue;
163
+ }
164
+ if (current === "]") {
165
+ break;
166
+ }
167
+ name += current;
168
+ index += 1;
72
169
  }
73
- return "file";
74
- }
75
- function dirnameFromPath(path) {
76
- const parts = path.split("/").filter(Boolean);
77
- if (parts.length <= 1) {
78
- return path.startsWith("/") ? "/" : "";
170
+ if (value[index] !== "]" || value[index + 1] !== "(") {
171
+ return null;
79
172
  }
80
- return `/${parts.slice(0, -1).join("/")}`;
173
+ index += 2;
174
+ let href = "";
175
+ while (index < value.length) {
176
+ const current = value[index];
177
+ if (current === "\\") {
178
+ const escaped = value[index + 1];
179
+ if (escaped === "\\" || escaped === ")") {
180
+ href += escaped;
181
+ index += 2;
182
+ continue;
183
+ }
184
+ href += current;
185
+ index += 1;
186
+ continue;
187
+ }
188
+ if (current === ")") {
189
+ const item = parseMentionItemFromHref({ name, href });
190
+ if (!item) {
191
+ return null;
192
+ }
193
+ if (item.kind !== "file" && !prefixedMention && !isRichTextMentionHref(href)) {
194
+ return null;
195
+ }
196
+ return {
197
+ item,
198
+ end: index + 1
199
+ };
200
+ }
201
+ href += current;
202
+ index += 1;
203
+ }
204
+ return null;
81
205
  }
82
- function mentionViewModel(attrs, t) {
83
- const kind = normalizeKind(attrString(attrs, "kind"));
84
- const name = attrString(attrs, "name");
85
- const href = attrString(attrs, "href");
86
- if (kind === "session") {
87
- const label = attrString(attrs, "title").trim() || name.trim();
206
+ function parseMentionItemFromHref(input) {
207
+ const href = input.href.trim();
208
+ if (!href) {
209
+ return null;
210
+ }
211
+ const mention = parseRichTextMentionHref(href, input.name);
212
+ if (!mention && !isRichTextMentionHref(href)) {
88
213
  return {
89
- ariaLabel: `${t("agentHost.agentGui.mentionKindSession")} ${label}`.trim(),
90
- directoryPath: "",
91
- entryKind: "",
214
+ kind: "file",
92
215
  href,
93
- kind,
94
- label
216
+ path: href,
217
+ name: input.name,
218
+ entryKind: isLocalDirectoryMentionHref(href) ? "directory" : "unknown",
219
+ directoryPath: dirnameFromPath(href)
95
220
  };
96
221
  }
97
- if (kind === "workspace-issue") {
222
+ if (!mention) {
223
+ return null;
224
+ }
225
+ const resource = mention.providerId.trim().toLowerCase();
226
+ const targetId = mention.entityId.trim();
227
+ const workspaceId = mention.scope?.workspaceId?.trim() ?? "";
228
+ const name = mention.label;
229
+ if (resource === "agent-session") {
230
+ if (!workspaceId) {
231
+ return null;
232
+ }
98
233
  return {
99
- ariaLabel: `${t("agentHost.agentGui.mentionKindIssue")} ${name}`.trim(),
100
- directoryPath: "",
101
- entryKind: "",
234
+ kind: "session",
102
235
  href,
103
- kind,
104
- label: name
236
+ workspaceId,
237
+ targetId,
238
+ agentTargetId: mention.scope?.agentTargetId?.trim() || void 0,
239
+ name,
240
+ title: name,
241
+ scope: "collab_sessions",
242
+ initiatorName: "",
243
+ agentName: ""
105
244
  };
106
245
  }
107
- if (kind === "workspace-app") {
246
+ if (resource === "workspace-issue") {
247
+ if (!workspaceId) {
248
+ return null;
249
+ }
108
250
  return {
109
- ariaLabel: `${t("agentHost.agentGui.mentionKindApp")} ${name}`.trim(),
110
- directoryPath: "",
111
- entryKind: "",
251
+ kind: "workspace-issue",
112
252
  href,
113
- iconUrl: attrString(attrs, "iconUrl").trim() || void 0,
114
- kind,
115
- label: name
253
+ workspaceId,
254
+ targetId,
255
+ topicId: mention.scope?.topicId?.trim() || void 0,
256
+ name,
257
+ title: name
116
258
  };
117
259
  }
118
- if (kind === "workspace-reference") {
260
+ if (resource === "workspace-app") {
261
+ if (!workspaceId) {
262
+ return null;
263
+ }
264
+ return {
265
+ kind: "workspace-app",
266
+ href,
267
+ workspaceId,
268
+ targetId,
269
+ appId: targetId,
270
+ name,
271
+ iconUrl: mention.scope?.icon?.trim() || void 0
272
+ };
273
+ }
274
+ if (resource === "agent-target") {
275
+ if (!workspaceId) {
276
+ return null;
277
+ }
278
+ return {
279
+ kind: "agent-target",
280
+ href,
281
+ workspaceId,
282
+ targetId,
283
+ name
284
+ };
285
+ }
286
+ if (resource === "workspace-reference") {
287
+ if (!workspaceId) {
288
+ return null;
289
+ }
290
+ const source = mention.scope?.source?.trim();
291
+ if (source !== "app" && source !== "task") {
292
+ return null;
293
+ }
294
+ return {
295
+ kind: "workspace-reference",
296
+ href,
297
+ workspaceId,
298
+ targetId,
299
+ source,
300
+ groupId: mention.scope?.groupId?.trim() || void 0,
301
+ name,
302
+ iconUrl: mention.scope?.icon?.trim() || void 0,
303
+ fileCount: parseMentionFileCount(mention.scope?.count)
304
+ };
305
+ }
306
+ if (resource === "workspace-app-factory") {
307
+ return {
308
+ kind: "workspace-app-factory",
309
+ href,
310
+ workspaceId,
311
+ targetId,
312
+ jobId: targetId === "create" ? "" : targetId,
313
+ name: name || translate("agentHost.agentGui.workspaceAppFactoryMentionFallback"),
314
+ action: mention.scope?.action?.trim() || void 0,
315
+ contextPath: mention.scope?.contextPath?.trim() || void 0
316
+ };
317
+ }
318
+ const customDefinition = getAgentCustomMentionKind(resource);
319
+ if (customDefinition) {
320
+ const presentation = customDefinition.present(mention, href);
321
+ if (!presentation) {
322
+ return null;
323
+ }
324
+ return {
325
+ kind: "custom",
326
+ customKind: resource,
327
+ href,
328
+ workspaceId: presentation.workspaceId?.trim() || workspaceId,
329
+ targetId,
330
+ name: presentation.name.trim() || name,
331
+ summary: presentation.summary?.trim() || void 0
332
+ };
333
+ }
334
+ return null;
335
+ }
336
+ function isLocalDirectoryMentionHref(href) {
337
+ return href.endsWith("/") && !/^[a-zA-Z][a-zA-Z\d+.-]*:/.test(href);
338
+ }
339
+
340
+ // agent-gui/agentGuiNode/agentRichText/agentMentionPresentation.ts
341
+ function resolveAgentSessionMentionIconUrl(input) {
342
+ const explicitIconUrl = input.agentIconUrl?.trim() ?? "";
343
+ if (explicitIconUrl) {
344
+ return explicitIconUrl;
345
+ }
346
+ const agentTargetId = input.agentTargetId?.trim() || agentSessionTargetIdFromHref(input.href?.trim() ?? "") || "";
347
+ if (!agentTargetId.startsWith("local:")) {
348
+ return void 0;
349
+ }
350
+ const provider = agentTargetId.slice("local:".length).trim();
351
+ return provider ? managedAgentRoundedIconUrl(provider) : void 0;
352
+ }
353
+ function mentionVisual(item) {
354
+ if (item.kind === "file") {
355
+ return {
356
+ kindLabel: "File",
357
+ primary: item.name
358
+ };
359
+ }
360
+ if (item.kind === "session") {
361
+ return {
362
+ kindLabel: "Session",
363
+ primary: item.title.trim() || item.name.trim()
364
+ };
365
+ }
366
+ if (item.kind === "workspace-app") {
367
+ return {
368
+ kindLabel: "App",
369
+ primary: item.name
370
+ };
371
+ }
372
+ if (item.kind === "agent-target") {
373
+ return {
374
+ kindLabel: "Agent",
375
+ primary: item.name
376
+ };
377
+ }
378
+ if (item.kind === "workspace-app-factory") {
379
+ return {
380
+ kindLabel: "App Factory",
381
+ primary: item.name
382
+ };
383
+ }
384
+ if (item.kind === "workspace-reference") {
385
+ return {
386
+ kindLabel: "Reference",
387
+ primary: item.name
388
+ };
389
+ }
390
+ if (item.kind === "custom") {
391
+ return {
392
+ kindLabel: "Reference",
393
+ primary: item.name
394
+ };
395
+ }
396
+ return {
397
+ kindLabel: "Task",
398
+ primary: item.name
399
+ };
400
+ }
401
+
402
+ // agent-gui/agentGuiNode/agentRichText/AgentMentionNodeView.tsx
403
+ import { jsx, jsxs } from "react/jsx-runtime";
404
+ function parseFileCountAttr(value) {
405
+ const parsed = typeof value === "string" ? Number.parseInt(value.trim(), 10) : Number.NaN;
406
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
407
+ }
408
+ var AgentMentionTooltipProviderContext = createContext(true);
409
+ function attrString(attrs, key) {
410
+ const value = attrs[key];
411
+ return typeof value === "string" ? value : "";
412
+ }
413
+ function normalizeKind(value) {
414
+ if (value === "session" || value === "agent-session") {
415
+ return "session";
416
+ }
417
+ if (value === "workspace-issue") {
418
+ return "workspace-issue";
419
+ }
420
+ if (value === "workspace-app") {
421
+ return "workspace-app";
422
+ }
423
+ if (value === "workspace-reference") {
424
+ return "workspace-reference";
425
+ }
426
+ if (value === "workspace-app-factory") {
427
+ return "workspace-app-factory";
428
+ }
429
+ if (value === "agent-target") {
430
+ return "agent-target";
431
+ }
432
+ if (value === "custom") {
433
+ return "custom";
434
+ }
435
+ return "file";
436
+ }
437
+ function dirnameFromPath2(path) {
438
+ const parts = path.split("/").filter(Boolean);
439
+ if (parts.length <= 1) {
440
+ return path.startsWith("/") ? "/" : "";
441
+ }
442
+ return `/${parts.slice(0, -1).join("/")}`;
443
+ }
444
+ function mentionViewModel(attrs, t) {
445
+ const kind = normalizeKind(attrString(attrs, "kind"));
446
+ const name = attrString(attrs, "name");
447
+ const href = attrString(attrs, "href");
448
+ if (kind === "session") {
449
+ const label = attrString(attrs, "title").trim() || name.trim();
450
+ const agentTargetId = attrString(attrs, "agentTargetId").trim();
451
+ return {
452
+ ariaLabel: `${t("agentHost.agentGui.mentionKindSession")} ${label}`.trim(),
453
+ directoryPath: "",
454
+ entryKind: "",
455
+ href,
456
+ iconUrl: resolveAgentSessionMentionIconUrl({
457
+ agentIconUrl: attrString(attrs, "iconUrl"),
458
+ agentTargetId,
459
+ href
460
+ }),
461
+ kind,
462
+ label
463
+ };
464
+ }
465
+ if (kind === "workspace-issue") {
466
+ return {
467
+ ariaLabel: `${t("agentHost.agentGui.mentionKindIssue")} ${name}`.trim(),
468
+ directoryPath: "",
469
+ entryKind: "",
470
+ href,
471
+ kind,
472
+ label: name
473
+ };
474
+ }
475
+ if (kind === "workspace-app") {
476
+ return {
477
+ ariaLabel: `${t("agentHost.agentGui.mentionKindApp")} ${name}`.trim(),
478
+ directoryPath: "",
479
+ entryKind: "",
480
+ href,
481
+ iconUrl: attrString(attrs, "iconUrl").trim() || void 0,
482
+ kind,
483
+ label: name
484
+ };
485
+ }
486
+ if (kind === "workspace-reference") {
119
487
  return {
120
488
  ariaLabel: `${t("agentHost.agentGui.mentionKindApp")} ${name}`.trim(),
121
489
  directoryPath: "",
@@ -165,7 +533,7 @@ function mentionViewModel(attrs, t) {
165
533
  const entryKind = attrString(attrs, "entryKind") || "unknown";
166
534
  return {
167
535
  ariaLabel: name,
168
- directoryPath: attrString(attrs, "directoryPath") || dirnameFromPath(path),
536
+ directoryPath: attrString(attrs, "directoryPath") || dirnameFromPath2(path),
169
537
  entryKind,
170
538
  href: href || path,
171
539
  kind,
@@ -276,7 +644,7 @@ function AgentMentionLegacyFileNodeView({
276
644
  "button",
277
645
  {
278
646
  "aria-label": removeActionAriaLabel,
279
- className: "absolute left-1/2 top-1/2 inline-flex size-5 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-sm text-[var(--text-secondary)] opacity-0 transition-opacity hover:bg-transparency-block hover:text-[var(--text-primary)] focus-visible:opacity-100 group-hover:opacity-100",
647
+ className: "absolute left-1/2 top-1/2 inline-flex size-5 -translate-x-1/2 -translate-y-1/2 items-center justify-center text-[var(--text-secondary)] opacity-0 transition-opacity hover:text-[var(--text-primary)] focus-visible:opacity-100 group-hover:opacity-100",
280
648
  type: "button",
281
649
  onMouseDown: handleRemove,
282
650
  children: /* @__PURE__ */ jsx(CloseIcon, { className: "size-3.5" })
@@ -301,7 +669,7 @@ function AgentMentionLegacyFileNodeView({
301
669
  "button",
302
670
  {
303
671
  "aria-label": removeActionAriaLabel,
304
- className: "absolute left-1/2 top-1/2 inline-flex size-5 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-sm text-[var(--text-secondary)] opacity-0 transition-opacity hover:bg-transparency-block hover:text-[var(--text-primary)] focus-visible:opacity-100 group-hover:opacity-100",
672
+ className: "absolute left-1/2 top-1/2 inline-flex size-5 -translate-x-1/2 -translate-y-1/2 items-center justify-center text-[var(--text-secondary)] opacity-0 transition-opacity hover:text-[var(--text-primary)] focus-visible:opacity-100 group-hover:opacity-100",
305
673
  type: "button",
306
674
  onMouseDown: handleRemove,
307
675
  children: /* @__PURE__ */ jsx(CloseIcon, { className: "size-3.5" })
@@ -327,491 +695,192 @@ function AgentMentionNodeView(props) {
327
695
  const syncEditable = () => {
328
696
  setIsEditable(editor.isEditable);
329
697
  };
330
- syncEditable();
331
- editor.on("transaction", syncEditable);
332
- editor.on("update", syncEditable);
333
- return () => {
334
- editor.off("transaction", syncEditable);
335
- editor.off("update", syncEditable);
336
- };
337
- }, [editor]);
338
- const handleRemove = (event) => {
339
- event.preventDefault();
340
- event.stopPropagation();
341
- if (!editor.isEditable) {
342
- return;
343
- }
344
- deleteNode();
345
- if (!hasPromptContentAfterMentionRemoval(editor.state.doc)) {
346
- editor.commands.clearContent();
347
- }
348
- };
349
- if (mention.kind === "file") {
350
- return /* @__PURE__ */ jsx(AgentMentionLegacyFileNodeView, { ...props });
351
- }
352
- if (mention.kind === "workspace-app" || mention.kind === "workspace-reference" || mention.kind === "agent-target") {
353
- return /* @__PURE__ */ jsx(
354
- NodeViewWrapper,
355
- {
356
- as: "span",
357
- "aria-label": mention.ariaLabel,
358
- className: `agent-rich-text-mention-node inline-flex max-w-[min(100%,var(--agent-mention-max-width,16rem))] align-middle ${selected ? "is-selected" : ""}`,
359
- contentEditable: false,
360
- "data-agent-file-mention": "true",
361
- "data-agent-mention-href": mention.href,
362
- "data-agent-mention-icon-url": mention.iconUrl,
363
- "data-agent-mention-kind": mention.kind,
364
- children: /* @__PURE__ */ jsxs(
365
- "span",
366
- {
367
- className: "group relative top-0 inline-flex max-w-[min(100%,var(--agent-mention-max-width,16rem))] cursor-pointer items-center gap-1 overflow-hidden rounded-[4px] border border-transparent bg-transparent px-1 py-0 align-middle text-[13px] font-medium leading-6 text-[var(--agent-gui-mention-app-color,var(--tutti-purple))] no-underline transition-colors hover:border-transparent hover:bg-[color-mix(in_srgb,currentColor_12%,transparent)]",
368
- "data-agent-mention-kind": mention.kind,
369
- "data-slot": "mention-pill",
370
- children: [
371
- /* @__PURE__ */ jsxs(
372
- "span",
373
- {
374
- "aria-hidden": isEditable ? void 0 : true,
375
- className: "relative grid size-4 shrink-0 place-items-center overflow-hidden rounded-[4px] bg-block",
376
- "data-agent-mention-app-icon": "true",
377
- "data-workspace-app-icon": "true",
378
- children: [
379
- mention.iconUrl ? /* @__PURE__ */ jsx(
380
- "img",
381
- {
382
- src: mention.iconUrl,
383
- alt: "",
384
- className: `size-full object-cover transition-opacity ${isEditable ? "group-hover:opacity-0 group-focus-within:opacity-0" : ""}`,
385
- decoding: "async",
386
- loading: "lazy",
387
- draggable: false
388
- }
389
- ) : /* @__PURE__ */ jsx(
390
- "span",
391
- {
392
- className: `tsh-agent-object-token__kind-icon size-4 transition-opacity ${isEditable ? "group-hover:opacity-0 group-focus-within:opacity-0" : ""}`
393
- }
394
- ),
395
- isEditable ? /* @__PURE__ */ jsx(
396
- "button",
397
- {
398
- "aria-label": removeActionAriaLabel,
399
- className: "absolute left-1/2 top-1/2 inline-flex size-5 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-sm text-[var(--text-secondary)] opacity-0 transition-opacity hover:bg-transparency-block hover:text-[var(--text-primary)] focus-visible:opacity-100 group-hover:opacity-100",
400
- type: "button",
401
- onMouseDown: handleRemove,
402
- children: /* @__PURE__ */ jsx(CloseIcon, { className: "size-3.5" })
403
- }
404
- ) : null
405
- ]
406
- }
407
- ),
408
- /* @__PURE__ */ jsx(
409
- TruncatingPillLabel,
410
- {
411
- tooltip: mention.label,
412
- withTooltipProvider,
413
- children: mention.label
414
- }
415
- )
416
- ]
417
- }
418
- )
419
- }
420
- );
421
- }
422
- if (mention.kind === "custom") {
423
- const definition = getAgentCustomMentionKind(mention.customKind ?? "");
424
- const removeAction = isEditable ? /* @__PURE__ */ jsx(
425
- "button",
426
- {
427
- "aria-label": removeActionAriaLabel,
428
- className: "inline-flex size-4 shrink-0 items-center justify-center rounded-sm text-[var(--text-secondary)] opacity-0 transition-opacity hover:bg-transparency-block hover:text-[var(--text-primary)] focus-visible:opacity-100 group-hover:opacity-100",
429
- type: "button",
430
- onMouseDown: handleRemove,
431
- children: /* @__PURE__ */ jsx(CloseIcon, { className: "size-3.5" })
432
- }
433
- ) : null;
434
- if (definition?.renderChip) {
435
- return /* @__PURE__ */ jsx(
436
- NodeViewWrapper,
437
- {
438
- as: "span",
439
- "aria-label": mention.ariaLabel,
440
- className: `agent-rich-text-mention-node inline-grid max-w-[min(100%,var(--agent-mention-max-width,20rem))] align-middle ${selected ? "is-selected" : ""}`,
441
- contentEditable: false,
442
- "data-agent-file-mention": "true",
443
- "data-agent-mention-href": mention.href,
444
- "data-agent-mention-kind": mention.customKind || mention.kind,
445
- children: definition.renderChip({
446
- href: mention.href,
447
- name: mention.label,
448
- summary: mention.summary,
449
- isEditable,
450
- removeAction
451
- })
452
- }
453
- );
454
- }
455
- return /* @__PURE__ */ jsx(
456
- NodeViewWrapper,
457
- {
458
- as: "span",
459
- "aria-label": mention.ariaLabel,
460
- className: `agent-rich-text-mention-node inline-grid max-w-[min(100%,var(--agent-mention-max-width,20rem))] align-middle ${selected ? "is-selected" : ""}`,
461
- contentEditable: false,
462
- "data-agent-file-mention": "true",
463
- "data-agent-mention-href": mention.href,
464
- "data-agent-mention-kind": mention.customKind || mention.kind,
465
- children: /* @__PURE__ */ jsxs(
466
- "span",
467
- {
468
- className: "group relative grid max-w-full cursor-pointer gap-0.5 overflow-hidden rounded-[8px] border border-[var(--border-primary,rgba(0,0,0,0.08))] bg-block px-2.5 py-1.5 text-left align-middle",
469
- "data-slot": "mention-card",
470
- children: [
471
- /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-1", children: [
472
- /* @__PURE__ */ jsx(
473
- "span",
474
- {
475
- "aria-hidden": "true",
476
- className: "tsh-agent-object-token__kind-icon size-3.5 shrink-0"
477
- }
478
- ),
479
- /* @__PURE__ */ jsx("span", { className: "truncate text-[13px] font-medium leading-[130%]", children: mention.label }),
480
- removeAction
481
- ] }),
482
- mention.summary ? /* @__PURE__ */ jsx("span", { className: "truncate text-[12px] font-normal leading-[130%] text-[var(--text-tertiary)]", children: mention.summary }) : null
483
- ]
484
- }
485
- )
486
- }
487
- );
488
- }
489
- return /* @__PURE__ */ jsx(
490
- NodeViewWrapper,
491
- {
492
- as: "span",
493
- className: `agent-rich-text-mention-node inline-flex max-w-[min(100%,var(--agent-mention-max-width,16rem))] align-middle ${selected ? "is-selected" : ""}`,
494
- contentEditable: false,
495
- children: /* @__PURE__ */ jsx(
496
- MentionPill,
497
- {
498
- "aria-label": mention.ariaLabel,
499
- className: "top-0 h-6 py-0 align-middle leading-6",
500
- "data-agent-mention-href": mention.href,
501
- "data-agent-mention-kind": mention.kind,
502
- kind: mention.kind === "session" ? "session" : "issue",
503
- label: mention.label,
504
- removable: isEditable,
505
- removeButtonProps: isEditable ? {
506
- "aria-label": removeActionAriaLabel,
507
- onMouseDown: handleRemove
508
- } : void 0,
509
- summary: mention.summary,
510
- withTooltipProvider
511
- }
512
- )
513
- }
514
- );
515
- }
516
-
517
- // agent-gui/agentGuiNode/agentRichText/agentMentionMarkdown.ts
518
- import {
519
- createRichTextLinkMarkdown,
520
- createRichTextMarkdownLink,
521
- createRichTextMentionHref,
522
- createRichTextMentionMarkdown,
523
- isRichTextMentionHref,
524
- parseRichTextMentionHref
525
- } from "@tutti-os/ui-rich-text/core";
526
- function dirnameFromPath2(path) {
527
- const parts = path.split("/").filter(Boolean);
528
- if (parts.length <= 1) {
529
- return path.startsWith("/") ? "/" : "";
530
- }
531
- return `/${parts.slice(0, -1).join("/")}`;
532
- }
533
- function normalizeAgentSessionMentionTitle(value) {
534
- const trimmed = value.trim();
535
- const withoutMentionPrefix = trimmed.replace(/^@+/, "").trim();
536
- return withoutMentionPrefix || trimmed;
537
- }
538
- function createAgentSessionMentionHref(input) {
539
- const label = normalizeAgentSessionMarkdownLabel(input.label);
540
- const agentTargetId = input.agentTargetId?.trim() ?? "";
541
- return createRichTextMentionHref({
542
- providerId: "agent-session",
543
- entityId: input.agentSessionId,
544
- label,
545
- scope: {
546
- ...agentTargetId ? { agentTargetId } : {},
547
- workspaceId: input.workspaceId
548
- }
549
- });
550
- }
551
- function createAgentSessionMarkdownLink(input) {
552
- const label = normalizeAgentSessionMarkdownLabel(input.label);
553
- const href = createAgentSessionMentionHref({
554
- agentSessionId: input.agentSessionId,
555
- agentTargetId: input.agentTargetId,
556
- label,
557
- workspaceId: input.workspaceId
558
- });
559
- return createRichTextMarkdownLink({
560
- href,
561
- label: input.withAtPrefix ? `@${label}` : label
562
- });
563
- }
564
- function formatAgentMentionMarkdown(item) {
565
- if (item.kind === "file") {
566
- const label = item.name.trim().startsWith("@") ? item.name : `@${item.name}`;
567
- return createRichTextLinkMarkdown({
568
- kind: "file",
569
- name: label,
570
- path: item.href
571
- });
572
- }
573
- if (item.kind === "workspace-reference") {
574
- return createRichTextMentionMarkdown({
575
- providerId: "workspace-reference",
576
- entityId: item.targetId,
577
- label: item.name,
578
- scope: {
579
- workspaceId: item.workspaceId,
580
- source: item.source,
581
- ...item.groupId?.trim() ? { groupId: item.groupId.trim() } : {},
582
- ...item.fileCount > 0 ? { count: String(item.fileCount) } : {}
583
- }
584
- });
585
- }
586
- if (item.kind === "session") {
587
- return createAgentSessionMarkdownLink({
588
- agentSessionId: item.targetId,
589
- agentTargetId: item.agentTargetId ?? agentSessionTargetIdFromHref(item.href),
590
- label: item.title.trim() || item.name,
591
- workspaceId: item.workspaceId,
592
- withAtPrefix: true
593
- });
594
- }
595
- if (item.kind === "agent-target") {
596
- return createRichTextMentionMarkdown({
597
- providerId: "agent-target",
598
- entityId: item.targetId,
599
- label: item.name,
600
- scope: { workspaceId: item.workspaceId }
601
- });
602
- }
603
- const identity = parseRichTextMentionHref(item.href, item.name);
604
- return identity ? createRichTextMentionMarkdown(identity) : "";
605
- }
606
- function normalizeAgentSessionMarkdownLabel(value) {
607
- return value.trim().replace(/^@+/, "").trim();
608
- }
609
- function agentSessionTargetIdFromHref(href) {
610
- const mention = parseRichTextMentionHref(href, "");
611
- const agentTargetId = mention?.scope?.agentTargetId?.trim() ?? "";
612
- return agentTargetId || void 0;
613
- }
614
- function parseMentionFileCount(value) {
615
- const parsed = typeof value === "number" ? value : typeof value === "string" ? Number.parseInt(value.trim(), 10) : Number.NaN;
616
- return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
617
- }
618
- function parseAgentMentionMarkdown(value, start = 0) {
619
- if (!value.startsWith("[", start)) {
620
- return null;
621
- }
622
- let index = start + 1;
623
- const prefixedMention = value[index] === "@";
624
- if (prefixedMention) {
625
- index += 1;
626
- }
627
- let name = "";
628
- while (index < value.length) {
629
- const current = value[index];
630
- if (current === "\\") {
631
- const escaped = value[index + 1];
632
- if (escaped === "\\" || escaped === "[" || escaped === "]") {
633
- name += escaped;
634
- index += 2;
635
- continue;
636
- }
637
- name += current;
638
- index += 1;
639
- continue;
640
- }
641
- if (current === "]") {
642
- break;
643
- }
644
- name += current;
645
- index += 1;
646
- }
647
- if (value[index] !== "]" || value[index + 1] !== "(") {
648
- return null;
649
- }
650
- index += 2;
651
- let href = "";
652
- while (index < value.length) {
653
- const current = value[index];
654
- if (current === "\\") {
655
- const escaped = value[index + 1];
656
- if (escaped === "\\" || escaped === ")") {
657
- href += escaped;
658
- index += 2;
659
- continue;
660
- }
661
- href += current;
662
- index += 1;
663
- continue;
664
- }
665
- if (current === ")") {
666
- const item = parseMentionItemFromHref({ name, href });
667
- if (!item) {
668
- return null;
669
- }
670
- if (item.kind !== "file" && !prefixedMention && !isRichTextMentionHref(href)) {
671
- return null;
672
- }
673
- return {
674
- item,
675
- end: index + 1
676
- };
677
- }
678
- href += current;
679
- index += 1;
680
- }
681
- return null;
682
- }
683
- function parseMentionItemFromHref(input) {
684
- const href = input.href.trim();
685
- if (!href) {
686
- return null;
687
- }
688
- const mention = parseRichTextMentionHref(href, input.name);
689
- if (!mention && !isRichTextMentionHref(href)) {
690
- return {
691
- kind: "file",
692
- href,
693
- path: href,
694
- name: input.name,
695
- entryKind: isLocalDirectoryMentionHref(href) ? "directory" : "unknown",
696
- directoryPath: dirnameFromPath2(href)
697
- };
698
- }
699
- if (!mention) {
700
- return null;
701
- }
702
- const resource = mention.providerId.trim().toLowerCase();
703
- const targetId = mention.entityId.trim();
704
- const workspaceId = mention.scope?.workspaceId?.trim() ?? "";
705
- const name = mention.label;
706
- if (resource === "agent-session") {
707
- if (!workspaceId) {
708
- return null;
709
- }
710
- return {
711
- kind: "session",
712
- href,
713
- workspaceId,
714
- targetId,
715
- agentTargetId: mention.scope?.agentTargetId?.trim() || void 0,
716
- name,
717
- title: name,
718
- scope: "collab_sessions",
719
- initiatorName: "",
720
- agentName: ""
721
- };
722
- }
723
- if (resource === "workspace-issue") {
724
- if (!workspaceId) {
725
- return null;
726
- }
727
- return {
728
- kind: "workspace-issue",
729
- href,
730
- workspaceId,
731
- targetId,
732
- topicId: mention.scope?.topicId?.trim() || void 0,
733
- name,
734
- title: name
735
- };
736
- }
737
- if (resource === "workspace-app") {
738
- if (!workspaceId) {
739
- return null;
740
- }
741
- return {
742
- kind: "workspace-app",
743
- href,
744
- workspaceId,
745
- targetId,
746
- appId: targetId,
747
- name,
748
- iconUrl: mention.scope?.icon?.trim() || void 0
749
- };
750
- }
751
- if (resource === "agent-target") {
752
- if (!workspaceId) {
753
- return null;
754
- }
755
- return {
756
- kind: "agent-target",
757
- href,
758
- workspaceId,
759
- targetId,
760
- name
761
- };
762
- }
763
- if (resource === "workspace-reference") {
764
- if (!workspaceId) {
765
- return null;
766
- }
767
- const source = mention.scope?.source?.trim();
768
- if (source !== "app" && source !== "task") {
769
- return null;
770
- }
771
- return {
772
- kind: "workspace-reference",
773
- href,
774
- workspaceId,
775
- targetId,
776
- source,
777
- groupId: mention.scope?.groupId?.trim() || void 0,
778
- name,
779
- iconUrl: mention.scope?.icon?.trim() || void 0,
780
- fileCount: parseMentionFileCount(mention.scope?.count)
781
- };
782
- }
783
- if (resource === "workspace-app-factory") {
784
- return {
785
- kind: "workspace-app-factory",
786
- href,
787
- workspaceId,
788
- targetId,
789
- jobId: targetId === "create" ? "" : targetId,
790
- name: name || translate("agentHost.agentGui.workspaceAppFactoryMentionFallback"),
791
- action: mention.scope?.action?.trim() || void 0,
792
- contextPath: mention.scope?.contextPath?.trim() || void 0
698
+ syncEditable();
699
+ editor.on("transaction", syncEditable);
700
+ editor.on("update", syncEditable);
701
+ return () => {
702
+ editor.off("transaction", syncEditable);
703
+ editor.off("update", syncEditable);
793
704
  };
705
+ }, [editor]);
706
+ const handleRemove = (event) => {
707
+ event.preventDefault();
708
+ event.stopPropagation();
709
+ if (!editor.isEditable) {
710
+ return;
711
+ }
712
+ deleteNode();
713
+ if (!hasPromptContentAfterMentionRemoval(editor.state.doc)) {
714
+ editor.commands.clearContent();
715
+ }
716
+ };
717
+ if (mention.kind === "file") {
718
+ return /* @__PURE__ */ jsx(AgentMentionLegacyFileNodeView, { ...props });
794
719
  }
795
- const customDefinition = getAgentCustomMentionKind(resource);
796
- if (customDefinition) {
797
- const presentation = customDefinition.present(mention, href);
798
- if (!presentation) {
799
- return null;
720
+ if (mention.kind === "workspace-app" || mention.kind === "workspace-reference" || mention.kind === "agent-target") {
721
+ return /* @__PURE__ */ jsx(
722
+ NodeViewWrapper,
723
+ {
724
+ as: "span",
725
+ "aria-label": mention.ariaLabel,
726
+ className: `agent-rich-text-mention-node inline-flex max-w-[min(100%,var(--agent-mention-max-width,16rem))] align-middle ${selected ? "is-selected" : ""}`,
727
+ contentEditable: false,
728
+ "data-agent-file-mention": "true",
729
+ "data-agent-mention-href": mention.href,
730
+ "data-agent-mention-icon-url": mention.iconUrl,
731
+ "data-agent-mention-kind": mention.kind,
732
+ children: /* @__PURE__ */ jsxs(
733
+ "span",
734
+ {
735
+ className: "group relative top-0 inline-flex max-w-[min(100%,var(--agent-mention-max-width,16rem))] cursor-pointer items-center gap-1 overflow-hidden rounded-[4px] border border-transparent bg-transparent px-1 py-0 align-middle text-[13px] font-medium leading-6 text-[var(--agent-gui-mention-app-color,var(--tutti-purple))] no-underline transition-colors hover:border-transparent hover:bg-[color-mix(in_srgb,currentColor_12%,transparent)]",
736
+ "data-agent-mention-kind": mention.kind,
737
+ "data-slot": "mention-pill",
738
+ children: [
739
+ /* @__PURE__ */ jsxs(
740
+ "span",
741
+ {
742
+ "aria-hidden": isEditable ? void 0 : true,
743
+ className: "relative grid size-4 shrink-0 place-items-center overflow-hidden rounded-[4px] bg-block",
744
+ "data-agent-mention-app-icon": "true",
745
+ "data-workspace-app-icon": "true",
746
+ children: [
747
+ mention.iconUrl ? /* @__PURE__ */ jsx(
748
+ "img",
749
+ {
750
+ src: mention.iconUrl,
751
+ alt: "",
752
+ className: `size-full object-cover transition-opacity ${isEditable ? "group-hover:opacity-0 group-focus-within:opacity-0" : ""}`,
753
+ decoding: "async",
754
+ loading: "lazy",
755
+ draggable: false
756
+ }
757
+ ) : /* @__PURE__ */ jsx(
758
+ "span",
759
+ {
760
+ className: `tsh-agent-object-token__kind-icon size-4 transition-opacity ${isEditable ? "group-hover:opacity-0 group-focus-within:opacity-0" : ""}`
761
+ }
762
+ ),
763
+ isEditable ? /* @__PURE__ */ jsx(
764
+ "button",
765
+ {
766
+ "aria-label": removeActionAriaLabel,
767
+ className: "absolute left-1/2 top-1/2 inline-flex size-5 -translate-x-1/2 -translate-y-1/2 items-center justify-center text-[var(--text-secondary)] opacity-0 transition-opacity hover:text-[var(--text-primary)] focus-visible:opacity-100 group-hover:opacity-100",
768
+ type: "button",
769
+ onMouseDown: handleRemove,
770
+ children: /* @__PURE__ */ jsx(CloseIcon, { className: "size-3.5" })
771
+ }
772
+ ) : null
773
+ ]
774
+ }
775
+ ),
776
+ /* @__PURE__ */ jsx(
777
+ TruncatingPillLabel,
778
+ {
779
+ tooltip: mention.label,
780
+ withTooltipProvider,
781
+ children: mention.label
782
+ }
783
+ )
784
+ ]
785
+ }
786
+ )
787
+ }
788
+ );
789
+ }
790
+ if (mention.kind === "custom") {
791
+ const definition = getAgentCustomMentionKind(mention.customKind ?? "");
792
+ const removeAction = isEditable ? /* @__PURE__ */ jsx(
793
+ "button",
794
+ {
795
+ "aria-label": removeActionAriaLabel,
796
+ className: "inline-flex size-4 shrink-0 items-center justify-center text-[var(--text-secondary)] opacity-0 transition-opacity hover:text-[var(--text-primary)] focus-visible:opacity-100 group-hover:opacity-100",
797
+ type: "button",
798
+ onMouseDown: handleRemove,
799
+ children: /* @__PURE__ */ jsx(CloseIcon, { className: "size-3.5" })
800
+ }
801
+ ) : null;
802
+ if (definition?.renderChip) {
803
+ return /* @__PURE__ */ jsx(
804
+ NodeViewWrapper,
805
+ {
806
+ as: "span",
807
+ "aria-label": mention.ariaLabel,
808
+ className: `agent-rich-text-mention-node inline-grid max-w-[min(100%,var(--agent-mention-max-width,20rem))] align-middle ${selected ? "is-selected" : ""}`,
809
+ contentEditable: false,
810
+ "data-agent-file-mention": "true",
811
+ "data-agent-mention-href": mention.href,
812
+ "data-agent-mention-kind": mention.customKind || mention.kind,
813
+ children: definition.renderChip({
814
+ href: mention.href,
815
+ name: mention.label,
816
+ summary: mention.summary,
817
+ isEditable,
818
+ removeAction
819
+ })
820
+ }
821
+ );
800
822
  }
801
- return {
802
- kind: "custom",
803
- customKind: resource,
804
- href,
805
- workspaceId: presentation.workspaceId?.trim() || workspaceId,
806
- targetId,
807
- name: presentation.name.trim() || name,
808
- summary: presentation.summary?.trim() || void 0
809
- };
823
+ return /* @__PURE__ */ jsx(
824
+ NodeViewWrapper,
825
+ {
826
+ as: "span",
827
+ "aria-label": mention.ariaLabel,
828
+ className: `agent-rich-text-mention-node inline-grid max-w-[min(100%,var(--agent-mention-max-width,20rem))] align-middle ${selected ? "is-selected" : ""}`,
829
+ contentEditable: false,
830
+ "data-agent-file-mention": "true",
831
+ "data-agent-mention-href": mention.href,
832
+ "data-agent-mention-kind": mention.customKind || mention.kind,
833
+ children: /* @__PURE__ */ jsxs(
834
+ "span",
835
+ {
836
+ className: "group relative grid max-w-full cursor-pointer gap-0.5 overflow-hidden rounded-[8px] border border-[var(--border-primary,rgba(0,0,0,0.08))] bg-block px-2.5 py-1.5 text-left align-middle",
837
+ "data-slot": "mention-card",
838
+ children: [
839
+ /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-1", children: [
840
+ /* @__PURE__ */ jsx(
841
+ "span",
842
+ {
843
+ "aria-hidden": "true",
844
+ className: "tsh-agent-object-token__kind-icon size-3.5 shrink-0"
845
+ }
846
+ ),
847
+ /* @__PURE__ */ jsx("span", { className: "truncate text-[13px] font-medium leading-[130%]", children: mention.label }),
848
+ removeAction
849
+ ] }),
850
+ mention.summary ? /* @__PURE__ */ jsx("span", { className: "truncate text-[12px] font-normal leading-[130%] text-[var(--text-tertiary)]", children: mention.summary }) : null
851
+ ]
852
+ }
853
+ )
854
+ }
855
+ );
810
856
  }
811
- return null;
812
- }
813
- function isLocalDirectoryMentionHref(href) {
814
- return href.endsWith("/") && !/^[a-zA-Z][a-zA-Z\d+.-]*:/.test(href);
857
+ return /* @__PURE__ */ jsx(
858
+ NodeViewWrapper,
859
+ {
860
+ as: "span",
861
+ className: `agent-rich-text-mention-node inline-flex max-w-[min(100%,var(--agent-mention-max-width,16rem))] align-middle ${selected ? "is-selected" : ""}`,
862
+ contentEditable: false,
863
+ children: /* @__PURE__ */ jsx(
864
+ MentionPill,
865
+ {
866
+ "aria-label": mention.ariaLabel,
867
+ className: "top-0 h-6 py-0 align-middle leading-6",
868
+ "data-agent-mention-href": mention.href,
869
+ "data-agent-mention-kind": mention.kind,
870
+ kind: mention.kind === "session" ? "session" : "issue",
871
+ iconUrl: mention.iconUrl,
872
+ label: mention.label,
873
+ removable: isEditable,
874
+ removeButtonProps: isEditable ? {
875
+ "aria-label": removeActionAriaLabel,
876
+ onMouseDown: handleRemove
877
+ } : void 0,
878
+ summary: mention.summary,
879
+ withTooltipProvider
880
+ }
881
+ )
882
+ }
883
+ );
815
884
  }
816
885
 
817
886
  // agent-gui/agentGuiNode/agentRichText/agentMentionAttrs.ts
@@ -828,6 +897,11 @@ function mentionItemToAttrs(item) {
828
897
  };
829
898
  }
830
899
  if (item.kind === "session") {
900
+ const iconUrl = resolveAgentSessionMentionIconUrl({
901
+ agentIconUrl: item.agentIconUrl,
902
+ agentTargetId: item.agentTargetId,
903
+ href: item.href
904
+ });
831
905
  return {
832
906
  name: item.name,
833
907
  kind: item.kind,
@@ -839,6 +913,7 @@ function mentionItemToAttrs(item) {
839
913
  title: item.title,
840
914
  initiatorName: item.initiatorName,
841
915
  agentName: item.agentName,
916
+ ...iconUrl ? { iconUrl } : {},
842
917
  status: item.status ?? "",
843
918
  inputPreview: item.inputPreview ?? "",
844
919
  summaryPreview: item.summaryPreview ?? ""
@@ -941,6 +1016,7 @@ function attrsToMentionItem(attrs) {
941
1016
  scope: attrs.scope === "my_sessions" || attrs.scope === "collab_sessions" ? attrs.scope : "collab_sessions",
942
1017
  initiatorName: typeof attrs.initiatorName === "string" ? attrs.initiatorName : "",
943
1018
  agentName: typeof attrs.agentName === "string" ? attrs.agentName : "",
1019
+ agentIconUrl: typeof attrs.iconUrl === "string" && attrs.iconUrl.trim() ? attrs.iconUrl.trim() : void 0,
944
1020
  status: typeof attrs.status === "string" ? attrs.status : void 0,
945
1021
  inputPreview: typeof attrs.inputPreview === "string" ? attrs.inputPreview : void 0,
946
1022
  summaryPreview: typeof attrs.summaryPreview === "string" ? attrs.summaryPreview : void 0
@@ -1048,7 +1124,7 @@ function attrsToMentionItem(attrs) {
1048
1124
  path,
1049
1125
  name,
1050
1126
  entryKind: normalizeEntryKind(attrs.entryKind),
1051
- directoryPath: typeof attrs.directoryPath === "string" && attrs.directoryPath.trim() ? attrs.directoryPath : dirnameFromPath2(path),
1127
+ directoryPath: typeof attrs.directoryPath === "string" && attrs.directoryPath.trim() ? attrs.directoryPath : dirnameFromPath(path),
1052
1128
  thumbnailUrl: resolveAgentMentionFileThumbnailUrl({
1053
1129
  entryKind: normalizeEntryKind(attrs.entryKind),
1054
1130
  href: href || path,
@@ -1108,56 +1184,6 @@ function normalizeEntryKind(value) {
1108
1184
  return value === "directory" || value === "file" ? value : "unknown";
1109
1185
  }
1110
1186
 
1111
- // agent-gui/agentGuiNode/agentRichText/agentMentionPresentation.ts
1112
- function mentionVisual(item) {
1113
- if (item.kind === "file") {
1114
- return {
1115
- kindLabel: "File",
1116
- primary: item.name
1117
- };
1118
- }
1119
- if (item.kind === "session") {
1120
- return {
1121
- kindLabel: "Session",
1122
- primary: item.title.trim() || item.name.trim()
1123
- };
1124
- }
1125
- if (item.kind === "workspace-app") {
1126
- return {
1127
- kindLabel: "App",
1128
- primary: item.name
1129
- };
1130
- }
1131
- if (item.kind === "agent-target") {
1132
- return {
1133
- kindLabel: "Agent",
1134
- primary: item.name
1135
- };
1136
- }
1137
- if (item.kind === "workspace-app-factory") {
1138
- return {
1139
- kindLabel: "App Factory",
1140
- primary: item.name
1141
- };
1142
- }
1143
- if (item.kind === "workspace-reference") {
1144
- return {
1145
- kindLabel: "Reference",
1146
- primary: item.name
1147
- };
1148
- }
1149
- if (item.kind === "custom") {
1150
- return {
1151
- kindLabel: "Reference",
1152
- primary: item.name
1153
- };
1154
- }
1155
- return {
1156
- kindLabel: "Task",
1157
- primary: item.name
1158
- };
1159
- }
1160
-
1161
1187
  // agent-gui/agentGuiNode/agentRichText/agentFileMentionExtension.ts
1162
1188
  var agentFileMentionPluginKey = new PluginKey(
1163
1189
  "agentFileMentionSuggestion"
@@ -1165,6 +1191,15 @@ var agentFileMentionPluginKey = new PluginKey(
1165
1191
  function exitAgentFileMentionSuggestion(editor) {
1166
1192
  exitSuggestion(editor.view, agentFileMentionPluginKey);
1167
1193
  }
1194
+ function mentionItemIconUrl(item) {
1195
+ if (item.kind === "session") {
1196
+ return item.agentIconUrl;
1197
+ }
1198
+ if (item.kind === "workspace-app" || item.kind === "agent-target" || item.kind === "workspace-reference") {
1199
+ return item.iconUrl;
1200
+ }
1201
+ return void 0;
1202
+ }
1168
1203
  var MENTION_PLACEHOLDER_LEAF_SENTINEL = "\uFFFC";
1169
1204
  var MENTION_PLACEHOLDER_MAX_LENGTH = 40;
1170
1205
  function expandRangeOverMentionPlaceholder(editor, range) {
@@ -1280,6 +1315,7 @@ function createAgentFileMentionExtension(options = {}) {
1280
1315
  const item = attrsToMentionItem(HTMLAttributes);
1281
1316
  const fileThumbnailUrl = item.kind === "file" ? resolveAgentMentionFileThumbnailUrl(item) : void 0;
1282
1317
  const href = item.href;
1318
+ const iconUrl = mentionItemIconUrl(item);
1283
1319
  const tagName = options.renderAsLink ? "a" : "span";
1284
1320
  const visual = mentionVisual(item);
1285
1321
  const sharedAttributes = {
@@ -1298,7 +1334,7 @@ function createAgentFileMentionExtension(options = {}) {
1298
1334
  "data-agent-file-visual-kind": resolveAgentMentionFileVisualKind(item)
1299
1335
  } : {},
1300
1336
  ...options.renderAsLink ? { href } : {},
1301
- ...(item.kind === "workspace-app" || item.kind === "agent-target" || item.kind === "workspace-reference") && item.iconUrl ? { "data-agent-mention-icon-url": item.iconUrl } : {},
1337
+ ...iconUrl ? { "data-agent-mention-icon-url": iconUrl } : {},
1302
1338
  ...item.kind === "workspace-reference" ? { "data-agent-mention-file-count": String(item.fileCount) } : {},
1303
1339
  ...fileThumbnailUrl ? { "data-agent-mention-thumbnail-url": fileThumbnailUrl } : {},
1304
1340
  class: item.kind === "file" ? "tsh-agent-object-token tsh-agent-object-token--file" : "tsh-agent-object-token tsh-agent-object-token--entity"
@@ -1448,7 +1484,22 @@ function createAgentFileMentionExtension(options = {}) {
1448
1484
  });
1449
1485
  }
1450
1486
 
1487
+ // shared/workspaceAgentSyntheticMessages.ts
1488
+ function isWorkspaceAgentSyntheticControlMessage(text) {
1489
+ const normalized = text?.trim().toLowerCase() ?? "";
1490
+ switch (normalized) {
1491
+ case "[request interrupted by user]":
1492
+ case "request interrupted by user":
1493
+ case "[request interrupted by user for tool use]":
1494
+ case "request interrupted by user for tool use":
1495
+ return true;
1496
+ default:
1497
+ return false;
1498
+ }
1499
+ }
1500
+
1451
1501
  export {
1502
+ isWorkspaceAgentSyntheticControlMessage,
1452
1503
  AGENT_RICH_TEXT_CARET_ANCHOR,
1453
1504
  normalizeAgentSessionMentionTitle,
1454
1505
  createAgentSessionMentionHref,
@@ -1461,4 +1512,4 @@ export {
1461
1512
  exitAgentFileMentionSuggestion,
1462
1513
  createAgentFileMentionExtension
1463
1514
  };
1464
- //# sourceMappingURL=chunk-CPUEPDF7.js.map
1515
+ //# sourceMappingURL=chunk-GCW57WYQ.js.map