@tutti-os/agent-gui 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +56 -0
  3. package/dist/agent-message-center/index.d.ts +218 -0
  4. package/dist/agent-message-center/index.js +1962 -0
  5. package/dist/agent-message-center/index.js.map +1 -0
  6. package/dist/agent-rich-text-at-provider.d.ts +49 -0
  7. package/dist/agent-rich-text-at-provider.js +7 -0
  8. package/dist/agent-rich-text-at-provider.js.map +1 -0
  9. package/dist/agent-title-text.d.ts +3 -0
  10. package/dist/agent-title-text.js +7 -0
  11. package/dist/agent-title-text.js.map +1 -0
  12. package/dist/app/renderer/agentactivity.css +6773 -0
  13. package/dist/app/renderer/assets/icons/agent-sessions-filled.svg +1 -0
  14. package/dist/app/renderer/assets/icons/agents/claude-rounded.png +0 -0
  15. package/dist/app/renderer/assets/icons/agents/codex-rounded.png +0 -0
  16. package/dist/app/renderer/assets/icons/agents/gemini-rounded.png +0 -0
  17. package/dist/app/renderer/assets/icons/agents/hermes-rounded.png +0 -0
  18. package/dist/app/renderer/assets/icons/agents/manage-agent-claude-code.png +0 -0
  19. package/dist/app/renderer/assets/icons/agents/manage-agent-codex.png +0 -0
  20. package/dist/app/renderer/assets/icons/agents/manage-agent-gemini.png +0 -0
  21. package/dist/app/renderer/assets/icons/agents/manage-agent-hermes.png +0 -0
  22. package/dist/app/renderer/assets/icons/agents/manage-agent-nextop.png +0 -0
  23. package/dist/app/renderer/assets/icons/agents/manage-agent-openclaw.png +0 -0
  24. package/dist/app/renderer/assets/icons/agents/nextop-doc-rounded.png +0 -0
  25. package/dist/app/renderer/assets/icons/agents/openclaw-rounded.png +0 -0
  26. package/dist/app/renderer/assets/icons/agents/workspace-dock-agent-claude-code.png +0 -0
  27. package/dist/app/renderer/assets/icons/agents/workspace-dock-agent-codex.png +0 -0
  28. package/dist/app/renderer/assets/icons/agents/workspace-dock-agent-gemini.png +0 -0
  29. package/dist/app/renderer/assets/icons/agents/workspace-dock-agent-nexight.png +0 -0
  30. package/dist/app/renderer/assets/icons/agents/workspace-dock-agent-openclaw.png +0 -0
  31. package/dist/app/renderer/assets/icons/code-filled.svg +1 -0
  32. package/dist/app/renderer/assets/icons/doc-filled.svg +1 -0
  33. package/dist/app/renderer/assets/icons/folder-filled.svg +1 -0
  34. package/dist/app/renderer/assets/icons/image-filled.svg +1 -0
  35. package/dist/app/renderer/assets/icons/issue-filled.svg +1 -0
  36. package/dist/app/renderer/assets/icons/product-filled.svg +1 -0
  37. package/dist/app/renderer/assets/icons/user-avatar-placeholder.png +0 -0
  38. package/dist/app/renderer/assets/icons/video-filled.svg +1 -0
  39. package/dist/chunk-22L4VWUR.js +70 -0
  40. package/dist/chunk-22L4VWUR.js.map +1 -0
  41. package/dist/chunk-3D5VTIKP.js +93 -0
  42. package/dist/chunk-3D5VTIKP.js.map +1 -0
  43. package/dist/chunk-AF5CXBJN.js +3075 -0
  44. package/dist/chunk-AF5CXBJN.js.map +1 -0
  45. package/dist/chunk-BABBC24I.js +28 -0
  46. package/dist/chunk-BABBC24I.js.map +1 -0
  47. package/dist/chunk-GCBDIQDX.js +22 -0
  48. package/dist/chunk-GCBDIQDX.js.map +1 -0
  49. package/dist/chunk-HSR5DI6O.js +4695 -0
  50. package/dist/chunk-HSR5DI6O.js.map +1 -0
  51. package/dist/chunk-IVPB4MLI.js +7 -0
  52. package/dist/chunk-IVPB4MLI.js.map +1 -0
  53. package/dist/chunk-KCC3GNPB.js +13 -0
  54. package/dist/chunk-KCC3GNPB.js.map +1 -0
  55. package/dist/chunk-PJP5BUU6.js +18 -0
  56. package/dist/chunk-PJP5BUU6.js.map +1 -0
  57. package/dist/chunk-RORLLV27.js +144 -0
  58. package/dist/chunk-RORLLV27.js.map +1 -0
  59. package/dist/chunk-UJWUGMWC.js +128 -0
  60. package/dist/chunk-UJWUGMWC.js.map +1 -0
  61. package/dist/chunk-UKQIGNN3.js +921 -0
  62. package/dist/chunk-UKQIGNN3.js.map +1 -0
  63. package/dist/chunk-ZP7P7DYO.js +270 -0
  64. package/dist/chunk-ZP7P7DYO.js.map +1 -0
  65. package/dist/chunk-ZX5PDYAS.js +346 -0
  66. package/dist/chunk-ZX5PDYAS.js.map +1 -0
  67. package/dist/claude-rounded-F6VPQETB.png +0 -0
  68. package/dist/codex-rounded-SC63MZAW.png +0 -0
  69. package/dist/gemini-rounded-O4KAJFIM.png +0 -0
  70. package/dist/hermes-rounded-QGDHBNRJ.png +0 -0
  71. package/dist/i18n/index.d.ts +4580 -0
  72. package/dist/i18n/index.js +19 -0
  73. package/dist/i18n/index.js.map +1 -0
  74. package/dist/index.d.ts +775 -0
  75. package/dist/index.js +33699 -0
  76. package/dist/index.js.map +1 -0
  77. package/dist/manage-agent-claude-code-F6VPQETB.png +0 -0
  78. package/dist/manage-agent-codex-SC63MZAW.png +0 -0
  79. package/dist/manage-agent-gemini-O4KAJFIM.png +0 -0
  80. package/dist/manage-agent-hermes-QGDHBNRJ.png +0 -0
  81. package/dist/manage-agent-nextop-UFAQ22K2.png +0 -0
  82. package/dist/manage-agent-openclaw-24U7O6CA.png +0 -0
  83. package/dist/mention-file-presentation.d.ts +16 -0
  84. package/dist/mention-file-presentation.js +10 -0
  85. package/dist/mention-file-presentation.js.map +1 -0
  86. package/dist/nextop-doc-rounded-UFAQ22K2.png +0 -0
  87. package/dist/openclaw-rounded-24U7O6CA.png +0 -0
  88. package/dist/user-avatar-placeholder-WP2373TS.png +0 -0
  89. package/dist/workbench/contribution.d.ts +42 -0
  90. package/dist/workbench/contribution.js +24 -0
  91. package/dist/workbench/contribution.js.map +1 -0
  92. package/dist/workbench/index.d.ts +24 -0
  93. package/dist/workbench/index.js +82 -0
  94. package/dist/workbench/index.js.map +1 -0
  95. package/dist/workbench/launch.d.ts +49 -0
  96. package/dist/workbench/launch.js +23 -0
  97. package/dist/workbench/launch.js.map +1 -0
  98. package/dist/workbench/providerCatalog.d.ts +15 -0
  99. package/dist/workbench/providerCatalog.js +27 -0
  100. package/dist/workbench/providerCatalog.js.map +1 -0
  101. package/dist/workbench/state.d.ts +22 -0
  102. package/dist/workbench/state.js +22 -0
  103. package/dist/workbench/state.js.map +1 -0
  104. package/dist/workbench/types.d.ts +43 -0
  105. package/dist/workbench/types.js +7 -0
  106. package/dist/workbench/types.js.map +1 -0
  107. package/dist/workspace-agent-generated-files.d.ts +2 -0
  108. package/dist/workspace-agent-generated-files.js +21 -0
  109. package/dist/workspace-agent-generated-files.js.map +1 -0
  110. package/dist/workspaceAgentActivityListViewModel-PvLQDj60.d.ts +309 -0
  111. package/dist/workspaceLinkActions-Bwa-phu8.d.ts +51 -0
  112. package/package.json +166 -0
@@ -0,0 +1,921 @@
1
+ import {
2
+ resolveWorkspaceAgentSessionSortTimeUnixMs,
3
+ workspaceAgentProviderLabel
4
+ } from "./chunk-3D5VTIKP.js";
5
+ import {
6
+ normalizeAgentTitleText
7
+ } from "./chunk-GCBDIQDX.js";
8
+ import {
9
+ translate,
10
+ translateInUiLanguage
11
+ } from "./chunk-HSR5DI6O.js";
12
+
13
+ // shared/workspaceAgentStatusNormalizer.ts
14
+ var FAILED_STATUS_TOKENS = /* @__PURE__ */ new Set(["failed", "error"]);
15
+ var CANCELED_STATUS_TOKENS = /* @__PURE__ */ new Set(["canceled"]);
16
+ var COMPLETED_STATUS_TOKENS = /* @__PURE__ */ new Set(["completed", "ended", "end"]);
17
+ var WAITING_APPROVAL_TOKENS = /* @__PURE__ */ new Set([
18
+ "waiting_approval",
19
+ "awaiting_approval"
20
+ ]);
21
+ var WAITING_INPUT_TOKENS = /* @__PURE__ */ new Set(["waiting_input"]);
22
+ var WAITING_STATUS_TOKENS = /* @__PURE__ */ new Set(["waiting"]);
23
+ var WORKING_STATUS_TOKENS = /* @__PURE__ */ new Set(["working", "running", "streaming"]);
24
+ var READY_STATUS_TOKENS = /* @__PURE__ */ new Set(["ready", "idle"]);
25
+ function normalizeWorkspaceAgentStatus(input) {
26
+ return normalizeOptionalWorkspaceAgentStatus(input) ?? { kind: "ready" };
27
+ }
28
+ function normalizeOptionalWorkspaceAgentStatus(input) {
29
+ const lifecycleStatus = normalizeStatusToken(input.lifecycleStatus);
30
+ const effectiveStatus = normalizeStatusToken(input.effectiveStatus);
31
+ const sessionStatus = normalizeStatusToken(input.status);
32
+ const turnPhase = normalizeStatusToken(input.turnPhase);
33
+ const currentPhase = normalizeStatusToken(input.currentPhase);
34
+ const tokens = [
35
+ lifecycleStatus,
36
+ effectiveStatus,
37
+ sessionStatus,
38
+ turnPhase,
39
+ currentPhase
40
+ ].filter(Boolean);
41
+ if (tokens.length === 0) {
42
+ return null;
43
+ }
44
+ if ([lifecycleStatus, effectiveStatus, sessionStatus, currentPhase].some(
45
+ (token) => FAILED_STATUS_TOKENS.has(token)
46
+ )) {
47
+ return { kind: "failed" };
48
+ }
49
+ if ([lifecycleStatus, effectiveStatus, sessionStatus].some(
50
+ (token) => CANCELED_STATUS_TOKENS.has(token)
51
+ )) {
52
+ return { kind: "canceled" };
53
+ }
54
+ if ([lifecycleStatus, effectiveStatus, sessionStatus].some(
55
+ (token) => COMPLETED_STATUS_TOKENS.has(token)
56
+ )) {
57
+ return { kind: "completed" };
58
+ }
59
+ const waitKind = waitingKindFromTokens([
60
+ currentPhase,
61
+ turnPhase,
62
+ effectiveStatus,
63
+ sessionStatus
64
+ ]);
65
+ if (waitKind) {
66
+ return { kind: "waiting", waitKind };
67
+ }
68
+ if ([currentPhase, turnPhase, effectiveStatus, sessionStatus].some(
69
+ (token) => WAITING_STATUS_TOKENS.has(token)
70
+ )) {
71
+ return { kind: "waiting" };
72
+ }
73
+ if ([currentPhase, turnPhase, effectiveStatus, sessionStatus].some(
74
+ (token) => WORKING_STATUS_TOKENS.has(token)
75
+ )) {
76
+ return { kind: "working" };
77
+ }
78
+ if (lifecycleStatus === "active" || lifecycleStatus === "ready" || [currentPhase, turnPhase, effectiveStatus, sessionStatus].some(
79
+ (token) => READY_STATUS_TOKENS.has(token)
80
+ )) {
81
+ return { kind: "ready" };
82
+ }
83
+ return null;
84
+ }
85
+ function waitingKindFromTokens(tokens) {
86
+ if (tokens.some((token) => WAITING_APPROVAL_TOKENS.has(token))) {
87
+ return "approval";
88
+ }
89
+ if (tokens.some((token) => WAITING_INPUT_TOKENS.has(token))) {
90
+ return "input";
91
+ }
92
+ return void 0;
93
+ }
94
+ function normalizeStatusToken(status) {
95
+ return status?.trim().toLowerCase() ?? "";
96
+ }
97
+
98
+ // shared/workspaceAgentSyntheticMessages.ts
99
+ function isWorkspaceAgentSyntheticControlMessage(text) {
100
+ const normalized = text?.trim().toLowerCase() ?? "";
101
+ switch (normalized) {
102
+ case "[request interrupted by user]":
103
+ case "request interrupted by user":
104
+ case "[request interrupted by user for tool use]":
105
+ case "request interrupted by user for tool use":
106
+ return true;
107
+ default:
108
+ return false;
109
+ }
110
+ }
111
+
112
+ // shared/workspaceAgentLatestActivitySummary.ts
113
+ function fallbackSummary(status) {
114
+ switch (status) {
115
+ case "working":
116
+ return translate("agentHost.workspaceAgentActivityStatusWorking");
117
+ case "waiting":
118
+ return translate("agentHost.workspaceAgentActivityStatusWaiting");
119
+ case "idle":
120
+ return translate("agentHost.workspaceAgentActivityStatusIdle");
121
+ case "canceled":
122
+ case "completed":
123
+ return translate("agentHost.workspaceAgentActivityStatusEnd");
124
+ case "failed":
125
+ return translate("agentHost.workspaceAgentActivityStatusFailed");
126
+ }
127
+ }
128
+ function isWorkspaceAgentUntitledTask(title) {
129
+ return localizedWorkspaceAgentLabelSet(
130
+ "agentHost.workspaceAgentsUntitledTask"
131
+ ).has(compactText(title));
132
+ }
133
+ function compactText(value) {
134
+ return value.trim().replace(/\s+/g, " ");
135
+ }
136
+ function localizedWorkspaceAgentLabelSet(key) {
137
+ return new Set(
138
+ ["en", "zh-CN"].map((language) => compactText(translateInUiLanguage(language, key))).filter(Boolean)
139
+ );
140
+ }
141
+
142
+ // shared/workspaceAgentSessionTitle.ts
143
+ function resolveDisplayableWorkspaceAgentSessionTitle(session) {
144
+ const title = normalizeAgentTitleText(session.title);
145
+ if (!title || isWorkspaceAgentUntitledTask(title) || isWorkspaceAgentSyntheticControlMessage(title)) {
146
+ return "";
147
+ }
148
+ const provider = session.provider?.trim();
149
+ if (provider && workspaceAgentProviderLabel(provider).toLowerCase() === title.toLowerCase()) {
150
+ return "";
151
+ }
152
+ return title;
153
+ }
154
+
155
+ // shared/workspaceAgentActivityTypes.ts
156
+ import {
157
+ mergeAgentActivityMessages
158
+ } from "@tutti-os/agent-activity-core";
159
+ var WORKSPACE_AGENT_ACTIVITY_RUNTIME_SESSION_ORIGIN = "WORKSPACE_AGENT_SESSION_ORIGIN_RUNTIME";
160
+ function isWorkspaceAgentActivityRuntimeSessionOrigin(sessionOrigin) {
161
+ const normalized = sessionOrigin?.trim().toUpperCase() ?? "";
162
+ return normalized === "" || normalized === WORKSPACE_AGENT_ACTIVITY_RUNTIME_SESSION_ORIGIN;
163
+ }
164
+ function isWorkspaceAgentActivityOptimisticMessage(message) {
165
+ return message.payload?.__agentGuiOptimisticPrompt === true;
166
+ }
167
+ function selectWorkspaceAgentActivityOverlayMessages(input) {
168
+ const durableMessages = input.durableMessages ?? [];
169
+ const localMessages = input.localMessages ?? [];
170
+ if (localMessages.length === 0) {
171
+ return [];
172
+ }
173
+ const durableIdentities = new Set(
174
+ durableMessages.map(workspaceAgentActivityMessageIdentity).filter((identity) => identity !== null)
175
+ );
176
+ return localMessages.filter((message) => {
177
+ if (isWorkspaceAgentActivityOptimisticMessage(message)) {
178
+ return true;
179
+ }
180
+ const identity = workspaceAgentActivityMessageIdentity(message);
181
+ return identity === null || !durableIdentities.has(identity);
182
+ });
183
+ }
184
+ function mergeWorkspaceAgentActivityDurableAndOverlayMessages(input) {
185
+ const durableMessages = input.durableMessages ?? [];
186
+ const overlayMessages = selectWorkspaceAgentActivityOverlayMessages(input);
187
+ return overlayMessages.length === 0 ? [...durableMessages] : mergeAgentActivityMessages(durableMessages, overlayMessages);
188
+ }
189
+ function workspaceAgentActivityMessageIdentity(message) {
190
+ const messageId = message.messageId?.trim() ?? "";
191
+ if (messageId) {
192
+ return `message:${messageId}`;
193
+ }
194
+ if (typeof message.version === "number" && Number.isFinite(message.version)) {
195
+ return `version:${message.version}`;
196
+ }
197
+ return null;
198
+ }
199
+
200
+ // shared/workspaceAgentActivityListViewModel.ts
201
+ function collectWorkspaceAgentGeneratedFiles(snapshot, options = {}) {
202
+ const workspaceRoot = options.workspaceRoot?.trim().replace(/\/+$/, "") || resolveWorkspaceRootFromSessions(snapshot.sessions);
203
+ const filesByPath = /* @__PURE__ */ new Map();
204
+ for (const session of snapshot.sessions) {
205
+ const sessionCwd = session.cwd?.trim().replace(/\/+$/, "") || workspaceRoot;
206
+ const normalizePath = createAgentGeneratedFilePathNormalizer({
207
+ sessionCwd,
208
+ workspaceRoot
209
+ });
210
+ const messages = resolveWorkspaceAgentSessionMessages(
211
+ snapshot.sessionMessagesById,
212
+ session
213
+ );
214
+ if (messages.length === 0) {
215
+ continue;
216
+ }
217
+ for (const file of changedFilesForSession(messages, normalizePath)) {
218
+ filesByPath.set(file.path, file);
219
+ }
220
+ for (const path of imageGenerationPathsFromMessages(
221
+ messages,
222
+ normalizePath
223
+ )) {
224
+ if (filesByPath.has(path)) {
225
+ continue;
226
+ }
227
+ filesByPath.set(path, {
228
+ path,
229
+ label: path.split("/").filter(Boolean).at(-1) ?? path
230
+ });
231
+ }
232
+ }
233
+ return applyShortestUniqueFileLabels([...filesByPath.values()]);
234
+ }
235
+ function buildWorkspaceAgentActivityListViewModel(snapshot, options = {}) {
236
+ const presencesById = new Map(
237
+ snapshot.presences.map((presence) => [presence.id, presence])
238
+ );
239
+ const activities = snapshot.sessions.map((session) => {
240
+ const presence = session.presenceId === void 0 ? null : presencesById.get(session.presenceId) ?? null;
241
+ const messages = resolveWorkspaceAgentSessionMessages(
242
+ options.sessionMessagesById,
243
+ session
244
+ );
245
+ const status = resolveWorkspaceAgentActivityStatus(session);
246
+ if (shouldHideEmptyRuntimePlaceholderSession(
247
+ session,
248
+ messages,
249
+ status,
250
+ options
251
+ )) {
252
+ return null;
253
+ }
254
+ const user = resolveActivityUser(session, presence, options);
255
+ const agentProvider = resolveProvider(session, presence);
256
+ const agentName = workspaceAgentProviderLabel(agentProvider);
257
+ const resolvedSortTimeUnixMs = resolveWorkspaceAgentSessionSortTimeUnixMs(
258
+ session,
259
+ {
260
+ messages
261
+ }
262
+ );
263
+ const latestActivity = resolveLatestActivity(messages, status, {
264
+ agentName,
265
+ userName: user.userName
266
+ });
267
+ const activity = {
268
+ id: `activity-${session.agentSessionId}`,
269
+ sessionId: session.agentSessionId,
270
+ userId: user.userId,
271
+ userName: user.userName,
272
+ ...user.userAvatarUrl ? { userAvatarUrl: user.userAvatarUrl } : {},
273
+ agentProvider,
274
+ agentName,
275
+ title: resolveWorkspaceAgentActivityTitle(session, messages),
276
+ status,
277
+ latestActivitySummary: latestActivity.summary,
278
+ latestActivityActorName: latestActivity.actorName,
279
+ changedFiles: changedFilesForSession(messages),
280
+ sortTimeUnixMs: resolvedSortTimeUnixMs,
281
+ readTimeUnixMs: readTimeUnixMs(session, status, resolvedSortTimeUnixMs)
282
+ };
283
+ return activity;
284
+ }).filter(
285
+ (activity) => activity !== null
286
+ ).sort(compareActivities);
287
+ return { activities };
288
+ }
289
+ function reuseWorkspaceAgentActivityListViewModelIfUnchanged(previous, next) {
290
+ if (!previous) {
291
+ return next;
292
+ }
293
+ if (next.activities.length === 0) {
294
+ return previous.activities.length === 0 ? previous : next;
295
+ }
296
+ const previousActivitiesById = new Map(
297
+ previous.activities.map((activity) => [activity.id, activity])
298
+ );
299
+ const activities = next.activities.map((activity) => {
300
+ const previousActivity = previousActivitiesById.get(activity.id);
301
+ if (!previousActivity || !workspaceAgentActivityCardEquals(previousActivity, activity)) {
302
+ return activity;
303
+ }
304
+ return previousActivity;
305
+ });
306
+ const reusedEveryActivityInPlace = previous.activities.length === activities.length && previous.activities.every(
307
+ (activity, index) => activity === activities[index]
308
+ );
309
+ return reusedEveryActivityInPlace ? previous : { activities };
310
+ }
311
+ function shouldHideEmptyRuntimePlaceholderSession(session, messages, status, options) {
312
+ if (!isWorkspaceAgentActivityRuntimeSessionOrigin(session.sessionOrigin)) {
313
+ return false;
314
+ }
315
+ if (messages.length > 0) {
316
+ return false;
317
+ }
318
+ if (!hasLoadedSessionMessageRecord(session, options.sessionMessagesById)) {
319
+ return false;
320
+ }
321
+ if (!isRuntimePlaceholderTerminalStatus(status)) {
322
+ return false;
323
+ }
324
+ return resolveDisplayableWorkspaceAgentSessionTitle(session) === "";
325
+ }
326
+ function hasLoadedSessionMessageRecord(session, sessionMessagesById) {
327
+ if (!sessionMessagesById) {
328
+ return false;
329
+ }
330
+ return workspaceAgentSessionMessageAliases(session).some(
331
+ (alias) => alias in sessionMessagesById
332
+ );
333
+ }
334
+ function isRuntimePlaceholderTerminalStatus(status) {
335
+ return status === "idle" || status === "completed" || status === "canceled";
336
+ }
337
+ function workspaceAgentActivityCardEquals(left, right) {
338
+ return left.id === right.id && left.sessionId === right.sessionId && left.userId === right.userId && left.userName === right.userName && left.userAvatarUrl === right.userAvatarUrl && left.agentProvider === right.agentProvider && left.agentName === right.agentName && left.title === right.title && left.status === right.status && left.latestActivitySummary === right.latestActivitySummary && left.latestActivityActorName === right.latestActivityActorName && left.sortTimeUnixMs === right.sortTimeUnixMs && JSON.stringify(left.conversationPreview ?? []) === JSON.stringify(right.conversationPreview ?? []) && JSON.stringify(left.toolCalls ?? []) === JSON.stringify(right.toolCalls ?? []) && JSON.stringify(left.changedFiles) === JSON.stringify(right.changedFiles);
339
+ }
340
+ function resolveWorkspaceAgentSessionMessages(sessionMessagesById, session) {
341
+ if (!sessionMessagesById) {
342
+ return [];
343
+ }
344
+ for (const alias of workspaceAgentSessionMessageAliases(session)) {
345
+ const messages = sessionMessagesById[alias];
346
+ if (messages) {
347
+ return messages;
348
+ }
349
+ }
350
+ return [];
351
+ }
352
+ function resolveActivityUser(session, presence, options) {
353
+ if (presence) {
354
+ return resolveUserFromId(presence.userId ?? "", options);
355
+ }
356
+ const sessionUserId = session.userId?.trim() ?? "";
357
+ if (sessionUserId) {
358
+ return resolveUserFromId(sessionUserId, options);
359
+ }
360
+ const fallbackMember = selectFallbackMember(options.fallbackMembers ?? []);
361
+ if (fallbackMember) {
362
+ return {
363
+ userId: fallbackMember.userId,
364
+ userName: fallbackMember.label || "Unknown member",
365
+ ...fallbackMember.avatarUrl ? { userAvatarUrl: fallbackMember.avatarUrl } : {}
366
+ };
367
+ }
368
+ return {
369
+ userId: null,
370
+ userName: "Unknown member"
371
+ };
372
+ }
373
+ function resolveUserFromId(rawUserId, options) {
374
+ const userId = rawUserId.trim();
375
+ const profile = options.userProfilesById?.[userId];
376
+ const profileName = compactText2(profile?.name ?? "");
377
+ const profileAvatar = profile?.avatar?.trim();
378
+ const rawName = profileName || userId || "Unknown member";
379
+ return {
380
+ userId,
381
+ userName: stripTrailingParentheticalEmailFromLabel(rawName) || rawName,
382
+ ...profileAvatar ? { userAvatarUrl: profileAvatar } : {}
383
+ };
384
+ }
385
+ function selectFallbackMember(members) {
386
+ return members.find((member) => member.role === "owner") ?? members[0] ?? null;
387
+ }
388
+ function resolveProvider(session, presence) {
389
+ const sessionProvider = normalizeProvider(session.provider);
390
+ if (sessionProvider) {
391
+ return sessionProvider;
392
+ }
393
+ const presenceProvider = normalizeProvider(presence?.provider);
394
+ if (presenceProvider) {
395
+ return presenceProvider;
396
+ }
397
+ return "unknown";
398
+ }
399
+ function normalizeProvider(provider) {
400
+ const trimmed = provider?.trim();
401
+ return trimmed ? trimmed.toLowerCase() : null;
402
+ }
403
+ function resolveWorkspaceAgentActivityStatus(session) {
404
+ const normalized = normalizeWorkspaceAgentStatus(session).kind;
405
+ switch (normalized) {
406
+ case "failed":
407
+ return "failed";
408
+ case "canceled":
409
+ return "canceled";
410
+ case "completed":
411
+ return "completed";
412
+ case "waiting":
413
+ return "waiting";
414
+ case "working":
415
+ return "working";
416
+ case "ready":
417
+ default:
418
+ return "idle";
419
+ }
420
+ }
421
+ function resolveWorkspaceAgentActivityTitle(session, messages = []) {
422
+ const sessionTitle = resolveDisplayableWorkspaceAgentSessionTitle(session);
423
+ const userMessageTitle = firstUserMessageText(messages);
424
+ if (sessionTitle && !isProviderPlaceholderTitleForSession(sessionTitle, session)) {
425
+ return sessionTitle;
426
+ }
427
+ return userMessageTitle || sessionTitle || workspaceAgentUntitledTaskLabel();
428
+ }
429
+ function isProviderPlaceholderTitleForSession(title, session) {
430
+ const provider = normalizeProvider(session.provider);
431
+ if (!provider) {
432
+ return false;
433
+ }
434
+ const normalizedTitle = title.trim().toLowerCase();
435
+ return workspaceAgentProviderLabel(provider).toLowerCase() === normalizedTitle;
436
+ }
437
+ function resolveLatestActivity(messages, status, actors) {
438
+ const latestMessage = latestDisplayableMessage(messages);
439
+ if (latestMessage) {
440
+ return {
441
+ actorName: messageRole(latestMessage.message) === "user" ? actors.userName : actors.agentName,
442
+ summary: latestMessage.text
443
+ };
444
+ }
445
+ return {
446
+ actorName: actors.agentName,
447
+ summary: fallbackSummary(status)
448
+ };
449
+ }
450
+ function changedFilesForSession(messages, normalizePath = defaultChangedFilePathNormalizer) {
451
+ const changedFilesByPath = /* @__PURE__ */ new Map();
452
+ const appendPath = (path) => {
453
+ if (!path || changedFilesByPath.has(path)) {
454
+ return;
455
+ }
456
+ changedFilesByPath.set(path, {
457
+ path,
458
+ label: path
459
+ });
460
+ };
461
+ for (const message of messages) {
462
+ for (const path of changedFilePathsFromMessage(message, normalizePath)) {
463
+ appendPath(path);
464
+ }
465
+ }
466
+ return applyShortestUniqueFileLabels(Array.from(changedFilesByPath.values()));
467
+ }
468
+ function changedFilePathsFromMessage(message, normalizePath = defaultChangedFilePathNormalizer) {
469
+ const payload = objectValue(message.payload);
470
+ const explicitFileChanges = fileChangePaths(
471
+ arrayValue(objectValue(payload?.fileChanges)?.files),
472
+ normalizePath
473
+ );
474
+ if (explicitFileChanges.length > 0) {
475
+ return explicitFileChanges;
476
+ }
477
+ if (!isSuccessfulFileChangeToolMessage(message)) {
478
+ return [];
479
+ }
480
+ const toolState = objectValue(payload?.tool_state);
481
+ const input = objectValue(payload?.input) ?? objectValue(toolState?.input) ?? null;
482
+ const output = objectValue(payload?.output);
483
+ const paths = dedupeStrings([
484
+ ...pathsValue(payload?.paths, normalizePath),
485
+ ...pathsValue(output?.paths, normalizePath),
486
+ ...pathsValue(input?.paths, normalizePath),
487
+ ...changeMapPaths(payload?.changes, normalizePath),
488
+ ...changeMapPaths(output?.changes, normalizePath),
489
+ ...changeMapPaths(input?.changes, normalizePath),
490
+ ...contentDiffPaths(payload?.content, normalizePath),
491
+ ...contentDiffPaths(output?.content, normalizePath),
492
+ ...contentDiffPaths(input?.content, normalizePath),
493
+ stringValue(payload?.path),
494
+ stringValue(payload?.filePath),
495
+ stringValue(payload?.file_path),
496
+ stringValue(input?.path),
497
+ stringValue(input?.filePath),
498
+ stringValue(input?.file_path),
499
+ stringValue(output?.path),
500
+ stringValue(output?.filePath),
501
+ stringValue(output?.file_path)
502
+ ]);
503
+ return paths.map((path) => normalizePath(path)).filter((path) => path !== null);
504
+ }
505
+ function defaultChangedFilePathNormalizer(value) {
506
+ return normalizedChangedFilePath(value);
507
+ }
508
+ function resolveWorkspaceRootFromSessions(sessions) {
509
+ for (const session of sessions) {
510
+ const cwd = session.cwd?.trim().replace(/\/+$/, "") ?? "";
511
+ if (cwd) {
512
+ return cwd;
513
+ }
514
+ }
515
+ return "";
516
+ }
517
+ function createAgentGeneratedFilePathNormalizer(input) {
518
+ const workspaceRoot = input.workspaceRoot?.trim().replace(/\/+$/, "") ?? "";
519
+ const sessionCwd = input.sessionCwd?.trim().replace(/\/+$/, "") || workspaceRoot;
520
+ return (value) => {
521
+ if (typeof value !== "string") {
522
+ return null;
523
+ }
524
+ return resolveAgentGeneratedFilePath(value, workspaceRoot, sessionCwd);
525
+ };
526
+ }
527
+ function resolveAgentGeneratedFilePath(rawPath, workspaceRoot, sessionCwd) {
528
+ const path = rawPath.trim();
529
+ if (!path || isStructuredPayloadPath(path)) {
530
+ return null;
531
+ }
532
+ if (path.startsWith("/workspace/")) {
533
+ return path;
534
+ }
535
+ if (isAgentStateGeneratedImagePath(path)) {
536
+ return path;
537
+ }
538
+ if (isAbsoluteAgentGeneratedFilePath(path)) {
539
+ if (workspaceRoot && !isPathInsideOrEqual(path, workspaceRoot) && !isAgentStateGeneratedImagePath(path)) {
540
+ return null;
541
+ }
542
+ return path.replace(/\\/g, "/");
543
+ }
544
+ const base = sessionCwd || workspaceRoot;
545
+ if (!base) {
546
+ return null;
547
+ }
548
+ const resolved = joinAgentGeneratedFilePath(base, path.replace(/^\.?\//, ""));
549
+ if (workspaceRoot && !isPathInsideOrEqual(resolved, workspaceRoot) && !isAgentStateGeneratedImagePath(resolved)) {
550
+ return null;
551
+ }
552
+ return resolved;
553
+ }
554
+ function isAbsoluteAgentGeneratedFilePath(path) {
555
+ return path.startsWith("/") || /^[A-Za-z]:[\\/]/.test(path);
556
+ }
557
+ function isPathInsideOrEqual(path, root) {
558
+ const normalizedPath = path.replace(/\\/g, "/").replace(/\/+$/, "");
559
+ const normalizedRoot = root.replace(/\\/g, "/").replace(/\/+$/, "");
560
+ if (!normalizedRoot) {
561
+ return false;
562
+ }
563
+ return normalizedPath === normalizedRoot || normalizedPath.startsWith(`${normalizedRoot}/`);
564
+ }
565
+ function joinAgentGeneratedFilePath(base, relativePath) {
566
+ const normalizedBase = base.replace(/\\/g, "/").replace(/\/+$/, "");
567
+ const normalizedRelative = relativePath.replace(/\\/g, "/");
568
+ return `${normalizedBase}/${normalizedRelative}`;
569
+ }
570
+ function imageGenerationPathsFromMessages(messages, normalizePath) {
571
+ const paths = [];
572
+ for (const message of messages) {
573
+ const payload = objectValue(message.payload);
574
+ if (!payload) {
575
+ continue;
576
+ }
577
+ const output = objectValue(payload.output);
578
+ for (const uri of [
579
+ ...imageGenerationUris(payload.content),
580
+ ...imageGenerationUris(output?.content)
581
+ ]) {
582
+ const normalized = normalizePath(uri);
583
+ if (normalized) {
584
+ paths.push(normalized);
585
+ }
586
+ }
587
+ }
588
+ return dedupeStrings(paths);
589
+ }
590
+ function imageGenerationUris(value) {
591
+ if (!Array.isArray(value)) {
592
+ return [];
593
+ }
594
+ const uris = [];
595
+ for (const item of value) {
596
+ const record = objectValue(item);
597
+ if (!record) {
598
+ continue;
599
+ }
600
+ const type = stringValue(record.type)?.toLowerCase();
601
+ const uri = stringValue(record.uri) ?? stringValue(record.path);
602
+ if (!uri) {
603
+ continue;
604
+ }
605
+ if (type === "image" || uri.toLowerCase().includes("generated_images") || /\.(?:png|jpe?g|gif|webp|bmp|svg)$/i.test(uri)) {
606
+ uris.push(uri);
607
+ }
608
+ }
609
+ return uris;
610
+ }
611
+ function isAgentStateGeneratedImagePath(path) {
612
+ const segments = path.split("/").filter(Boolean);
613
+ const stateRootIndex = segments.findIndex(
614
+ (segment) => segment === ".nextop" || segment === ".nextop-dev"
615
+ );
616
+ if (stateRootIndex < 0) {
617
+ return false;
618
+ }
619
+ const statePath = segments.slice(stateRootIndex);
620
+ return statePath[1] === "agent" && statePath[2] === "runs" && statePath.includes("generated_images");
621
+ }
622
+ function normalizedChangedFilePath(value, options = {}) {
623
+ if (typeof value !== "string") {
624
+ return null;
625
+ }
626
+ const path = value.trim();
627
+ if (!path || isStructuredPayloadPath(path)) {
628
+ return null;
629
+ }
630
+ if (!options.allowRelative && !path.startsWith("/workspace/")) {
631
+ return null;
632
+ }
633
+ return path;
634
+ }
635
+ function applyShortestUniqueFileLabels(files) {
636
+ const suffixByPath = shortestUniquePathSuffixByPath(
637
+ files.map((file) => file.path)
638
+ );
639
+ return files.map((file) => ({
640
+ ...file,
641
+ label: suffixByPath.get(file.path) ?? file.label
642
+ }));
643
+ }
644
+ function shortestUniquePathSuffixByPath(paths) {
645
+ const partsByPath = new Map(
646
+ paths.map((path) => [path, splitPathSegments(path)])
647
+ );
648
+ const labels = /* @__PURE__ */ new Map();
649
+ const unresolved = new Set(paths);
650
+ for (let depth = 1; unresolved.size > 0; depth += 1) {
651
+ const grouped = /* @__PURE__ */ new Map();
652
+ for (const path of unresolved) {
653
+ const parts = partsByPath.get(path) ?? [];
654
+ const suffix = parts.slice(-Math.min(depth, parts.length)).join("/");
655
+ const fallback = parts.at(-1) ?? path;
656
+ const label = suffix || fallback;
657
+ const group = grouped.get(label);
658
+ if (group) {
659
+ group.push(path);
660
+ } else {
661
+ grouped.set(label, [path]);
662
+ }
663
+ }
664
+ let resolvedCount = 0;
665
+ for (const [label, group] of grouped) {
666
+ if (group.length !== 1) {
667
+ continue;
668
+ }
669
+ const path = group[0];
670
+ if (!path) {
671
+ continue;
672
+ }
673
+ labels.set(path, label);
674
+ unresolved.delete(path);
675
+ resolvedCount += 1;
676
+ }
677
+ if (resolvedCount === 0) {
678
+ for (const path of unresolved) {
679
+ labels.set(path, path);
680
+ }
681
+ break;
682
+ }
683
+ }
684
+ return labels;
685
+ }
686
+ function splitPathSegments(path) {
687
+ return path.trim().split(/[\\/]/).filter(Boolean);
688
+ }
689
+ function isSuccessfulFileChangeToolMessage(message) {
690
+ if (normalizeToken(message.kind) !== "tool_call") {
691
+ return false;
692
+ }
693
+ const normalizedStatus = normalizeToken(message.status ?? void 0);
694
+ if (normalizedStatus && normalizedStatus !== "completed" && normalizedStatus !== "success") {
695
+ return false;
696
+ }
697
+ const payload = objectValue(message.payload);
698
+ const activityKind = stringValue(payload?.activityKind);
699
+ if (activityKind === "write_file" || activityKind === "edit_file" || activityKind === "delete_file") {
700
+ return true;
701
+ }
702
+ if (stringValue(payload?.fileChangeKind)) {
703
+ return true;
704
+ }
705
+ const input = objectValue(payload?.input);
706
+ const toolCall = objectValue(input?.toolCall) ?? objectValue(payload?.toolCall);
707
+ const toolCallKind = normalizeToken(stringValue(toolCall?.kind) ?? void 0);
708
+ if (toolCallKind === "write" || toolCallKind === "edit" || toolCallKind === "delete") {
709
+ return true;
710
+ }
711
+ const toolName = normalizeToolName(
712
+ stringValue(payload?.toolName) ?? stringValue(payload?.title) ?? stringValue(payload?.name) ?? ""
713
+ );
714
+ return isFileChangeNormalizedToolName(toolName);
715
+ }
716
+ function isFileChangeNormalizedToolName(normalizedToolName) {
717
+ if (!normalizedToolName) {
718
+ return false;
719
+ }
720
+ const exactMatches = /* @__PURE__ */ new Set([
721
+ "write",
722
+ "writefile",
723
+ "create",
724
+ "createfile",
725
+ "delete",
726
+ "deletefile",
727
+ "edit",
728
+ "editfile",
729
+ "multiedit",
730
+ "applypatch",
731
+ "move",
732
+ "notebookedit"
733
+ ]);
734
+ if (exactMatches.has(normalizedToolName)) {
735
+ return true;
736
+ }
737
+ for (const prefix of exactMatches) {
738
+ if (normalizedToolName.startsWith(`${prefix}/`)) {
739
+ return true;
740
+ }
741
+ }
742
+ return false;
743
+ }
744
+ function fileChangePaths(files, normalizePath = defaultChangedFilePathNormalizer) {
745
+ if (!files) {
746
+ return [];
747
+ }
748
+ return files.map((file) => normalizePath(objectValue(file)?.path)).filter((path) => path !== null);
749
+ }
750
+ function changeMapPaths(value, normalizePath = defaultChangedFilePathNormalizer) {
751
+ const changes = objectValue(value);
752
+ if (!changes) {
753
+ return [];
754
+ }
755
+ return Object.keys(changes).map((path) => normalizePath(path)).filter((path) => path !== null);
756
+ }
757
+ function contentDiffPaths(value, normalizePath = defaultChangedFilePathNormalizer) {
758
+ const content = arrayValue(value);
759
+ if (!content) {
760
+ return [];
761
+ }
762
+ return content.map((entry) => {
763
+ const record = objectValue(entry);
764
+ if (!record || stringValue(record.type) !== "diff") {
765
+ return null;
766
+ }
767
+ return normalizePath(record.path);
768
+ }).filter((path) => path !== null);
769
+ }
770
+ function pathsValue(value, normalizePath = defaultChangedFilePathNormalizer) {
771
+ const paths = arrayValue(value);
772
+ if (!paths) {
773
+ return [];
774
+ }
775
+ return paths.map((path) => normalizePath(path)).filter((path) => path !== null);
776
+ }
777
+ function objectValue(value) {
778
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
779
+ return null;
780
+ }
781
+ return value;
782
+ }
783
+ function arrayValue(value) {
784
+ return Array.isArray(value) ? value : null;
785
+ }
786
+ function stringValue(value) {
787
+ return typeof value === "string" && value.trim() ? value.trim() : null;
788
+ }
789
+ function dedupeStrings(values) {
790
+ return [
791
+ ...new Set(
792
+ values.filter(
793
+ (value) => typeof value === "string" && value.length > 0
794
+ )
795
+ )
796
+ ];
797
+ }
798
+ function normalizeToolName(value) {
799
+ return value.trim().toLowerCase().replaceAll("_", "").replaceAll("-", "").replaceAll(" ", "");
800
+ }
801
+ function isStructuredPayloadPath(path) {
802
+ if (/[\r\n]/.test(path)) {
803
+ return true;
804
+ }
805
+ if (!path.startsWith("{") && !path.startsWith("[")) {
806
+ return false;
807
+ }
808
+ try {
809
+ JSON.parse(path);
810
+ return true;
811
+ } catch {
812
+ return false;
813
+ }
814
+ }
815
+ function readTimeUnixMs(session, status, fallbackUnixMs) {
816
+ if (status === "completed" || status === "failed") {
817
+ return session.endedAtUnixMs ?? session.updatedAtUnixMs ?? fallbackUnixMs;
818
+ }
819
+ return fallbackUnixMs;
820
+ }
821
+ function firstUserMessageText(messages) {
822
+ const firstUserMessage = messages.map((message) => ({
823
+ message,
824
+ text: messageDisplayText(message),
825
+ time: messageTime(message)
826
+ })).filter(
827
+ (item) => messageRole(item.message) === "user" && item.text.length > 0
828
+ ).sort((left, right) => {
829
+ const timeDiff = (left.time ?? 0) - (right.time ?? 0);
830
+ if (timeDiff !== 0) {
831
+ return timeDiff;
832
+ }
833
+ return (left.message.id ?? 0) - (right.message.id ?? 0) || left.message.messageId.localeCompare(right.message.messageId);
834
+ })[0];
835
+ return firstUserMessage?.text ?? "";
836
+ }
837
+ function latestDisplayableMessage(messages) {
838
+ return messages.map((message) => ({
839
+ message,
840
+ text: messageDisplayText(message),
841
+ time: messageTime(message)
842
+ })).filter(
843
+ (item) => item.text.length > 0 && normalizeToken(item.message.kind) !== "tool_call"
844
+ ).sort((left, right) => {
845
+ const timeDiff = (right.time ?? 0) - (left.time ?? 0);
846
+ if (timeDiff !== 0) {
847
+ return timeDiff;
848
+ }
849
+ return (right.message.id ?? 0) - (left.message.id ?? 0) || right.message.messageId.localeCompare(left.message.messageId);
850
+ })[0] ?? null;
851
+ }
852
+ function messageDisplayText(message) {
853
+ const payload = message.payload ?? {};
854
+ const text = normalizeAgentTitleText(
855
+ compactText2(
856
+ stringValue(payload.content) || stringValue(payload.text) || stringValue(payload.message) || stringValue(payload.body) || stringValue(payload.title) || ""
857
+ )
858
+ );
859
+ return isWorkspaceAgentSyntheticControlMessage(text) ? "" : text;
860
+ }
861
+ function messageRole(message) {
862
+ return normalizeToken(message.role);
863
+ }
864
+ function messageTime(message) {
865
+ return message.occurredAtUnixMs ?? message.completedAtUnixMs ?? message.startedAtUnixMs;
866
+ }
867
+ function normalizeToken(value) {
868
+ return value?.trim().toLowerCase() ?? "";
869
+ }
870
+ function compareActivities(left, right) {
871
+ const timeDiff = right.sortTimeUnixMs - left.sortTimeUnixMs;
872
+ if (timeDiff !== 0) {
873
+ return timeDiff;
874
+ }
875
+ return left.sessionId.localeCompare(right.sessionId);
876
+ }
877
+ function compactText2(value) {
878
+ return value.replace(/\s+/g, " ").trim();
879
+ }
880
+ function workspaceAgentUntitledTaskLabel() {
881
+ return normalizeAgentTitleText(
882
+ translate("agentHost.workspaceAgentsUntitledTask")
883
+ );
884
+ }
885
+ function workspaceAgentSessionMessageAliases(session) {
886
+ const values = [
887
+ session.syncState?.agentSessionId,
888
+ session.agentSessionId,
889
+ session.providerSessionId
890
+ ];
891
+ const seen = /* @__PURE__ */ new Set();
892
+ const aliases = [];
893
+ for (const value of values) {
894
+ const normalized = value?.trim() ?? "";
895
+ if (!normalized || seen.has(normalized)) {
896
+ continue;
897
+ }
898
+ seen.add(normalized);
899
+ aliases.push(normalized);
900
+ }
901
+ return aliases;
902
+ }
903
+ function stripTrailingParentheticalEmailFromLabel(label) {
904
+ return label.trim().replace(/\s*\([^)]*@[^)]+\)\s*$/u, "").trim();
905
+ }
906
+
907
+ export {
908
+ normalizeOptionalWorkspaceAgentStatus,
909
+ isWorkspaceAgentSyntheticControlMessage,
910
+ isWorkspaceAgentUntitledTask,
911
+ WORKSPACE_AGENT_ACTIVITY_RUNTIME_SESSION_ORIGIN,
912
+ isWorkspaceAgentActivityRuntimeSessionOrigin,
913
+ selectWorkspaceAgentActivityOverlayMessages,
914
+ mergeWorkspaceAgentActivityDurableAndOverlayMessages,
915
+ collectWorkspaceAgentGeneratedFiles,
916
+ buildWorkspaceAgentActivityListViewModel,
917
+ reuseWorkspaceAgentActivityListViewModelIfUnchanged,
918
+ resolveWorkspaceAgentActivityStatus,
919
+ resolveWorkspaceAgentActivityTitle
920
+ };
921
+ //# sourceMappingURL=chunk-UKQIGNN3.js.map