@tutti-os/agent-gui 0.0.11 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/agent-conversation/index.d.ts +5 -52
  2. package/dist/agent-conversation/index.js +4 -3
  3. package/dist/agent-conversation/index.js.map +1 -1
  4. package/dist/agent-message-center/index.d.ts +15 -5
  5. package/dist/agent-message-center/index.js +49 -28
  6. package/dist/agent-message-center/index.js.map +1 -1
  7. package/dist/{agentConversationVM-BtHYOTgv.d.ts → agentConversationVM-BVe64P2E.d.ts} +1 -1
  8. package/dist/app/renderer/agentactivity.css +136 -134
  9. package/dist/app/renderer/assets/icons/agents/manage-agent-tutti.png +0 -0
  10. package/dist/app/renderer/assets/icons/agents/tutti-doc-rounded.png +0 -0
  11. package/dist/app/renderer/assets/icons/agents/workspace-dock-agent-nexight.png +0 -0
  12. package/dist/chunk-3YZX5EUC.js +1993 -0
  13. package/dist/chunk-3YZX5EUC.js.map +1 -0
  14. package/dist/{chunk-QU4F2RSS.js → chunk-ASAZDEQE.js} +7 -7
  15. package/dist/chunk-ASAZDEQE.js.map +1 -0
  16. package/dist/{chunk-B7K776UD.js → chunk-FSTZDNRM.js} +51 -3
  17. package/dist/chunk-FSTZDNRM.js.map +1 -0
  18. package/dist/{chunk-ZEFETOTS.js → chunk-GZHQPPK2.js} +718 -2010
  19. package/dist/chunk-GZHQPPK2.js.map +1 -0
  20. package/dist/{chunk-CGBRAWTD.js → chunk-HSXDSFKB.js} +10 -1123
  21. package/dist/chunk-HSXDSFKB.js.map +1 -0
  22. package/dist/{chunk-ITMKZRCT.js → chunk-KEKPOVQD.js} +15 -8
  23. package/dist/chunk-KEKPOVQD.js.map +1 -0
  24. package/dist/{chunk-4ASBZ4X7.js → chunk-MTFSQWZ6.js} +2 -2
  25. package/dist/chunk-MU2LODEV.js +1211 -0
  26. package/dist/chunk-MU2LODEV.js.map +1 -0
  27. package/dist/{chunk-R5Q2UDDH.js → chunk-Q75AK47T.js} +2 -2
  28. package/dist/{chunk-QTZALZIV.js → chunk-RLPVFX7V.js} +140 -58
  29. package/dist/chunk-RLPVFX7V.js.map +1 -0
  30. package/dist/chunk-VDNMTW2E.js +9 -0
  31. package/dist/chunk-VDNMTW2E.js.map +1 -0
  32. package/dist/chunk-WME2V26J.js +1124 -0
  33. package/dist/chunk-WME2V26J.js.map +1 -0
  34. package/dist/chunk-YXSO4ITT.js +10 -0
  35. package/dist/chunk-YXSO4ITT.js.map +1 -0
  36. package/dist/{chunk-3735XYFZ.js → chunk-ZO3SZCIX.js} +54 -3
  37. package/dist/chunk-ZO3SZCIX.js.map +1 -0
  38. package/dist/context-mention-palette/index.d.ts +203 -0
  39. package/dist/context-mention-palette/index.js +30 -0
  40. package/dist/context-mention-provider.d.ts +51 -0
  41. package/dist/context-mention-provider.js +7 -0
  42. package/dist/context-mention-provider.js.map +1 -0
  43. package/dist/i18n/index.d.ts +50 -2
  44. package/dist/i18n/index.js +1 -1
  45. package/dist/index.d.ts +33 -6
  46. package/dist/index.js +3466 -4473
  47. package/dist/index.js.map +1 -1
  48. package/dist/plan-decision-ops.d.ts +2 -2
  49. package/dist/workbench/contribution.js +5 -5
  50. package/dist/workbench/index.d.ts +2 -2
  51. package/dist/workbench/index.js +10 -6
  52. package/dist/workbench/launch.d.ts +19 -2
  53. package/dist/workbench/launch.js +7 -2
  54. package/dist/workbench/types.d.ts +6 -1
  55. package/dist/workbench/types.js +5 -3
  56. package/dist/workspace-agent-generated-files.d.ts +1 -1
  57. package/dist/workspace-agent-generated-files.js +2 -2
  58. package/dist/{workspaceAgentActivityListViewModel-BLLYGuFO.d.ts → workspaceAgentActivityListViewModel-BK_J3aNX.d.ts} +8 -5
  59. package/dist/{workspaceLinkActions-Bwa-phu8.d.ts → workspaceLinkActions-BlLN8Pvz.d.ts} +7 -1
  60. package/package.json +24 -15
  61. package/dist/agent-rich-text-at-provider.d.ts +0 -63
  62. package/dist/agent-rich-text-at-provider.js +0 -7
  63. package/dist/chunk-3735XYFZ.js.map +0 -1
  64. package/dist/chunk-6AZ2KF6R.js +0 -7
  65. package/dist/chunk-6AZ2KF6R.js.map +0 -1
  66. package/dist/chunk-77HBKGHF.js +0 -13
  67. package/dist/chunk-77HBKGHF.js.map +0 -1
  68. package/dist/chunk-B7K776UD.js.map +0 -1
  69. package/dist/chunk-CGBRAWTD.js.map +0 -1
  70. package/dist/chunk-ITMKZRCT.js.map +0 -1
  71. package/dist/chunk-QTZALZIV.js.map +0 -1
  72. package/dist/chunk-QU4F2RSS.js.map +0 -1
  73. package/dist/chunk-ZEFETOTS.js.map +0 -1
  74. /package/dist/{chunk-4ASBZ4X7.js.map → chunk-MTFSQWZ6.js.map} +0 -0
  75. /package/dist/{chunk-R5Q2UDDH.js.map → chunk-Q75AK47T.js.map} +0 -0
  76. /package/dist/{agent-rich-text-at-provider.js.map → context-mention-palette/index.js.map} +0 -0
@@ -0,0 +1,1993 @@
1
+ import {
2
+ Spinner,
3
+ managedAgentRoundedIconUrl,
4
+ userAvatarPlaceholderUrl,
5
+ workspaceAgentActivityStatusLabel
6
+ } from "./chunk-HSXDSFKB.js";
7
+ import {
8
+ buildAgentGenericMentionHref,
9
+ buildAgentSessionMentionHref,
10
+ buildAgentWorkspaceAppMentionHref,
11
+ buildAgentWorkspaceIssueMentionHref,
12
+ normalizeAgentSessionMentionTitle
13
+ } from "./chunk-MU2LODEV.js";
14
+ import {
15
+ AGENT_CONTEXT_MENTION_PROVIDER_IDS
16
+ } from "./chunk-YXSO4ITT.js";
17
+ import {
18
+ translate
19
+ } from "./chunk-FSTZDNRM.js";
20
+ import {
21
+ resolveAgentMentionFileThumbnailUrl,
22
+ resolveAgentMentionFileVisualKind
23
+ } from "./chunk-LUGELG5V.js";
24
+
25
+ // agent-gui/agentGuiNode/agentMentionAgentGeneratedFilesPresentation.ts
26
+ var AGENT_GENERATED_FOLDER_MIN_FILES = 2;
27
+ function presentAgentGeneratedFileMentionItems(input) {
28
+ const fileItems = input.files.filter(
29
+ (item) => item.kind === "file"
30
+ );
31
+ if (input.query.trim()) {
32
+ return fileItems;
33
+ }
34
+ if (input.browsePath) {
35
+ return presentAgentGeneratedBrowseFolder(fileItems, input.browsePath);
36
+ }
37
+ return presentAgentGeneratedRootFolders(fileItems);
38
+ }
39
+ function presentAgentGeneratedRootFolders(files) {
40
+ const filesByDirectory = /* @__PURE__ */ new Map();
41
+ for (const file of files) {
42
+ const directoryPath = resolveAgentGeneratedFileDirectoryPath(file);
43
+ const group = filesByDirectory.get(directoryPath);
44
+ if (group) {
45
+ group.push(file);
46
+ continue;
47
+ }
48
+ filesByDirectory.set(directoryPath, [file]);
49
+ }
50
+ const presented = [];
51
+ for (const [directoryPath, group] of filesByDirectory) {
52
+ if (group.length >= AGENT_GENERATED_FOLDER_MIN_FILES) {
53
+ presented.push(createAgentGeneratedFolderItem(directoryPath, group));
54
+ continue;
55
+ }
56
+ presented.push(...group);
57
+ }
58
+ return sortAgentGeneratedMentionItems(presented);
59
+ }
60
+ function presentAgentGeneratedBrowseFolder(files, browsePath) {
61
+ const normalizedBrowsePath = normalizeAgentGeneratedDirectoryPath(browsePath);
62
+ const children = files.filter(
63
+ (file) => resolveAgentGeneratedFileDirectoryPath(file) === normalizedBrowsePath
64
+ );
65
+ return [
66
+ createAgentGeneratedFolderBackItem(normalizedBrowsePath),
67
+ ...sortAgentGeneratedMentionItems(children)
68
+ ];
69
+ }
70
+ function createAgentGeneratedFolderItem(directoryPath, files) {
71
+ const normalizedPath = normalizeAgentGeneratedDirectoryPath(directoryPath);
72
+ const name = normalizedPath.split("/").filter(Boolean).at(-1) ?? normalizedPath;
73
+ return {
74
+ kind: "file",
75
+ href: `${normalizedPath}/`,
76
+ path: normalizedPath,
77
+ name,
78
+ entryKind: "directory",
79
+ directoryPath: parentAgentGeneratedDirectoryPath(normalizedPath),
80
+ mentionNavigation: "agent-generated-folder",
81
+ childCount: files.length
82
+ };
83
+ }
84
+ function createAgentGeneratedFolderBackItem(browsePath) {
85
+ return {
86
+ kind: "file",
87
+ href: "",
88
+ path: browsePath,
89
+ name: translate("agentHost.agentGui.mentionAgentGeneratedFolderBack"),
90
+ entryKind: "unknown",
91
+ directoryPath: parentAgentGeneratedDirectoryPath(browsePath),
92
+ mentionNavigation: "agent-generated-folder-back"
93
+ };
94
+ }
95
+ function resolveAgentGeneratedFileDirectoryPath(file) {
96
+ const directoryPath = file.directoryPath?.trim();
97
+ if (directoryPath) {
98
+ return normalizeAgentGeneratedDirectoryPath(directoryPath);
99
+ }
100
+ return parentAgentGeneratedDirectoryPath(file.path);
101
+ }
102
+ function parentAgentGeneratedDirectoryPath(path) {
103
+ const normalized = normalizeAgentGeneratedDirectoryPath(path);
104
+ const index = normalized.lastIndexOf("/");
105
+ if (index <= 0) {
106
+ return "/";
107
+ }
108
+ return normalized.slice(0, index);
109
+ }
110
+ function normalizeAgentGeneratedDirectoryPath(path) {
111
+ return path.trim().replace(/\\/g, "/").replace(/\/+$/, "");
112
+ }
113
+ function sortAgentGeneratedMentionItems(items) {
114
+ return [...items].sort(
115
+ (left, right) => left.name.localeCompare(right.name, void 0, { sensitivity: "base" })
116
+ );
117
+ }
118
+ function agentGeneratedMentionItemKey(item) {
119
+ if (item.kind !== "file") {
120
+ return item.targetId;
121
+ }
122
+ if (item.mentionNavigation) {
123
+ return `${item.mentionNavigation}:${item.path}`;
124
+ }
125
+ return item.path;
126
+ }
127
+
128
+ // agent-gui/agentGuiNode/agentMentionSearchDiagnostics.ts
129
+ var AGENT_MENTION_SEARCH_LOG_PREFIX = "[agent-gui] mention-search";
130
+ var {
131
+ agentGeneratedFile: AGENT_GENERATED_FILE_PROVIDER_ID,
132
+ agentSession: AGENT_SESSION_PROVIDER_ID,
133
+ file: FILE_PROVIDER_ID,
134
+ workspaceApp: WORKSPACE_APP_PROVIDER_ID,
135
+ workspaceIssue: WORKSPACE_ISSUE_PROVIDER_ID
136
+ } = AGENT_CONTEXT_MENTION_PROVIDER_IDS;
137
+ var AGENT_MENTION_PROVIDER_LOG_ORDER = [
138
+ FILE_PROVIDER_ID,
139
+ AGENT_GENERATED_FILE_PROVIDER_ID,
140
+ WORKSPACE_APP_PROVIDER_ID,
141
+ WORKSPACE_ISSUE_PROVIDER_ID,
142
+ AGENT_SESSION_PROVIDER_ID
143
+ ];
144
+ function emitAgentMentionSearchDiagnostic(input) {
145
+ const durationMs = elapsedAgentMentionSearchDiagnosticMs(
146
+ input.diagnosticNow(),
147
+ input.startedAt
148
+ );
149
+ const providerResults = orderAgentMentionProviderDiagnostics(
150
+ input.providerDiagnostics
151
+ );
152
+ const hasProviderIssue = providerResults.some(
153
+ (result) => result.status === "timeout" || result.status === "error"
154
+ );
155
+ if (input.status === "ready" && !hasProviderIssue && durationMs < input.diagnosticSlowThresholdMs) {
156
+ return;
157
+ }
158
+ const payload = {
159
+ debounceMs: input.debounceMs,
160
+ durationMs,
161
+ ...input.status === "error" ? { errorKind: agentMentionSearchErrorKind(input.error) } : {},
162
+ event: "agent_gui.mention_search",
163
+ filter: input.filter,
164
+ groupCount: input.groups.length,
165
+ itemCount: input.groups.reduce((sum, group) => sum + group.items.length, 0),
166
+ mode: input.mode,
167
+ providerResults,
168
+ providerTimeoutMs: input.providerTimeoutMs,
169
+ queryLength: [...input.query].length,
170
+ requestId: input.requestId,
171
+ status: input.status,
172
+ workspaceId: input.workspaceId
173
+ };
174
+ try {
175
+ input.diagnosticInfoLogger(payload);
176
+ } catch {
177
+ }
178
+ }
179
+ async function queryAgentMentionProviderWithDiagnostics(input) {
180
+ if (!input.query) {
181
+ input.diagnostics.push({
182
+ durationMs: 0,
183
+ providerId: input.providerId,
184
+ resultCount: 0,
185
+ status: "missing"
186
+ });
187
+ return input.fallback;
188
+ }
189
+ const startedAt = input.diagnosticNow();
190
+ try {
191
+ const { result, timedOut } = await runAgentMentionProviderQuery({
192
+ fallback: input.fallback,
193
+ providerTimeoutMs: input.providerTimeoutMs,
194
+ query: input.query
195
+ });
196
+ input.diagnostics.push({
197
+ durationMs: elapsedAgentMentionSearchDiagnosticMs(
198
+ input.diagnosticNow(),
199
+ startedAt
200
+ ),
201
+ providerId: input.providerId,
202
+ resultCount: input.resultCount(result),
203
+ status: timedOut ? "timeout" : "success"
204
+ });
205
+ return result;
206
+ } catch (error) {
207
+ input.diagnostics.push({
208
+ durationMs: elapsedAgentMentionSearchDiagnosticMs(
209
+ input.diagnosticNow(),
210
+ startedAt
211
+ ),
212
+ errorKind: agentMentionSearchErrorKind(error),
213
+ providerId: input.providerId,
214
+ resultCount: 0,
215
+ status: "error"
216
+ });
217
+ throw error;
218
+ }
219
+ }
220
+ function elapsedAgentMentionSearchDiagnosticMs(now, startedAt) {
221
+ const durationMs = now - startedAt;
222
+ if (!Number.isFinite(durationMs)) {
223
+ return 0;
224
+ }
225
+ return Math.max(0, Math.round(durationMs));
226
+ }
227
+ function agentMentionSearchErrorKind(error) {
228
+ if (error instanceof Error && error.name.trim()) {
229
+ return error.name.trim();
230
+ }
231
+ if (error === null) {
232
+ return "null";
233
+ }
234
+ return typeof error;
235
+ }
236
+ function logAgentMentionSearchInfo(payload) {
237
+ console.info(AGENT_MENTION_SEARCH_LOG_PREFIX, JSON.stringify(payload));
238
+ }
239
+ function orderAgentMentionProviderDiagnostics(diagnostics) {
240
+ return [...diagnostics].sort((left, right) => {
241
+ const leftIndex = providerDiagnosticOrder(left.providerId);
242
+ const rightIndex = providerDiagnosticOrder(right.providerId);
243
+ return leftIndex - rightIndex || left.providerId.localeCompare(right.providerId);
244
+ });
245
+ }
246
+ function providerDiagnosticOrder(providerId) {
247
+ const index = AGENT_MENTION_PROVIDER_LOG_ORDER.indexOf(providerId);
248
+ return index === -1 ? AGENT_MENTION_PROVIDER_LOG_ORDER.length : index;
249
+ }
250
+ async function runAgentMentionProviderQuery(input) {
251
+ const abortController = new AbortController();
252
+ let timedOut = false;
253
+ const queryPromise = Promise.resolve().then(
254
+ () => input.query(abortController.signal)
255
+ );
256
+ const queryResultPromise = queryPromise.then(
257
+ (result) => ({ result, timedOut: false }),
258
+ (error) => {
259
+ if (timedOut && abortController.signal.aborted) {
260
+ return { result: input.fallback, timedOut: true };
261
+ }
262
+ throw error;
263
+ }
264
+ );
265
+ if (input.providerTimeoutMs <= 0 || !Number.isFinite(input.providerTimeoutMs)) {
266
+ return queryResultPromise;
267
+ }
268
+ let timeout = null;
269
+ const timeoutPromise = new Promise(
270
+ (resolve) => {
271
+ timeout = setTimeout(() => {
272
+ timedOut = true;
273
+ abortController.abort();
274
+ resolve({ result: input.fallback, timedOut: true });
275
+ }, input.providerTimeoutMs);
276
+ }
277
+ );
278
+ try {
279
+ return await Promise.race([queryResultPromise, timeoutPromise]);
280
+ } finally {
281
+ if (timeout !== null) {
282
+ clearTimeout(timeout);
283
+ }
284
+ }
285
+ }
286
+
287
+ // agent-gui/agentGuiNode/AgentMentionLabels.ts
288
+ function agentMentionGroupLabel(groupId) {
289
+ switch (groupId) {
290
+ case "apps":
291
+ return translate("agentHost.agentGui.mentionGroupApps");
292
+ case "files":
293
+ return translate("agentHost.agentGui.mentionGroupFiles");
294
+ case "opened_files":
295
+ return translate("agentHost.agentGui.mentionGroupOpenedFiles");
296
+ case "agent_generated_files":
297
+ return translate("agentHost.agentGui.mentionGroupAgentGeneratedFiles");
298
+ case "my_sessions":
299
+ return translate("agentHost.agentGui.mentionGroupMySessions");
300
+ case "collab_sessions":
301
+ return translate("agentHost.agentGui.mentionGroupCollabSessions");
302
+ case "issues":
303
+ return translate("agentHost.agentGui.mentionGroupIssues");
304
+ }
305
+ }
306
+ function agentMentionFilterLabel(filter) {
307
+ switch (filter) {
308
+ case "all":
309
+ return translate("agentHost.agentGui.mentionFilterAll");
310
+ case "app":
311
+ return translate("agentHost.agentGui.mentionFilterApp");
312
+ case "file":
313
+ return translate("agentHost.agentGui.mentionFilterFile");
314
+ case "session":
315
+ return translate("agentHost.agentGui.mentionFilterSession");
316
+ case "issue":
317
+ return translate("agentHost.agentGui.mentionFilterIssue");
318
+ }
319
+ }
320
+ function agentMentionEmptyGroupLabel(groupId, query) {
321
+ if (groupId === "files" || groupId === "opened_files") {
322
+ return query.trim() ? translate("agentHost.agentGui.mentionNoMatchingFiles") : translate("agentHost.agentGui.mentionEmptyDockFiles");
323
+ }
324
+ if (groupId === "agent_generated_files") {
325
+ return query.trim() ? translate("agentHost.agentGui.mentionNoMatchingFiles") : translate("agentHost.agentGui.mentionEmptyAgentGeneratedFiles");
326
+ }
327
+ if (groupId === "apps") {
328
+ return translate("agentHost.agentGui.mentionEmptyApps");
329
+ }
330
+ if (groupId === "my_sessions") {
331
+ return translate("agentHost.agentGui.mentionEmptyMySessions");
332
+ }
333
+ if (groupId === "collab_sessions") {
334
+ return translate("agentHost.agentGui.mentionEmptyCollabSessions");
335
+ }
336
+ return translate("agentHost.agentGui.mentionEmptyIssues");
337
+ }
338
+
339
+ // agent-gui/agentGuiNode/agentMentionSearchHelpers.ts
340
+ var AGENT_MENTION_FILTER_TAB_ORDER = [
341
+ "all",
342
+ "session",
343
+ "file",
344
+ "issue",
345
+ "app"
346
+ ];
347
+ var DEFAULT_MENTION_ALL_TAB_PAGE_SIZE = 5;
348
+ var DEFAULT_MENTION_GROUP_PAGE_SIZE = 10;
349
+ function mentionGroupPageSize(filter, _groupId) {
350
+ return filter === "all" ? DEFAULT_MENTION_ALL_TAB_PAGE_SIZE : DEFAULT_MENTION_GROUP_PAGE_SIZE;
351
+ }
352
+ function mentionGroupExpandCount(group, filter) {
353
+ const pageSize = mentionGroupPageSize(
354
+ filter,
355
+ group.id
356
+ );
357
+ const remaining = Math.max(0, group.totalCount - group.visibleCount);
358
+ return Math.min(pageSize, remaining);
359
+ }
360
+ function groupIdsForFilter(filter) {
361
+ switch (filter) {
362
+ case "app":
363
+ return ["apps"];
364
+ case "file":
365
+ return ["opened_files", "agent_generated_files"];
366
+ case "session":
367
+ return ["my_sessions"];
368
+ case "issue":
369
+ return ["issues"];
370
+ case "all":
371
+ default:
372
+ return ["my_sessions", "files", "issues", "apps"];
373
+ }
374
+ }
375
+ function shouldShowEmptyGroup(groupId, filter, query) {
376
+ const hasQuery = query.trim().length > 0;
377
+ if (groupId === "files") {
378
+ return filter === "all";
379
+ }
380
+ if (groupId === "opened_files" || groupId === "agent_generated_files") {
381
+ return filter === "file" && !hasQuery;
382
+ }
383
+ if (groupId === "apps") {
384
+ return filter === "all" || filter === "app";
385
+ }
386
+ if (groupId === "my_sessions") {
387
+ return filter === "all" || filter === "session";
388
+ }
389
+ if (groupId === "collab_sessions") {
390
+ return false;
391
+ }
392
+ return filter === "all" || filter === "issue";
393
+ }
394
+ function buildEmptyGroup(groupId, query) {
395
+ return {
396
+ id: groupId,
397
+ items: [],
398
+ totalCount: 0,
399
+ visibleCount: 0,
400
+ hasMore: false,
401
+ emptyLabel: emptyGroupLabel(groupId, query)
402
+ };
403
+ }
404
+ function emptyGroupLabel(groupId, query) {
405
+ return agentMentionEmptyGroupLabel(groupId, query);
406
+ }
407
+ function shouldPrefetchBrowseFilter(filter) {
408
+ return filter === "all" || filter === "app" || filter === "file" || filter === "session" || filter === "issue";
409
+ }
410
+ function filterForGroup(groupId) {
411
+ switch (groupId) {
412
+ case "apps":
413
+ return "app";
414
+ case "files":
415
+ case "opened_files":
416
+ case "agent_generated_files":
417
+ return "file";
418
+ case "my_sessions":
419
+ return "session";
420
+ case "collab_sessions":
421
+ return "session";
422
+ case "issues":
423
+ return "issue";
424
+ }
425
+ }
426
+ function resolveMentionGroupItems(groupId, rawGroups) {
427
+ if (groupId === "files") {
428
+ return [...rawGroups.opened_files, ...rawGroups.agent_generated_files];
429
+ }
430
+ return rawGroups[groupId] ?? [];
431
+ }
432
+ function resolveMentionGroupTotalCount(groupId, totalCounts, itemCount) {
433
+ if (groupId === "files") {
434
+ return (totalCounts.opened_files ?? 0) + (totalCounts.agent_generated_files ?? 0);
435
+ }
436
+ if (groupId === "agent_generated_files") {
437
+ return itemCount;
438
+ }
439
+ return totalCounts[groupId] ?? itemCount;
440
+ }
441
+ function normalizeQuery(value) {
442
+ return value.replace(/\s+/g, " ").trim();
443
+ }
444
+ function compactText(value) {
445
+ return value?.replace(/\s+/g, " ").trim() ?? "";
446
+ }
447
+
448
+ // agent-gui/agentGuiNode/AgentMentionSearchController.ts
449
+ var DEFAULT_DEBOUNCE_MS = 120;
450
+ var DEFAULT_FILE_LIMIT = 30;
451
+ var DEFAULT_ISSUE_LIMIT = 25;
452
+ var DEFAULT_SESSION_LIMIT = 30;
453
+ var DEFAULT_PROVIDER_TIMEOUT_MS = 3500;
454
+ var DEFAULT_DIAGNOSTIC_SLOW_THRESHOLD_MS = 250;
455
+ function buildBrowseCategories() {
456
+ return AGENT_MENTION_FILTER_TAB_ORDER.map((id) => ({
457
+ id,
458
+ label: agentMentionFilterLabel(id)
459
+ }));
460
+ }
461
+ var {
462
+ agentGeneratedFile: AGENT_GENERATED_FILE_PROVIDER_ID2,
463
+ agentSession: AGENT_SESSION_PROVIDER_ID2,
464
+ file: FILE_PROVIDER_ID2,
465
+ workspaceApp: WORKSPACE_APP_PROVIDER_ID2,
466
+ workspaceIssue: WORKSPACE_ISSUE_PROVIDER_ID2
467
+ } = AGENT_CONTEXT_MENTION_PROVIDER_IDS;
468
+ var AgentMentionSearchController = class {
469
+ contextMentionProviders;
470
+ debounceMs;
471
+ fileLimit;
472
+ issueLimit;
473
+ providerTimeoutMs;
474
+ diagnosticInfoLogger;
475
+ diagnosticNow;
476
+ diagnosticSlowThresholdMs;
477
+ listeners = /* @__PURE__ */ new Set();
478
+ expandedCounts = {};
479
+ totalCounts = {};
480
+ timer = null;
481
+ requestId = 0;
482
+ disposed = false;
483
+ activeWorkspaceId = "";
484
+ currentUserId = "";
485
+ currentFilter = "all";
486
+ currentQuery = "";
487
+ currentSessionCwd = "";
488
+ currentFileSearchLimit;
489
+ currentIssueSearchLimit;
490
+ agentGeneratedBrowsePath = null;
491
+ rawGroups = {
492
+ apps: [],
493
+ opened_files: [],
494
+ agent_generated_files: [],
495
+ my_sessions: [],
496
+ collab_sessions: [],
497
+ issues: []
498
+ };
499
+ state = {
500
+ status: "idle",
501
+ query: "",
502
+ mode: "browse",
503
+ filter: "all",
504
+ categories: buildBrowseCategories(),
505
+ groups: [],
506
+ error: null
507
+ };
508
+ constructor(options) {
509
+ this.contextMentionProviders = new Map(
510
+ (options.contextMentionProviders ?? []).map((provider) => [
511
+ provider.id,
512
+ provider
513
+ ])
514
+ );
515
+ this.debounceMs = options.debounceMs ?? DEFAULT_DEBOUNCE_MS;
516
+ this.fileLimit = options.fileLimit ?? DEFAULT_FILE_LIMIT;
517
+ this.issueLimit = options.issueLimit ?? DEFAULT_ISSUE_LIMIT;
518
+ this.providerTimeoutMs = options.providerTimeoutMs ?? DEFAULT_PROVIDER_TIMEOUT_MS;
519
+ this.diagnosticInfoLogger = options.diagnosticInfoLogger ?? logAgentMentionSearchInfo;
520
+ this.diagnosticNow = options.diagnosticNow ?? Date.now;
521
+ this.diagnosticSlowThresholdMs = options.diagnosticSlowThresholdMs ?? DEFAULT_DIAGNOSTIC_SLOW_THRESHOLD_MS;
522
+ this.currentFileSearchLimit = this.fileLimit;
523
+ this.currentIssueSearchLimit = this.issueLimit;
524
+ }
525
+ subscribe(listener) {
526
+ this.listeners.add(listener);
527
+ listener(this.state);
528
+ return () => {
529
+ this.listeners.delete(listener);
530
+ };
531
+ }
532
+ updateQuery(input) {
533
+ if (this.disposed) {
534
+ return;
535
+ }
536
+ this.activeWorkspaceId = input.workspaceId.trim();
537
+ this.currentUserId = input.currentUserId?.trim() ?? "";
538
+ this.currentSessionCwd = input.sessionCwd?.trim() ?? "";
539
+ this.currentQuery = normalizeQuery(input.query);
540
+ this.clearTimer();
541
+ const requestId = ++this.requestId;
542
+ this.resetAgentGeneratedBrowsePath();
543
+ this.resetExpandedCounts();
544
+ this.resetSearchLimits();
545
+ if (!this.activeWorkspaceId) {
546
+ this.setState({
547
+ status: "idle",
548
+ query: this.currentQuery,
549
+ mode: "browse",
550
+ filter: this.currentFilter,
551
+ categories: buildBrowseCategories(),
552
+ groups: [],
553
+ error: null
554
+ });
555
+ return;
556
+ }
557
+ if (!this.currentQuery) {
558
+ this.startBrowseModeFetch(this.currentFilter);
559
+ return;
560
+ }
561
+ this.setState({
562
+ status: "loading",
563
+ query: this.currentQuery,
564
+ mode: "results",
565
+ filter: this.currentFilter,
566
+ categories: buildBrowseCategories(),
567
+ groups: this.groupsFromRawGroups(),
568
+ error: null
569
+ });
570
+ this.timer = setTimeout(() => {
571
+ void this.runSearch({
572
+ workspaceId: this.activeWorkspaceId,
573
+ currentUserId: this.currentUserId,
574
+ query: this.currentQuery,
575
+ requestId
576
+ });
577
+ }, this.debounceMs);
578
+ }
579
+ setFilter(filter) {
580
+ if (this.disposed) {
581
+ return;
582
+ }
583
+ this.currentFilter = filter;
584
+ this.resetAgentGeneratedBrowsePath();
585
+ this.resetExpandedCounts();
586
+ if (!this.currentQuery) {
587
+ this.startBrowseModeFetch(filter);
588
+ return;
589
+ }
590
+ this.setState({
591
+ status: "ready",
592
+ query: this.currentQuery,
593
+ mode: "results",
594
+ filter: this.currentFilter,
595
+ categories: buildBrowseCategories(),
596
+ groups: this.groupsFromRawGroups(),
597
+ error: null
598
+ });
599
+ }
600
+ enterCategory(category) {
601
+ if (this.disposed) {
602
+ return;
603
+ }
604
+ this.currentFilter = category;
605
+ this.resetExpandedCounts();
606
+ this.clearTimer();
607
+ if (!this.currentQuery) {
608
+ this.startBrowseModeFetch(category);
609
+ return;
610
+ }
611
+ if (!this.activeWorkspaceId) {
612
+ this.emitBrowseState("ready");
613
+ return;
614
+ }
615
+ const requestId = ++this.requestId;
616
+ this.setState({
617
+ status: "loading",
618
+ query: this.currentQuery,
619
+ mode: "results",
620
+ filter: this.currentFilter,
621
+ categories: buildBrowseCategories(),
622
+ groups: this.groupsFromRawGroups(),
623
+ error: null
624
+ });
625
+ void this.runSearch({
626
+ workspaceId: this.activeWorkspaceId,
627
+ currentUserId: this.currentUserId,
628
+ query: this.currentQuery,
629
+ requestId
630
+ });
631
+ }
632
+ selectAgentGeneratedMentionItem(item) {
633
+ if (item.kind !== "file" || !item.mentionNavigation) {
634
+ return false;
635
+ }
636
+ if (item.mentionNavigation === "agent-generated-folder") {
637
+ this.agentGeneratedBrowsePath = item.path;
638
+ this.expandedCounts.agent_generated_files = mentionGroupPageSize(
639
+ this.currentFilter,
640
+ "agent_generated_files"
641
+ );
642
+ this.setState({
643
+ status: this.state.status === "loading" ? "loading" : "ready",
644
+ query: this.currentQuery,
645
+ mode: this.currentQuery ? "results" : "browse",
646
+ filter: this.currentFilter,
647
+ categories: buildBrowseCategories(),
648
+ groups: this.groupsFromRawGroups(),
649
+ error: null
650
+ });
651
+ return true;
652
+ }
653
+ if (item.mentionNavigation === "agent-generated-folder-back") {
654
+ this.resetAgentGeneratedBrowsePath();
655
+ this.setState({
656
+ status: this.state.status === "loading" ? "loading" : "ready",
657
+ query: this.currentQuery,
658
+ mode: this.currentQuery ? "results" : "browse",
659
+ filter: this.currentFilter,
660
+ categories: buildBrowseCategories(),
661
+ groups: this.groupsFromRawGroups(),
662
+ error: null
663
+ });
664
+ return true;
665
+ }
666
+ return false;
667
+ }
668
+ expandGroup(groupId) {
669
+ const pageSize = mentionGroupPageSize(this.currentFilter, groupId);
670
+ const current = this.expandedCounts[groupId] ?? pageSize;
671
+ this.expandedCounts[groupId] = current + pageSize;
672
+ if (!this.currentQuery) {
673
+ const nextFilter = filterForGroup(groupId);
674
+ if (this.currentFilter === "all") {
675
+ this.currentFilter = nextFilter;
676
+ }
677
+ this.setState({
678
+ status: "ready",
679
+ query: "",
680
+ mode: "browse",
681
+ filter: this.currentFilter,
682
+ categories: buildBrowseCategories(),
683
+ groups: this.groupsFromRawGroups(),
684
+ error: null
685
+ });
686
+ return;
687
+ }
688
+ const needsMoreFiles = (groupId === "opened_files" || groupId === "files" || groupId === "agent_generated_files") && (groupId === "agent_generated_files" ? this.rawGroups.agent_generated_files.length >= this.currentFileSearchLimit : this.rawGroups.opened_files.length >= this.currentFileSearchLimit);
689
+ const needsMoreIssues = groupId === "issues" && (this.totalCounts.issues ?? this.rawGroups.issues.length) > this.rawGroups.issues.length;
690
+ if (needsMoreFiles) {
691
+ this.currentFileSearchLimit += DEFAULT_MENTION_GROUP_PAGE_SIZE;
692
+ }
693
+ if (needsMoreIssues) {
694
+ this.currentIssueSearchLimit += DEFAULT_MENTION_GROUP_PAGE_SIZE;
695
+ }
696
+ if (needsMoreFiles || needsMoreIssues) {
697
+ this.clearTimer();
698
+ const requestId = ++this.requestId;
699
+ this.setState({
700
+ status: "loading",
701
+ query: this.currentQuery,
702
+ mode: "results",
703
+ filter: this.currentFilter,
704
+ categories: buildBrowseCategories(),
705
+ groups: this.groupsFromRawGroups(),
706
+ error: null
707
+ });
708
+ void this.runSearch({
709
+ workspaceId: this.activeWorkspaceId,
710
+ currentUserId: this.currentUserId,
711
+ query: this.currentQuery,
712
+ requestId
713
+ });
714
+ return;
715
+ }
716
+ this.setState({
717
+ status: "ready",
718
+ query: this.currentQuery,
719
+ mode: "results",
720
+ filter: this.currentFilter,
721
+ categories: buildBrowseCategories(),
722
+ groups: this.groupsFromRawGroups(),
723
+ error: null
724
+ });
725
+ }
726
+ close() {
727
+ this.clearTimer();
728
+ this.requestId += 1;
729
+ this.currentFilter = "all";
730
+ this.resetAgentGeneratedBrowsePath();
731
+ this.resetExpandedCounts();
732
+ this.resetSearchLimits();
733
+ this.rawGroups = {
734
+ apps: [],
735
+ opened_files: [],
736
+ agent_generated_files: [],
737
+ my_sessions: [],
738
+ collab_sessions: [],
739
+ issues: []
740
+ };
741
+ this.totalCounts.apps = 0;
742
+ this.totalCounts.opened_files = 0;
743
+ this.totalCounts.agent_generated_files = 0;
744
+ this.totalCounts.my_sessions = 0;
745
+ this.totalCounts.collab_sessions = 0;
746
+ this.totalCounts.issues = 0;
747
+ this.currentQuery = "";
748
+ this.setState({
749
+ status: "idle",
750
+ query: "",
751
+ mode: "browse",
752
+ filter: "all",
753
+ categories: buildBrowseCategories(),
754
+ groups: [],
755
+ error: null
756
+ });
757
+ }
758
+ dispose() {
759
+ this.disposed = true;
760
+ this.clearTimer();
761
+ this.listeners.clear();
762
+ this.requestId += 1;
763
+ }
764
+ startBrowseModeFetch(filter) {
765
+ if (!this.activeWorkspaceId || !shouldPrefetchBrowseFilter(filter)) {
766
+ this.rawGroups = {
767
+ apps: [],
768
+ opened_files: [],
769
+ agent_generated_files: [],
770
+ my_sessions: [],
771
+ collab_sessions: [],
772
+ issues: []
773
+ };
774
+ this.emitBrowseState("ready");
775
+ return;
776
+ }
777
+ this.clearTimer();
778
+ const requestId = ++this.requestId;
779
+ this.rawGroups = {
780
+ apps: [],
781
+ opened_files: [],
782
+ agent_generated_files: [],
783
+ my_sessions: [],
784
+ collab_sessions: [],
785
+ issues: []
786
+ };
787
+ this.emitBrowseState("loading");
788
+ void this.runBrowseSearch({
789
+ workspaceId: this.activeWorkspaceId,
790
+ currentUserId: this.currentUserId,
791
+ requestId,
792
+ filter
793
+ });
794
+ }
795
+ async runSearch(input) {
796
+ const startedAt = this.diagnosticNow();
797
+ const providerDiagnostics = [];
798
+ try {
799
+ const [fileItems, appItems, issueItems, sessionItems] = await Promise.all(
800
+ [
801
+ this.queryProviderMentionItemsById({
802
+ providerId: FILE_PROVIDER_ID2,
803
+ workspaceId: input.workspaceId,
804
+ currentUserId: input.currentUserId,
805
+ query: input.query,
806
+ limit: this.currentFileSearchLimit,
807
+ diagnostics: providerDiagnostics
808
+ }),
809
+ this.queryProviderMentionItemsById({
810
+ providerId: WORKSPACE_APP_PROVIDER_ID2,
811
+ workspaceId: input.workspaceId,
812
+ currentUserId: input.currentUserId,
813
+ query: input.query,
814
+ limit: DEFAULT_MENTION_GROUP_PAGE_SIZE,
815
+ diagnostics: providerDiagnostics
816
+ }),
817
+ this.queryProviderMentionItemsById({
818
+ providerId: WORKSPACE_ISSUE_PROVIDER_ID2,
819
+ workspaceId: input.workspaceId,
820
+ currentUserId: input.currentUserId,
821
+ query: input.query,
822
+ limit: this.currentIssueSearchLimit,
823
+ diagnostics: providerDiagnostics
824
+ }),
825
+ this.queryProviderMentionItemsById({
826
+ providerId: AGENT_SESSION_PROVIDER_ID2,
827
+ workspaceId: input.workspaceId,
828
+ currentUserId: input.currentUserId,
829
+ query: input.query,
830
+ limit: DEFAULT_SESSION_LIMIT,
831
+ diagnostics: providerDiagnostics
832
+ })
833
+ ]
834
+ );
835
+ if (!this.canApply(input.requestId, input.workspaceId, input.query)) {
836
+ return;
837
+ }
838
+ this.rawGroups = {
839
+ apps: appItems.filter((item) => item.kind === "workspace-app"),
840
+ opened_files: fileItems.filter((item) => item.kind === "file"),
841
+ agent_generated_files: [],
842
+ my_sessions: sessionItems.filter(
843
+ (item) => item.kind === "session" && item.scope === "my_sessions"
844
+ ),
845
+ collab_sessions: sessionItems.filter(
846
+ (item) => item.kind === "session" && item.scope === "collab_sessions"
847
+ ),
848
+ issues: issueItems.filter((item) => item.kind === "workspace-issue")
849
+ };
850
+ this.totalCounts.apps = this.rawGroups.apps.length;
851
+ this.totalCounts.opened_files = this.rawGroups.opened_files.length;
852
+ this.totalCounts.agent_generated_files = 0;
853
+ this.totalCounts.my_sessions = this.rawGroups.my_sessions.length;
854
+ this.totalCounts.collab_sessions = this.rawGroups.collab_sessions.length;
855
+ this.totalCounts.issues = this.rawGroups.issues.length;
856
+ const groups = this.groupsFromRawGroups();
857
+ this.setState({
858
+ status: "ready",
859
+ query: input.query,
860
+ mode: "results",
861
+ filter: this.currentFilter,
862
+ categories: buildBrowseCategories(),
863
+ groups,
864
+ error: null
865
+ });
866
+ this.logSearchDiagnostic({
867
+ filter: this.currentFilter,
868
+ groups,
869
+ mode: "results",
870
+ providerDiagnostics,
871
+ query: input.query,
872
+ requestId: input.requestId,
873
+ startedAt,
874
+ status: "ready",
875
+ workspaceId: input.workspaceId
876
+ });
877
+ } catch (error) {
878
+ if (!this.canApply(input.requestId, input.workspaceId, input.query)) {
879
+ return;
880
+ }
881
+ this.setState({
882
+ status: "error",
883
+ query: input.query,
884
+ mode: "results",
885
+ filter: this.currentFilter,
886
+ categories: buildBrowseCategories(),
887
+ groups: [],
888
+ error: error instanceof Error ? error.message : String(error)
889
+ });
890
+ this.logSearchDiagnostic({
891
+ error,
892
+ filter: this.currentFilter,
893
+ groups: [],
894
+ mode: "results",
895
+ providerDiagnostics,
896
+ query: input.query,
897
+ requestId: input.requestId,
898
+ startedAt,
899
+ status: "error",
900
+ workspaceId: input.workspaceId
901
+ });
902
+ }
903
+ }
904
+ async runBrowseSearch(input) {
905
+ const startedAt = this.diagnosticNow();
906
+ const providerDiagnostics = [];
907
+ try {
908
+ if (input.filter === "file") {
909
+ const [fileItems, agentGeneratedFileItems] = await Promise.all([
910
+ this.queryProviderMentionItemsById({
911
+ providerId: FILE_PROVIDER_ID2,
912
+ workspaceId: input.workspaceId,
913
+ currentUserId: input.currentUserId,
914
+ query: "",
915
+ limit: this.fileLimit,
916
+ diagnostics: providerDiagnostics
917
+ }),
918
+ this.queryProviderMentionItemsById({
919
+ providerId: AGENT_GENERATED_FILE_PROVIDER_ID2,
920
+ workspaceId: input.workspaceId,
921
+ currentUserId: input.currentUserId,
922
+ query: "",
923
+ limit: this.fileLimit,
924
+ diagnostics: providerDiagnostics
925
+ })
926
+ ]);
927
+ if (!this.canApply(input.requestId, input.workspaceId, "")) {
928
+ return;
929
+ }
930
+ this.rawGroups = {
931
+ apps: [],
932
+ opened_files: fileItems.filter((item) => item.kind === "file"),
933
+ agent_generated_files: agentGeneratedFileItems.filter(
934
+ (item) => item.kind === "file"
935
+ ),
936
+ my_sessions: [],
937
+ collab_sessions: [],
938
+ issues: []
939
+ };
940
+ this.totalCounts.apps = 0;
941
+ this.totalCounts.opened_files = this.rawGroups.opened_files.length;
942
+ this.totalCounts.agent_generated_files = this.rawGroups.agent_generated_files.length;
943
+ this.totalCounts.my_sessions = 0;
944
+ this.totalCounts.collab_sessions = 0;
945
+ this.totalCounts.issues = 0;
946
+ } else if (input.filter === "app") {
947
+ const appItems = await this.queryProviderMentionItemsById({
948
+ providerId: WORKSPACE_APP_PROVIDER_ID2,
949
+ workspaceId: input.workspaceId,
950
+ currentUserId: input.currentUserId,
951
+ query: "",
952
+ limit: DEFAULT_MENTION_GROUP_PAGE_SIZE,
953
+ diagnostics: providerDiagnostics
954
+ });
955
+ if (!this.canApply(input.requestId, input.workspaceId, "")) {
956
+ return;
957
+ }
958
+ this.rawGroups = {
959
+ apps: appItems.filter((item) => item.kind === "workspace-app"),
960
+ opened_files: [],
961
+ agent_generated_files: [],
962
+ my_sessions: [],
963
+ collab_sessions: [],
964
+ issues: []
965
+ };
966
+ this.totalCounts.apps = this.rawGroups.apps.length;
967
+ this.totalCounts.opened_files = 0;
968
+ this.totalCounts.agent_generated_files = 0;
969
+ this.totalCounts.my_sessions = 0;
970
+ this.totalCounts.collab_sessions = 0;
971
+ this.totalCounts.issues = 0;
972
+ } else if (input.filter === "issue") {
973
+ const issueItems = await this.queryProviderMentionItemsById({
974
+ providerId: WORKSPACE_ISSUE_PROVIDER_ID2,
975
+ workspaceId: input.workspaceId,
976
+ currentUserId: input.currentUserId,
977
+ query: "",
978
+ limit: this.currentIssueSearchLimit,
979
+ diagnostics: providerDiagnostics
980
+ });
981
+ if (!this.canApply(input.requestId, input.workspaceId, "")) {
982
+ return;
983
+ }
984
+ this.rawGroups = {
985
+ apps: [],
986
+ opened_files: [],
987
+ agent_generated_files: [],
988
+ my_sessions: [],
989
+ collab_sessions: [],
990
+ issues: issueItems.filter((item) => item.kind === "workspace-issue")
991
+ };
992
+ this.totalCounts.apps = 0;
993
+ this.totalCounts.opened_files = 0;
994
+ this.totalCounts.agent_generated_files = 0;
995
+ this.totalCounts.my_sessions = 0;
996
+ this.totalCounts.collab_sessions = 0;
997
+ this.totalCounts.issues = this.rawGroups.issues.length;
998
+ } else if (input.filter === "session") {
999
+ const sessionItems = await this.queryProviderMentionItemsById({
1000
+ providerId: AGENT_SESSION_PROVIDER_ID2,
1001
+ workspaceId: input.workspaceId,
1002
+ currentUserId: input.currentUserId,
1003
+ query: "",
1004
+ limit: DEFAULT_SESSION_LIMIT,
1005
+ diagnostics: providerDiagnostics
1006
+ });
1007
+ if (!this.canApply(input.requestId, input.workspaceId, "")) {
1008
+ return;
1009
+ }
1010
+ const sessionMentionItems = sessionItems.filter(
1011
+ (item) => item.kind === "session"
1012
+ );
1013
+ const mySessionItems = sessionMentionItems.filter(
1014
+ (item) => input.currentUserId ? item.scope === "my_sessions" : true
1015
+ ).map(
1016
+ (item) => item.scope === "my_sessions" ? item : { ...item, scope: "my_sessions" }
1017
+ );
1018
+ this.rawGroups = {
1019
+ apps: [],
1020
+ opened_files: [],
1021
+ agent_generated_files: [],
1022
+ my_sessions: mySessionItems,
1023
+ collab_sessions: [],
1024
+ issues: []
1025
+ };
1026
+ this.totalCounts.apps = 0;
1027
+ this.totalCounts.opened_files = 0;
1028
+ this.totalCounts.agent_generated_files = 0;
1029
+ this.totalCounts.my_sessions = this.rawGroups.my_sessions.length;
1030
+ this.totalCounts.collab_sessions = this.rawGroups.collab_sessions.length;
1031
+ this.totalCounts.issues = 0;
1032
+ } else {
1033
+ const [
1034
+ appItems,
1035
+ fileItems,
1036
+ agentGeneratedFileItems,
1037
+ issueItems,
1038
+ sessionItems
1039
+ ] = await Promise.all([
1040
+ this.queryProviderMentionItemsById({
1041
+ providerId: WORKSPACE_APP_PROVIDER_ID2,
1042
+ workspaceId: input.workspaceId,
1043
+ currentUserId: input.currentUserId,
1044
+ query: "",
1045
+ limit: DEFAULT_MENTION_GROUP_PAGE_SIZE,
1046
+ diagnostics: providerDiagnostics
1047
+ }),
1048
+ this.queryProviderMentionItemsById({
1049
+ providerId: FILE_PROVIDER_ID2,
1050
+ workspaceId: input.workspaceId,
1051
+ currentUserId: input.currentUserId,
1052
+ query: "",
1053
+ limit: this.fileLimit,
1054
+ diagnostics: providerDiagnostics
1055
+ }),
1056
+ this.queryProviderMentionItemsById({
1057
+ providerId: AGENT_GENERATED_FILE_PROVIDER_ID2,
1058
+ workspaceId: input.workspaceId,
1059
+ currentUserId: input.currentUserId,
1060
+ query: "",
1061
+ limit: this.fileLimit,
1062
+ diagnostics: providerDiagnostics
1063
+ }),
1064
+ this.queryProviderMentionItemsById({
1065
+ providerId: WORKSPACE_ISSUE_PROVIDER_ID2,
1066
+ workspaceId: input.workspaceId,
1067
+ currentUserId: input.currentUserId,
1068
+ query: "",
1069
+ limit: this.currentIssueSearchLimit,
1070
+ diagnostics: providerDiagnostics
1071
+ }),
1072
+ this.queryProviderMentionItemsById({
1073
+ providerId: AGENT_SESSION_PROVIDER_ID2,
1074
+ workspaceId: input.workspaceId,
1075
+ currentUserId: input.currentUserId,
1076
+ query: "",
1077
+ limit: DEFAULT_SESSION_LIMIT,
1078
+ diagnostics: providerDiagnostics
1079
+ })
1080
+ ]);
1081
+ if (!this.canApply(input.requestId, input.workspaceId, "")) {
1082
+ return;
1083
+ }
1084
+ this.rawGroups = {
1085
+ apps: appItems.filter((item) => item.kind === "workspace-app"),
1086
+ opened_files: fileItems.filter((item) => item.kind === "file"),
1087
+ agent_generated_files: agentGeneratedFileItems.filter(
1088
+ (item) => item.kind === "file"
1089
+ ),
1090
+ my_sessions: sessionItems.filter(
1091
+ (item) => item.kind === "session" && item.scope === "my_sessions"
1092
+ ),
1093
+ collab_sessions: sessionItems.filter(
1094
+ (item) => item.kind === "session" && item.scope === "collab_sessions"
1095
+ ),
1096
+ issues: issueItems.filter((item) => item.kind === "workspace-issue")
1097
+ };
1098
+ this.totalCounts.apps = this.rawGroups.apps.length;
1099
+ this.totalCounts.opened_files = this.rawGroups.opened_files.length;
1100
+ this.totalCounts.agent_generated_files = this.rawGroups.agent_generated_files.length;
1101
+ this.totalCounts.my_sessions = this.rawGroups.my_sessions.length;
1102
+ this.totalCounts.collab_sessions = this.rawGroups.collab_sessions.length;
1103
+ this.totalCounts.issues = this.rawGroups.issues.length;
1104
+ }
1105
+ const groups = this.groupsFromRawGroups();
1106
+ this.setState({
1107
+ status: "ready",
1108
+ query: "",
1109
+ mode: "browse",
1110
+ filter: this.currentFilter,
1111
+ categories: buildBrowseCategories(),
1112
+ groups,
1113
+ error: null
1114
+ });
1115
+ this.logSearchDiagnostic({
1116
+ filter: this.currentFilter,
1117
+ groups,
1118
+ mode: "browse",
1119
+ providerDiagnostics,
1120
+ query: "",
1121
+ requestId: input.requestId,
1122
+ startedAt,
1123
+ status: "ready",
1124
+ workspaceId: input.workspaceId
1125
+ });
1126
+ } catch (error) {
1127
+ if (!this.canApply(input.requestId, input.workspaceId, "")) {
1128
+ return;
1129
+ }
1130
+ this.setState({
1131
+ status: "error",
1132
+ query: "",
1133
+ mode: "browse",
1134
+ filter: this.currentFilter,
1135
+ categories: buildBrowseCategories(),
1136
+ groups: [],
1137
+ error: error instanceof Error ? error.message : String(error)
1138
+ });
1139
+ this.logSearchDiagnostic({
1140
+ error,
1141
+ filter: this.currentFilter,
1142
+ groups: [],
1143
+ mode: "browse",
1144
+ providerDiagnostics,
1145
+ query: "",
1146
+ requestId: input.requestId,
1147
+ startedAt,
1148
+ status: "error",
1149
+ workspaceId: input.workspaceId
1150
+ });
1151
+ }
1152
+ }
1153
+ async queryProviderMentionItems(input) {
1154
+ const items = await input.provider.query({
1155
+ keyword: input.query,
1156
+ maxResults: input.limit,
1157
+ abortSignal: input.abortSignal,
1158
+ trigger: "@",
1159
+ context: {
1160
+ metadata: {
1161
+ currentUserId: input.currentUserId,
1162
+ sessionCwd: this.currentSessionCwd || void 0,
1163
+ target: "agent-gui",
1164
+ workspaceId: input.workspaceId
1165
+ }
1166
+ }
1167
+ });
1168
+ if (input.abortSignal.aborted) {
1169
+ return [];
1170
+ }
1171
+ const mentionItems = await Promise.all(
1172
+ items.map(async (item) => {
1173
+ const mentionItem = providerItemToAgentMentionItem({
1174
+ currentUserId: input.currentUserId,
1175
+ insertResult: input.provider.toInsertResult(item),
1176
+ label: input.provider.getItemLabel(item),
1177
+ providerId: input.provider.id,
1178
+ subtitle: input.provider.getItemSubtitle?.(item) ?? "",
1179
+ workspaceId: input.workspaceId
1180
+ });
1181
+ if (!mentionItem || mentionItem.kind !== "file") {
1182
+ return mentionItem;
1183
+ }
1184
+ const thumbnailUrl = await Promise.resolve(
1185
+ input.provider.getItemThumbnailUrl?.(item) ?? null
1186
+ ).catch(() => null);
1187
+ const resolvedThumbnailUrl = resolveAgentMentionFileThumbnailUrl({
1188
+ ...mentionItem,
1189
+ thumbnailUrl
1190
+ });
1191
+ if (!resolvedThumbnailUrl) {
1192
+ return mentionItem;
1193
+ }
1194
+ return {
1195
+ ...mentionItem,
1196
+ thumbnailUrl: resolvedThumbnailUrl
1197
+ };
1198
+ })
1199
+ );
1200
+ return mentionItems.filter(
1201
+ (item) => item !== null
1202
+ );
1203
+ }
1204
+ async queryProviderMentionItemsById(input) {
1205
+ const provider = this.contextMentionProviders.get(input.providerId);
1206
+ return queryAgentMentionProviderWithDiagnostics({
1207
+ diagnosticNow: this.diagnosticNow,
1208
+ diagnostics: input.diagnostics,
1209
+ fallback: [],
1210
+ providerId: input.providerId,
1211
+ providerTimeoutMs: this.providerTimeoutMs,
1212
+ query: provider ? (abortSignal) => this.queryProviderMentionItems({
1213
+ provider,
1214
+ workspaceId: input.workspaceId,
1215
+ currentUserId: input.currentUserId,
1216
+ query: input.query,
1217
+ limit: input.limit,
1218
+ abortSignal
1219
+ }) : null,
1220
+ resultCount: (result) => result.length
1221
+ });
1222
+ }
1223
+ logSearchDiagnostic(input) {
1224
+ emitAgentMentionSearchDiagnostic({
1225
+ debounceMs: this.debounceMs,
1226
+ diagnosticInfoLogger: this.diagnosticInfoLogger,
1227
+ diagnosticNow: this.diagnosticNow,
1228
+ diagnosticSlowThresholdMs: this.diagnosticSlowThresholdMs,
1229
+ error: input.error,
1230
+ filter: input.filter,
1231
+ groups: input.groups,
1232
+ mode: input.mode,
1233
+ providerDiagnostics: input.providerDiagnostics,
1234
+ providerTimeoutMs: this.providerTimeoutMs,
1235
+ query: input.query,
1236
+ requestId: input.requestId,
1237
+ startedAt: input.startedAt,
1238
+ status: input.status,
1239
+ workspaceId: input.workspaceId
1240
+ });
1241
+ }
1242
+ groupsFromRawGroups() {
1243
+ const orderedGroupIds = groupIdsForFilter(this.currentFilter);
1244
+ const groups = orderedGroupIds.map((groupId) => {
1245
+ const rawItems = resolveMentionGroupItems(groupId, this.rawGroups);
1246
+ const items = groupId === "agent_generated_files" ? presentAgentGeneratedFileMentionItems({
1247
+ files: rawItems,
1248
+ browsePath: this.agentGeneratedBrowsePath,
1249
+ query: this.currentQuery
1250
+ }) : rawItems;
1251
+ if (items.length === 0) {
1252
+ if (!shouldShowEmptyGroup(
1253
+ groupId,
1254
+ this.currentFilter,
1255
+ this.currentQuery
1256
+ )) {
1257
+ return null;
1258
+ }
1259
+ return buildEmptyGroup(groupId, this.currentQuery);
1260
+ }
1261
+ const pageSize = mentionGroupPageSize(this.currentFilter, groupId);
1262
+ const visibleCount = Math.min(
1263
+ items.length,
1264
+ this.expandedCounts[groupId] ?? pageSize
1265
+ );
1266
+ const totalCount = resolveMentionGroupTotalCount(
1267
+ groupId,
1268
+ this.totalCounts,
1269
+ items.length
1270
+ );
1271
+ return {
1272
+ id: groupId,
1273
+ items: items.slice(0, visibleCount),
1274
+ totalCount,
1275
+ visibleCount,
1276
+ hasMore: items.length > visibleCount || (groupId === "opened_files" || groupId === "files" || groupId === "agent_generated_files") && items.length >= this.currentFileSearchLimit || totalCount > visibleCount
1277
+ };
1278
+ }).filter((group) => group !== null);
1279
+ return orderMentionGroupsForFilter({
1280
+ filter: this.currentFilter,
1281
+ groups,
1282
+ query: this.currentQuery
1283
+ });
1284
+ }
1285
+ emitBrowseState(status) {
1286
+ this.setState({
1287
+ status,
1288
+ query: "",
1289
+ mode: "browse",
1290
+ filter: this.currentFilter,
1291
+ categories: buildBrowseCategories(),
1292
+ groups: [],
1293
+ error: null
1294
+ });
1295
+ }
1296
+ canApply(requestId, workspaceId, query) {
1297
+ return !this.disposed && requestId === this.requestId && workspaceId === this.activeWorkspaceId && query === this.currentQuery;
1298
+ }
1299
+ clearTimer() {
1300
+ if (this.timer !== null) {
1301
+ clearTimeout(this.timer);
1302
+ this.timer = null;
1303
+ }
1304
+ }
1305
+ resetExpandedCounts() {
1306
+ for (const groupId of [
1307
+ "files",
1308
+ "opened_files",
1309
+ "agent_generated_files",
1310
+ "my_sessions",
1311
+ "collab_sessions",
1312
+ "apps",
1313
+ "issues"
1314
+ ]) {
1315
+ this.expandedCounts[groupId] = mentionGroupPageSize(
1316
+ this.currentFilter,
1317
+ groupId
1318
+ );
1319
+ }
1320
+ }
1321
+ resetSearchLimits() {
1322
+ this.currentFileSearchLimit = this.fileLimit;
1323
+ this.currentIssueSearchLimit = this.issueLimit;
1324
+ }
1325
+ resetAgentGeneratedBrowsePath() {
1326
+ this.agentGeneratedBrowsePath = null;
1327
+ }
1328
+ setState(state) {
1329
+ this.state = state;
1330
+ for (const listener of this.listeners) {
1331
+ listener(state);
1332
+ }
1333
+ }
1334
+ };
1335
+ function orderMentionGroupsForFilter(input) {
1336
+ if (input.filter !== "all") {
1337
+ return input.groups;
1338
+ }
1339
+ const query = normalizeQuery(input.query).toLowerCase();
1340
+ return input.groups.map((group, index) => ({
1341
+ group,
1342
+ hasItems: group.items.length > 0,
1343
+ index,
1344
+ score: mentionGroupBestMatchScore(group, query)
1345
+ })).sort((left, right) => {
1346
+ if (left.hasItems !== right.hasItems) {
1347
+ return left.hasItems ? -1 : 1;
1348
+ }
1349
+ if (query && left.score !== right.score) {
1350
+ return right.score - left.score;
1351
+ }
1352
+ return left.index - right.index;
1353
+ }).map((entry) => entry.group);
1354
+ }
1355
+ function mentionGroupBestMatchScore(group, query) {
1356
+ if (!query) {
1357
+ return 0;
1358
+ }
1359
+ return group.items.reduce(
1360
+ (bestScore, item) => Math.max(bestScore, mentionItemMatchScore(item, query)),
1361
+ 0
1362
+ );
1363
+ }
1364
+ function mentionItemMatchScore(item, query) {
1365
+ const primary = [];
1366
+ const secondary = [];
1367
+ let kindBoost = 0;
1368
+ if (item.kind === "workspace-app") {
1369
+ kindBoost = 8;
1370
+ primary.push(item.name, item.appId, item.targetId);
1371
+ secondary.push(item.description ?? "");
1372
+ } else if (item.kind === "file") {
1373
+ primary.push(item.name);
1374
+ secondary.push(item.path, item.directoryPath);
1375
+ } else if (item.kind === "session") {
1376
+ primary.push(item.title);
1377
+ secondary.push(
1378
+ item.name,
1379
+ item.initiatorName,
1380
+ item.agentName,
1381
+ item.inputPreview ?? "",
1382
+ item.summaryPreview ?? ""
1383
+ );
1384
+ } else if (item.kind === "workspace-issue") {
1385
+ primary.push(item.title, item.name);
1386
+ secondary.push(
1387
+ item.creatorName ?? "",
1388
+ item.status ?? "",
1389
+ item.contentPreview ?? ""
1390
+ );
1391
+ } else if (item.kind === "workspace-app-factory") {
1392
+ primary.push(item.name, item.jobId, item.targetId);
1393
+ secondary.push(item.action ?? "", item.contextPath ?? "");
1394
+ }
1395
+ const primaryScore = maxTextMatchScore(primary, query, {
1396
+ contains: 60,
1397
+ exact: 100,
1398
+ prefix: 90,
1399
+ wordPrefix: 80
1400
+ });
1401
+ const secondaryScore = maxTextMatchScore(secondary, query, {
1402
+ contains: 25,
1403
+ exact: 60,
1404
+ prefix: 50,
1405
+ wordPrefix: 40
1406
+ });
1407
+ const score = Math.max(primaryScore, secondaryScore);
1408
+ return score > 0 ? score + kindBoost : 0;
1409
+ }
1410
+ function maxTextMatchScore(values, query, scores) {
1411
+ return values.reduce(
1412
+ (bestScore, value) => Math.max(bestScore, textMatchScore(value, query, scores)),
1413
+ 0
1414
+ );
1415
+ }
1416
+ function textMatchScore(value, query, scores) {
1417
+ const normalized = normalizeQuery(value).toLowerCase();
1418
+ if (!normalized) {
1419
+ return 0;
1420
+ }
1421
+ if (normalized === query) {
1422
+ return scores.exact;
1423
+ }
1424
+ if (normalized.startsWith(query)) {
1425
+ return scores.prefix;
1426
+ }
1427
+ if (normalized.split(/[^a-z0-9]+/i).some((word) => word.startsWith(query))) {
1428
+ return scores.wordPrefix;
1429
+ }
1430
+ return normalized.includes(query) ? scores.contains : 0;
1431
+ }
1432
+ function providerItemToAgentMentionItem(input) {
1433
+ const label = compactText(input.label);
1434
+ if (!label) {
1435
+ return null;
1436
+ }
1437
+ if (input.insertResult.kind === "markdown-link") {
1438
+ const href = input.insertResult.href.trim();
1439
+ return {
1440
+ kind: "file",
1441
+ href,
1442
+ path: href,
1443
+ name: label,
1444
+ entryKind: href.endsWith("/") ? "directory" : "unknown",
1445
+ directoryPath: dirnameFromProviderWorkspaceFileHref(href)
1446
+ };
1447
+ }
1448
+ if (input.insertResult.kind !== "mention") {
1449
+ return null;
1450
+ }
1451
+ const mention = input.insertResult.mention;
1452
+ const targetId = mention.entityId.trim();
1453
+ if (!targetId) {
1454
+ return null;
1455
+ }
1456
+ const scope = normalizeMentionScope(mention.scope);
1457
+ const presentation = mention.presentation ?? {};
1458
+ const workspaceId = scope.workspaceId || input.workspaceId;
1459
+ if (input.providerId === FILE_PROVIDER_ID2 || input.providerId === AGENT_GENERATED_FILE_PROVIDER_ID2) {
1460
+ return {
1461
+ kind: "file",
1462
+ href: buildAgentGenericMentionHref(input.providerId, targetId, scope),
1463
+ path: targetId,
1464
+ name: label,
1465
+ entryKind: targetId.endsWith("/") ? "directory" : "unknown",
1466
+ directoryPath: dirnameFromProviderWorkspaceFileHref(targetId),
1467
+ thumbnailUrl: presentation.thumbnailUrl?.trim() || void 0
1468
+ };
1469
+ }
1470
+ if (input.providerId === WORKSPACE_ISSUE_PROVIDER_ID2) {
1471
+ return {
1472
+ kind: "workspace-issue",
1473
+ href: buildAgentWorkspaceIssueMentionHref(workspaceId, targetId, {
1474
+ topicId: scope.topicId
1475
+ }),
1476
+ workspaceId,
1477
+ targetId,
1478
+ topicId: scope.topicId,
1479
+ name: label,
1480
+ title: label,
1481
+ status: presentation.status?.trim() || void 0,
1482
+ contentPreview: compactText(presentation.description) || compactText(input.subtitle) || void 0
1483
+ };
1484
+ }
1485
+ if (input.providerId === WORKSPACE_APP_PROVIDER_ID2) {
1486
+ const appId = targetId;
1487
+ return {
1488
+ kind: "workspace-app",
1489
+ href: buildAgentWorkspaceAppMentionHref(workspaceId, appId),
1490
+ workspaceId,
1491
+ targetId: appId,
1492
+ appId,
1493
+ name: label,
1494
+ description: compactText(presentation.description) || compactText(presentation.subtitle) || compactText(input.subtitle) || void 0,
1495
+ iconUrl: presentation.iconUrl?.trim() || void 0
1496
+ };
1497
+ }
1498
+ if (input.providerId === AGENT_SESSION_PROVIDER_ID2) {
1499
+ const agentName = presentation.subtitle?.trim() || "";
1500
+ const title = normalizeAgentSessionMentionTitle(label) || label;
1501
+ const description = compactText(presentation.description);
1502
+ const summaryPreview = description || compactText(input.subtitle) || void 0;
1503
+ return {
1504
+ kind: "session",
1505
+ href: buildAgentSessionMentionHref(workspaceId, targetId),
1506
+ workspaceId,
1507
+ targetId,
1508
+ name: label,
1509
+ title,
1510
+ scope: mentionSessionScope({
1511
+ currentUserId: input.currentUserId,
1512
+ rawScope: scope.scope,
1513
+ userId: scope.userId
1514
+ }),
1515
+ initiatorName: "",
1516
+ agentName,
1517
+ status: presentation.status?.trim() || void 0,
1518
+ inputPreview: description || void 0,
1519
+ summaryPreview
1520
+ };
1521
+ }
1522
+ return null;
1523
+ }
1524
+ function normalizeMentionScope(scope) {
1525
+ return Object.fromEntries(
1526
+ Object.entries(scope ?? {}).map(([key, value]) => [key.trim(), value.trim()]).filter(([key, value]) => key.length > 0 && value.length > 0)
1527
+ );
1528
+ }
1529
+ function mentionSessionScope(input) {
1530
+ const rawScope = input.rawScope?.trim() ?? "";
1531
+ if (rawScope === "my_sessions" || rawScope === "collab_sessions") {
1532
+ return rawScope;
1533
+ }
1534
+ return input.userId && input.userId === input.currentUserId ? "my_sessions" : "collab_sessions";
1535
+ }
1536
+ function dirnameFromProviderWorkspaceFileHref(href) {
1537
+ const normalized = href.replace(/\/+$/, "");
1538
+ const index = normalized.lastIndexOf("/");
1539
+ if (index <= 0) {
1540
+ return "/";
1541
+ }
1542
+ return normalized.slice(0, index);
1543
+ }
1544
+
1545
+ // agent-gui/agentGuiNode/AgentFileMentionPalette.tsx
1546
+ import {
1547
+ normalizeAgentActivityDisplayStatus
1548
+ } from "@tutti-os/agent-activity-core";
1549
+ import {
1550
+ MentionPalette,
1551
+ flattenMentionPaletteEntries,
1552
+ issueMentionStatusTone,
1553
+ renderMentionRow
1554
+ } from "@tutti-os/ui-rich-text/at-panel";
1555
+
1556
+ // shared/roomIssueStatusLabel.ts
1557
+ function roomIssueStatusLabel(status, t) {
1558
+ const translateFn = t ?? translate;
1559
+ switch (status) {
1560
+ case "not_started":
1561
+ return translateFn("agentHost.roomIssueNode.issueStatusNotStarted");
1562
+ case "running":
1563
+ return translateFn("agentHost.roomIssueNode.issueStatusRunning");
1564
+ case "in_progress":
1565
+ return translateFn("agentHost.roomIssueNode.issueStatusInProgress");
1566
+ case "pending_acceptance":
1567
+ return translateFn(
1568
+ "agentHost.roomIssueNode.issueStatusPendingAcceptance"
1569
+ );
1570
+ case "completed":
1571
+ return translateFn("agentHost.roomIssueNode.issueStatusCompleted");
1572
+ case "failed":
1573
+ return translateFn("agentHost.roomIssueNode.issueStatusFailed");
1574
+ case "canceled":
1575
+ return translateFn("agentHost.roomIssueNode.issueStatusCanceled");
1576
+ default:
1577
+ return status || translateFn("agentHost.roomIssueNode.issueStatusUnknown");
1578
+ }
1579
+ }
1580
+
1581
+ // agent-gui/agentGuiNode/AgentFileMentionPalette.tsx
1582
+ import { jsx, jsxs } from "react/jsx-runtime";
1583
+ var AGENT_MENTION_PALETTE_THEME = {
1584
+ classNames: {
1585
+ palette: "agent-gui-node__mention-palette",
1586
+ header: "agent-gui-node__mention-palette-header",
1587
+ footer: "agent-gui-node__mention-palette-footer",
1588
+ tabs: "agent-gui-node__mention-palette-tabs",
1589
+ scrollRegion: "agent-gui-node__mention-palette-scroll-region",
1590
+ scrollbar: "workspace-agents-status-panel__scrollbar agent-gui-node__mention-palette-scrollbar",
1591
+ scrollbarThumb: "workspace-agents-status-panel__scrollbar-thumb",
1592
+ hint: "agent-gui-node__mention-palette-hint",
1593
+ hintItem: "agent-gui-node__mention-palette-hint-item",
1594
+ hintButton: "agent-gui-node__mention-palette-hint-button",
1595
+ hintSeparator: "agent-gui-node__mention-palette-hint-separator",
1596
+ shortcut: "agent-gui-node__mention-palette-shortcut",
1597
+ shortcutArrow: "agent-gui-node__mention-palette-shortcut--arrow",
1598
+ shortcutButton: "agent-gui-node__mention-palette-shortcut-button",
1599
+ shortcutGroup: "agent-gui-node__mention-palette-shortcut-group"
1600
+ },
1601
+ testIds: {
1602
+ emptyState: "agent-gui-mention-palette-empty-state",
1603
+ hint: "agent-gui-mention-palette-hint",
1604
+ scrollbar: "agent-gui-mention-palette-scrollbar",
1605
+ loadingSpinner: "agent-mention-loading-spinner"
1606
+ },
1607
+ groupDividerAttribute: "data-agent-mention-group-divider"
1608
+ };
1609
+ var AGENT_MENTION_ROW_CLASS_NAMES = {
1610
+ fileIcon: "agent-gui-node__mention-file-icon",
1611
+ fileThumb: "agent-gui-node__mention-file-thumb",
1612
+ kindIcon: "tsh-agent-object-token__kind-icon",
1613
+ avatarImgUserPlaceholder: "workspace-agents-status-panel__avatar-img--user-placeholder"
1614
+ };
1615
+ function agentMentionItemKey(item) {
1616
+ return `${item.kind}:${item.kind === "file" ? agentGeneratedMentionItemKey(item) : item.targetId}`;
1617
+ }
1618
+ function flattenAgentMentionPaletteEntries(state) {
1619
+ return flattenMentionPaletteEntries(
1620
+ state,
1621
+ (item) => agentMentionItemKey(item)
1622
+ ).map((entry) => {
1623
+ if (entry.type === "item") {
1624
+ const item = entry.groupId !== void 0 && entry.itemIndex !== void 0 ? state.groups.find((group) => group.id === entry.groupId)?.items[entry.itemIndex] : void 0;
1625
+ return {
1626
+ key: entry.key,
1627
+ type: "item",
1628
+ groupId: entry.groupId,
1629
+ item
1630
+ };
1631
+ }
1632
+ return {
1633
+ key: entry.key,
1634
+ type: entry.type,
1635
+ categoryId: entry.categoryId,
1636
+ groupId: entry.groupId
1637
+ };
1638
+ });
1639
+ }
1640
+ function groupStartKeys(state) {
1641
+ if (state.mode === "browse") {
1642
+ return state.categories.map((category) => `category:${category.id}`);
1643
+ }
1644
+ return state.groups.map((group) => {
1645
+ const firstItem = group.items[0];
1646
+ if (firstItem) {
1647
+ return `${group.id}:${firstItem.kind}:${firstItem.kind === "file" ? firstItem.path : firstItem.targetId}`;
1648
+ }
1649
+ if (group.hasMore) {
1650
+ return `expand:${group.id}`;
1651
+ }
1652
+ return null;
1653
+ }).filter((key) => key !== null);
1654
+ }
1655
+ function AgentFileMentionPalette({
1656
+ state,
1657
+ highlightedKey,
1658
+ label,
1659
+ loadingLabel,
1660
+ emptyLabel,
1661
+ errorLabel,
1662
+ tabHintLabel,
1663
+ maxHeightPx,
1664
+ shouldCenterHighlightedItem = false,
1665
+ onHighlightChange,
1666
+ onSelectItem,
1667
+ onSelectCategory,
1668
+ onSelectFilter,
1669
+ onExpandGroup,
1670
+ onCycleFilter,
1671
+ onMoveSelection
1672
+ }) {
1673
+ "use memo";
1674
+ const filter = state.filter;
1675
+ const highlightedBrowseCategory = highlightedKey?.startsWith("category:") ? highlightedKey.slice("category:".length) : null;
1676
+ const browseDisplayFilter = isBrowseCategoryId(highlightedBrowseCategory) ? highlightedBrowseCategory : filter;
1677
+ const showBrowseHint = shouldShowBrowseSearchHint({
1678
+ browseFilter: filter,
1679
+ groups: state.groups,
1680
+ highlightedBrowseCategory,
1681
+ mode: state.mode
1682
+ });
1683
+ const categories = state.mode === "browse" ? state.categories : AGENT_MENTION_FILTER_TAB_ORDER.map((id) => ({
1684
+ id,
1685
+ label: agentMentionFilterLabel(id)
1686
+ }));
1687
+ const shellState = showBrowseHint ? { ...state, categories, groups: [] } : {
1688
+ ...state,
1689
+ categories,
1690
+ groups: state.groups.map(
1691
+ (group, index) => decorateMentionGroup(
1692
+ group,
1693
+ index,
1694
+ state.groups,
1695
+ filter,
1696
+ state.query
1697
+ )
1698
+ )
1699
+ };
1700
+ const emptyLabelForShell = showBrowseHint ? browseHintForFilter(browseDisplayFilter) : resolveMentionPaletteEmptyLabel({
1701
+ emptyLabel,
1702
+ filter,
1703
+ mode: state.mode,
1704
+ query: state.query
1705
+ });
1706
+ const showFileSearchMoreHint = shouldShowFileSearchMoreHint({
1707
+ filter,
1708
+ groups: state.groups,
1709
+ mode: state.mode,
1710
+ query: state.query
1711
+ });
1712
+ return /* @__PURE__ */ jsx(
1713
+ MentionPalette,
1714
+ {
1715
+ state: shellState,
1716
+ highlightedKey,
1717
+ getItemKey: agentMentionItemKey,
1718
+ renderItem: (item) => renderMentionRow(agentMentionItemToRowItem(item), {
1719
+ classNames: AGENT_MENTION_ROW_CLASS_NAMES,
1720
+ dataAttributeMode: "agent"
1721
+ }),
1722
+ labels: {
1723
+ loading: loadingLabel,
1724
+ empty: emptyLabelForShell,
1725
+ error: errorLabel,
1726
+ tabHint: tabHintLabel,
1727
+ listbox: label
1728
+ },
1729
+ hintLabels: {
1730
+ cycleFilter: translate("agentHost.agentGui.fileMentionSwitchCategory"),
1731
+ moveSelection: translate(
1732
+ "agentHost.agentGui.fileMentionSwitchSelection"
1733
+ )
1734
+ },
1735
+ maxHeightPx,
1736
+ scrollHighlightedIntoViewCentered: shouldCenterHighlightedItem,
1737
+ loadingBanner: /* @__PURE__ */ jsx(MentionPaletteLoadingBanner, { label: loadingLabel }),
1738
+ theme: AGENT_MENTION_PALETTE_THEME,
1739
+ renderListFooter: showFileSearchMoreHint ? () => /* @__PURE__ */ jsx(MentionFileSearchMoreHint, {}) : void 0,
1740
+ onHighlightChange,
1741
+ onSelectItem: (item) => onSelectItem(item),
1742
+ onSelectCategory: (categoryId) => onSelectCategory(categoryId),
1743
+ onSelectFilter: (nextFilter) => onSelectFilter(nextFilter),
1744
+ onExpandGroup: (groupId) => onExpandGroup(groupId),
1745
+ onCycleFilter: () => onCycleFilter(),
1746
+ onMoveSelection
1747
+ }
1748
+ );
1749
+ }
1750
+ var AgentContextMentionPalette = AgentFileMentionPalette;
1751
+ function decorateMentionGroup(group, index, groups, filter, query) {
1752
+ const groupId = group.id;
1753
+ const suppressChrome = shouldSuppressFileSearchGroupChrome(filter, query);
1754
+ const followsMySessions = groupId === "collab_sessions" && groups[index - 1]?.id === "my_sessions";
1755
+ const showLabel = shouldRenderMentionGroupLabel({
1756
+ filter,
1757
+ groupCount: groups.length,
1758
+ groupId,
1759
+ query
1760
+ });
1761
+ return {
1762
+ ...group,
1763
+ label: showLabel ? agentMentionGroupLabel(groupId) : void 0,
1764
+ emptyLabel: suppressChrome ? void 0 : agentMentionEmptyGroupLabel(groupId, query),
1765
+ expandLabel: group.hasMore ? translate("agentHost.agentGui.contextPickerExpandMore", {
1766
+ count: mentionGroupExpandCount(group, filter)
1767
+ }) : void 0,
1768
+ sectionClassName: followsMySessions ? "mt-2" : void 0,
1769
+ hideTopDivider: suppressChrome
1770
+ };
1771
+ }
1772
+ function MentionPaletteLoadingBanner({
1773
+ label
1774
+ }) {
1775
+ "use memo";
1776
+ return /* @__PURE__ */ jsxs(
1777
+ "div",
1778
+ {
1779
+ className: "flex items-center gap-2 border-b border-[var(--line-1)] px-3 py-2 text-[13px] font-medium text-[var(--text-secondary)]",
1780
+ "data-testid": "agent-mention-loading-banner",
1781
+ children: [
1782
+ /* @__PURE__ */ jsx(
1783
+ Spinner,
1784
+ {
1785
+ size: 14,
1786
+ className: "text-[var(--text-secondary)]",
1787
+ testId: "agent-mention-loading-spinner"
1788
+ }
1789
+ ),
1790
+ /* @__PURE__ */ jsx("span", { children: label })
1791
+ ]
1792
+ }
1793
+ );
1794
+ }
1795
+ function MentionFileSearchMoreHint() {
1796
+ "use memo";
1797
+ return /* @__PURE__ */ jsx(
1798
+ "p",
1799
+ {
1800
+ className: "px-3 pb-1 pt-2 text-center text-[13px] leading-5 text-[var(--text-tertiary)]",
1801
+ "data-agent-mention-file-search-hint": "true",
1802
+ children: translate("agentHost.agentGui.mentionFileSearchMoreHint")
1803
+ }
1804
+ );
1805
+ }
1806
+ function shouldSuppressFileSearchGroupChrome(filter, query) {
1807
+ return filter === "file" && query.trim().length > 0;
1808
+ }
1809
+ function resolveMentionPaletteEmptyLabel(input) {
1810
+ if (input.mode === "results" && input.filter === "file" && input.query.trim().length > 0) {
1811
+ return translate("agentHost.agentGui.mentionNoMatchingFiles");
1812
+ }
1813
+ return input.emptyLabel;
1814
+ }
1815
+ function shouldRenderMentionGroupLabel(input) {
1816
+ if (shouldSuppressFileSearchGroupChrome(input.filter, input.query)) {
1817
+ return false;
1818
+ }
1819
+ if (input.filter === "all" || input.groupCount !== 1) {
1820
+ return true;
1821
+ }
1822
+ return agentMentionGroupLabel(input.groupId) !== agentMentionFilterLabel(input.filter);
1823
+ }
1824
+ function agentMentionItemToRowItem(item) {
1825
+ if (item.kind === "file") {
1826
+ const visualKind = resolveAgentMentionFileVisualKind({
1827
+ entryKind: item.entryKind,
1828
+ href: item.href,
1829
+ mentionNavigation: item.mentionNavigation,
1830
+ name: item.name,
1831
+ path: item.path
1832
+ });
1833
+ const childCountLabel = item.mentionNavigation === "agent-generated-folder" && typeof item.childCount === "number" && item.childCount > 0 ? translate("agentHost.agentGui.mentionAgentGeneratedFolderFileCount", {
1834
+ count: item.childCount
1835
+ }) : null;
1836
+ return {
1837
+ kind: "file",
1838
+ name: item.name,
1839
+ visualKind,
1840
+ thumbnailUrl: resolveAgentMentionFileThumbnailUrl(item) ?? null,
1841
+ childCountLabel,
1842
+ entryKind: item.entryKind,
1843
+ mentionNavigation: item.mentionNavigation
1844
+ };
1845
+ }
1846
+ if (item.kind === "session") {
1847
+ return {
1848
+ kind: "session",
1849
+ participant: `${item.initiatorName} & ${item.agentName}`,
1850
+ summary: item.title,
1851
+ userAvatarUrl: item.initiatorAvatarUrl ?? null,
1852
+ userAvatarPlaceholderUrl,
1853
+ agentIconUrl: managedAgentRoundedIconUrl(
1854
+ mentionSessionAgentProvider(item) ?? item.agentName
1855
+ ),
1856
+ statusTag: agentSessionStatusTag(item.status)
1857
+ };
1858
+ }
1859
+ if (item.kind === "workspace-app") {
1860
+ return {
1861
+ kind: "app",
1862
+ name: item.name,
1863
+ description: item.description ?? null,
1864
+ iconUrl: item.iconUrl ?? null
1865
+ };
1866
+ }
1867
+ if (item.kind === "workspace-app-factory") {
1868
+ return {
1869
+ kind: "app-factory",
1870
+ name: item.name
1871
+ };
1872
+ }
1873
+ return {
1874
+ kind: "issue",
1875
+ title: item.title,
1876
+ creatorName: item.creatorName ?? null,
1877
+ statusTag: agentIssueStatusTag(item.status)
1878
+ };
1879
+ }
1880
+ function mentionSessionAgentProvider(item) {
1881
+ const queryStart = item.href.indexOf("?");
1882
+ if (queryStart < 0) {
1883
+ return null;
1884
+ }
1885
+ return new URLSearchParams(item.href.slice(queryStart + 1)).get("provider");
1886
+ }
1887
+ function agentSessionStatusTag(status) {
1888
+ if (!status) {
1889
+ return null;
1890
+ }
1891
+ const activityStatus = normalizeAgentActivityDisplayStatus(status);
1892
+ return {
1893
+ label: workspaceAgentActivityStatusLabel(activityStatus),
1894
+ tone: mentionStatusTone(activityStatus),
1895
+ pulse: activityStatus === "working" || activityStatus === "waiting",
1896
+ variant: "activity",
1897
+ dataStatus: activityStatus
1898
+ };
1899
+ }
1900
+ function agentIssueStatusTag(status) {
1901
+ if (!status) {
1902
+ return null;
1903
+ }
1904
+ return {
1905
+ label: roomIssueStatusLabel(status),
1906
+ tone: issueMentionStatusTone(status),
1907
+ variant: "issue",
1908
+ dataStatus: status.trim().toLowerCase() || "not_started"
1909
+ };
1910
+ }
1911
+ function mentionStatusTone(status) {
1912
+ if (status === "working") {
1913
+ return "blue";
1914
+ }
1915
+ if (status === "waiting" || status === "canceled") {
1916
+ return "amber";
1917
+ }
1918
+ if (status === "completed" || status === "idle") {
1919
+ return "green";
1920
+ }
1921
+ if (status === "failed") {
1922
+ return "red";
1923
+ }
1924
+ return "neutral";
1925
+ }
1926
+ function browseHintForFilter(filter) {
1927
+ if (filter === "all") {
1928
+ return translate("agentHost.agentGui.contextPickerBrowseAllHint");
1929
+ }
1930
+ switch (filter) {
1931
+ case "app":
1932
+ return translate("agentHost.agentGui.contextPickerBrowseAppHint");
1933
+ case "file":
1934
+ return translate("agentHost.agentGui.contextPickerBrowseFileHint");
1935
+ case "session":
1936
+ return translate("agentHost.agentGui.contextPickerBrowseSessionHint");
1937
+ case "issue":
1938
+ return translate("agentHost.agentGui.contextPickerBrowseIssueHint");
1939
+ }
1940
+ }
1941
+ function isBrowseCategoryId(value) {
1942
+ return value === "all" || value === "app" || value === "file" || value === "session" || value === "issue";
1943
+ }
1944
+ function hasInteractiveGroupEntries(groups) {
1945
+ return groups.some((group) => group.items.length > 0 || group.hasMore);
1946
+ }
1947
+ function isFileBrowseGroupsOnlyEmpty(groups) {
1948
+ const fileGroups = groups.filter(
1949
+ (group) => group.id === "opened_files" || group.id === "agent_generated_files"
1950
+ );
1951
+ if (fileGroups.length === 0) {
1952
+ return false;
1953
+ }
1954
+ return fileGroups.every(
1955
+ (group) => group.items.length === 0 && !group.hasMore
1956
+ );
1957
+ }
1958
+ function hasVisibleFileGroupEntries(groups) {
1959
+ return groups.some(
1960
+ (group) => (group.id === "files" || group.id === "opened_files" || group.id === "agent_generated_files") && (group.items.length > 0 || group.hasMore)
1961
+ );
1962
+ }
1963
+ function shouldShowFileSearchMoreHint(input) {
1964
+ if (input.filter !== "file" || input.query.trim()) {
1965
+ return false;
1966
+ }
1967
+ if (input.mode !== "browse" && input.mode !== "results") {
1968
+ return false;
1969
+ }
1970
+ return hasVisibleFileGroupEntries(input.groups);
1971
+ }
1972
+ function shouldShowBrowseSearchHint(input) {
1973
+ if (input.mode !== "browse" || hasInteractiveGroupEntries(input.groups)) {
1974
+ return false;
1975
+ }
1976
+ if (input.groups.length === 0) {
1977
+ return true;
1978
+ }
1979
+ if (input.highlightedBrowseCategory !== null && input.highlightedBrowseCategory !== input.browseFilter) {
1980
+ return true;
1981
+ }
1982
+ return input.browseFilter === "file" && isFileBrowseGroupsOnlyEmpty(input.groups);
1983
+ }
1984
+
1985
+ export {
1986
+ AGENT_MENTION_FILTER_TAB_ORDER,
1987
+ AgentMentionSearchController,
1988
+ flattenAgentMentionPaletteEntries,
1989
+ groupStartKeys,
1990
+ AgentFileMentionPalette,
1991
+ AgentContextMentionPalette
1992
+ };
1993
+ //# sourceMappingURL=chunk-3YZX5EUC.js.map