@tutti-os/agent-gui 0.0.44 → 0.0.46

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 (49) hide show
  1. package/dist/agent-conversation/index.js +5 -4
  2. package/dist/agent-conversation/index.js.map +1 -1
  3. package/dist/agent-message-center/index.js +17 -11
  4. package/dist/agent-message-center/index.js.map +1 -1
  5. package/dist/app/renderer/agentactivity.css +154 -69
  6. package/dist/{chunk-GMLK2EFU.js → chunk-62QOR3TC.js} +4 -97
  7. package/dist/chunk-62QOR3TC.js.map +1 -0
  8. package/dist/{chunk-5UD2YEBX.js → chunk-AMNXH4DJ.js} +47 -14
  9. package/dist/{chunk-5UD2YEBX.js.map → chunk-AMNXH4DJ.js.map} +1 -1
  10. package/dist/{chunk-25VZHG6G.js → chunk-BAQTM6VS.js} +15 -6
  11. package/dist/chunk-BAQTM6VS.js.map +1 -0
  12. package/dist/{chunk-ZORA4UAT.js → chunk-D6IYEVDT.js} +2 -2
  13. package/dist/chunk-EIC7XS3C.js +71 -0
  14. package/dist/chunk-EIC7XS3C.js.map +1 -0
  15. package/dist/chunk-FJG2EH4V.js +317 -0
  16. package/dist/chunk-FJG2EH4V.js.map +1 -0
  17. package/dist/{chunk-64OSXJRE.js → chunk-FRG36S6N.js} +26 -7
  18. package/dist/chunk-FRG36S6N.js.map +1 -0
  19. package/dist/{chunk-J4MU53PH.js → chunk-NZ2BGOJU.js} +2 -2
  20. package/dist/chunk-OL54R6OL.js +99 -0
  21. package/dist/chunk-OL54R6OL.js.map +1 -0
  22. package/dist/{chunk-ZTQKIJ5J.js → chunk-QT45WUPQ.js} +71 -20
  23. package/dist/chunk-QT45WUPQ.js.map +1 -0
  24. package/dist/{chunk-IGXC7NRW.js → chunk-VFQR7AZI.js} +10 -63
  25. package/dist/chunk-VFQR7AZI.js.map +1 -0
  26. package/dist/{chunk-SF2PE7M6.js → chunk-ZJ7OSY4T.js} +4 -4
  27. package/dist/context-mention-palette/index.js +7 -6
  28. package/dist/i18n/index.d.ts +2 -2
  29. package/dist/i18n/index.js +2 -1
  30. package/dist/index.d.ts +1 -5
  31. package/dist/index.js +321 -245
  32. package/dist/index.js.map +1 -1
  33. package/dist/uiSettings-BQS9r2eo.d.ts +6 -0
  34. package/dist/workbench/contribution.js +1 -1
  35. package/dist/workbench/index.d.ts +3 -0
  36. package/dist/workbench/index.js +13 -2
  37. package/dist/workbench/sessionTitle.d.ts +28 -0
  38. package/dist/workbench/sessionTitle.js +14 -0
  39. package/dist/workbench/sessionTitle.js.map +1 -0
  40. package/dist/workspace-agent-generated-files.js +3 -2
  41. package/package.json +21 -14
  42. package/dist/chunk-25VZHG6G.js.map +0 -1
  43. package/dist/chunk-64OSXJRE.js.map +0 -1
  44. package/dist/chunk-GMLK2EFU.js.map +0 -1
  45. package/dist/chunk-IGXC7NRW.js.map +0 -1
  46. package/dist/chunk-ZTQKIJ5J.js.map +0 -1
  47. /package/dist/{chunk-ZORA4UAT.js.map → chunk-D6IYEVDT.js.map} +0 -0
  48. /package/dist/{chunk-J4MU53PH.js.map → chunk-NZ2BGOJU.js.map} +0 -0
  49. /package/dist/{chunk-SF2PE7M6.js.map → chunk-ZJ7OSY4T.js.map} +0 -0
@@ -14,7 +14,7 @@ import {
14
14
  import {
15
15
  translate,
16
16
  translateInUiLanguage
17
- } from "./chunk-IGXC7NRW.js";
17
+ } from "./chunk-EIC7XS3C.js";
18
18
 
19
19
  // shared/workspaceAgentActivityListViewModel.ts
20
20
  import { normalizeAgentActivityDisplayStatus } from "@tutti-os/agent-activity-core";
@@ -993,4 +993,4 @@ export {
993
993
  resolveWorkspaceAgentActivityStatus,
994
994
  resolveWorkspaceAgentActivityTitle
995
995
  };
996
- //# sourceMappingURL=chunk-ZORA4UAT.js.map
996
+ //# sourceMappingURL=chunk-D6IYEVDT.js.map
@@ -0,0 +1,71 @@
1
+ import {
2
+ agentGuiI18nResources,
3
+ getActiveUiLanguage,
4
+ getCurrentAgentGuiI18nRuntime,
5
+ resolveAgentGuiI18nRuntime,
6
+ setCurrentAgentGuiI18nRuntime,
7
+ translate,
8
+ translateInUiLanguage
9
+ } from "./chunk-VFQR7AZI.js";
10
+
11
+ // i18n/index.ts
12
+ import React, {
13
+ createContext,
14
+ useCallback,
15
+ useContext,
16
+ useMemo
17
+ } from "react";
18
+ import {
19
+ createLocaleObjectI18nModuleManifest
20
+ } from "@tutti-os/ui-i18n-runtime";
21
+ var agentGuiI18nResources2 = agentGuiI18nResources;
22
+ var getActiveUiLanguage2 = getActiveUiLanguage;
23
+ var translate2 = translate;
24
+ var translateInUiLanguage2 = translateInUiLanguage;
25
+ var agentGuiI18nModule = createLocaleObjectI18nModuleManifest({
26
+ fileByLocale: {
27
+ en: "packages/agent/gui/app/renderer/i18n/locales/en.ts",
28
+ "zh-CN": "packages/agent/gui/app/renderer/i18n/locales/zh-CN.ts"
29
+ },
30
+ name: "agent-gui",
31
+ sourceRoot: "packages/agent/gui"
32
+ });
33
+ var AgentGuiI18nContext = createContext(null);
34
+ function AgentGuiI18nProvider({
35
+ children,
36
+ locale = "en",
37
+ runtime
38
+ }) {
39
+ const value = useMemo(
40
+ () => resolveAgentGuiI18nRuntime({
41
+ locale,
42
+ runtime
43
+ }),
44
+ [locale, runtime]
45
+ );
46
+ setCurrentAgentGuiI18nRuntime(value);
47
+ return React.createElement(AgentGuiI18nContext.Provider, { value }, children);
48
+ }
49
+ function useTranslation() {
50
+ const context = useContext(AgentGuiI18nContext) ?? getCurrentAgentGuiI18nRuntime();
51
+ const t = useCallback(
52
+ (key, options) => context.runtime.t(key, options),
53
+ [context.runtime]
54
+ );
55
+ return {
56
+ i18n: context.runtime,
57
+ locale: context.locale,
58
+ t
59
+ };
60
+ }
61
+
62
+ export {
63
+ agentGuiI18nResources2 as agentGuiI18nResources,
64
+ getActiveUiLanguage2 as getActiveUiLanguage,
65
+ translate2 as translate,
66
+ translateInUiLanguage2 as translateInUiLanguage,
67
+ agentGuiI18nModule,
68
+ AgentGuiI18nProvider,
69
+ useTranslation
70
+ };
71
+ //# sourceMappingURL=chunk-EIC7XS3C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../i18n/index.ts"],"sourcesContent":["import React, {\n createContext,\n useCallback,\n useContext,\n useMemo,\n type ReactNode\n} from \"react\";\nimport {\n createLocaleObjectI18nModuleManifest,\n type I18nRuntime\n} from \"@tutti-os/ui-i18n-runtime\";\nimport * as agentGuiI18nRuntime from \"./runtime.ts\";\nimport type {\n AgentGuiI18nLocale,\n TranslateFn,\n TranslateOptions\n} from \"./runtime.ts\";\n\nexport const agentGuiI18nResources = agentGuiI18nRuntime.agentGuiI18nResources;\nexport const getActiveUiLanguage = agentGuiI18nRuntime.getActiveUiLanguage;\nexport const translate = agentGuiI18nRuntime.translate;\nexport const translateInUiLanguage = agentGuiI18nRuntime.translateInUiLanguage;\nexport type { AgentGuiI18nLocale, TranslateFn, TranslateOptions };\n\nexport const agentGuiI18nModule = createLocaleObjectI18nModuleManifest({\n fileByLocale: {\n en: \"packages/agent/gui/app/renderer/i18n/locales/en.ts\",\n \"zh-CN\": \"packages/agent/gui/app/renderer/i18n/locales/zh-CN.ts\"\n },\n name: \"agent-gui\",\n sourceRoot: \"packages/agent/gui\"\n});\n\nconst AgentGuiI18nContext = createContext<{\n locale: AgentGuiI18nLocale;\n runtime: I18nRuntime<string>;\n} | null>(null);\n\nexport function AgentGuiI18nProvider({\n children,\n locale = \"en\",\n runtime\n}: {\n children: ReactNode;\n locale?: AgentGuiI18nLocale;\n runtime?: I18nRuntime<string> | null;\n}): React.ReactElement {\n const value = useMemo(\n () =>\n agentGuiI18nRuntime.resolveAgentGuiI18nRuntime({\n locale,\n runtime\n }),\n [locale, runtime]\n );\n\n agentGuiI18nRuntime.setCurrentAgentGuiI18nRuntime(value);\n\n return React.createElement(AgentGuiI18nContext.Provider, { value }, children);\n}\n\nexport function useTranslation(): {\n i18n: I18nRuntime<string>;\n locale: AgentGuiI18nLocale;\n t: TranslateFn;\n} {\n const context =\n useContext(AgentGuiI18nContext) ??\n agentGuiI18nRuntime.getCurrentAgentGuiI18nRuntime();\n const t = useCallback(\n (key: string, options?: TranslateOptions) =>\n context.runtime.t(key, options),\n [context.runtime]\n );\n\n return {\n i18n: context.runtime,\n locale: context.locale,\n t\n };\n}\n"],"mappings":";;;;;;;;;;;AAAA,OAAO;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,OAEK;AAQA,IAAMA,yBAA4C;AAClD,IAAMC,uBAA0C;AAChD,IAAMC,aAAgC;AACtC,IAAMC,yBAA4C;AAGlD,IAAM,qBAAqB,qCAAqC;AAAA,EACrE,cAAc;AAAA,IACZ,IAAI;AAAA,IACJ,SAAS;AAAA,EACX;AAAA,EACA,MAAM;AAAA,EACN,YAAY;AACd,CAAC;AAED,IAAM,sBAAsB,cAGlB,IAAI;AAEP,SAAS,qBAAqB;AAAA,EACnC;AAAA,EACA,SAAS;AAAA,EACT;AACF,GAIuB;AACrB,QAAM,QAAQ;AAAA,IACZ,MACsB,2BAA2B;AAAA,MAC7C;AAAA,MACA;AAAA,IACF,CAAC;AAAA,IACH,CAAC,QAAQ,OAAO;AAAA,EAClB;AAEA,EAAoB,8BAA8B,KAAK;AAEvD,SAAO,MAAM,cAAc,oBAAoB,UAAU,EAAE,MAAM,GAAG,QAAQ;AAC9E;AAEO,SAAS,iBAId;AACA,QAAM,UACJ,WAAW,mBAAmB,KACV,8BAA8B;AACpD,QAAM,IAAI;AAAA,IACR,CAAC,KAAa,YACZ,QAAQ,QAAQ,EAAE,KAAK,OAAO;AAAA,IAChC,CAAC,QAAQ,OAAO;AAAA,EAClB;AAEA,SAAO;AAAA,IACL,MAAM,QAAQ;AAAA,IACd,QAAQ,QAAQ;AAAA,IAChB;AAAA,EACF;AACF;","names":["agentGuiI18nResources","getActiveUiLanguage","translate","translateInUiLanguage"]}
@@ -0,0 +1,317 @@
1
+ import {
2
+ normalizeAgentTitleText
3
+ } from "./chunk-GCBDIQDX.js";
4
+ import {
5
+ translateInUiLanguage
6
+ } from "./chunk-VFQR7AZI.js";
7
+
8
+ // shared/utils/agentSessionMentionText.ts
9
+ import {
10
+ isRichTextMentionHref,
11
+ parseRichTextMentionHref
12
+ } from "@tutti-os/ui-rich-text/core";
13
+ var MARKDOWN_LINK_PATTERN = /\[((?:\\.|[^\]\\])*)\]\(([^)\s]+)\)/g;
14
+ var MARKDOWN_LABEL_ESCAPE_PATTERN = /\\([\\[\]()])/g;
15
+ var SESSION_MENTION_DISPLAY_PREFIX_BY_LANGUAGE = {
16
+ "zh-CN": "@\u4F1A\u8BDD \xB7 ",
17
+ en: "@session \xB7 "
18
+ };
19
+ var PLAIN_SESSION_AGENT_LABELS = [
20
+ "Claude Code",
21
+ "Gemini CLI",
22
+ "Hermes Agent",
23
+ "OpenClaw",
24
+ "Nexight",
25
+ "Gemini",
26
+ "Hermes",
27
+ "Codex"
28
+ ];
29
+ function formatAgentSessionMentionText(value, options = {}) {
30
+ const trimmed = value?.trim() ?? "";
31
+ if (!trimmed) {
32
+ return "";
33
+ }
34
+ const sessionMentionDisplayPrefix = sessionMentionDisplayPrefixForLanguage(
35
+ options.language
36
+ );
37
+ const withSessionMentionsNormalized = trimmed.replace(
38
+ MARKDOWN_LINK_PATTERN,
39
+ (fullMatch, rawLabel, href) => {
40
+ const label = unescapeMarkdownLabel(rawLabel);
41
+ const mention = parseRichTextMentionHref(href, label);
42
+ if (!mention) {
43
+ return isRichTextMentionHref(href) ? label : fullMatch;
44
+ }
45
+ const providerId = mention.providerId.trim().toLowerCase();
46
+ const displayLabel = label || mention.label;
47
+ if (providerId === "agent-session") {
48
+ return formatSessionLabel(displayLabel, sessionMentionDisplayPrefix);
49
+ }
50
+ if (providerId === "workspace-issue") {
51
+ return formatIssueLabel(displayLabel);
52
+ }
53
+ return displayLabel;
54
+ }
55
+ );
56
+ const normalized = normalizeAgentTitleText(withSessionMentionsNormalized);
57
+ if (isPlainSessionMentionText(normalized, sessionMentionDisplayPrefix)) {
58
+ return formatSessionLabel(normalized, sessionMentionDisplayPrefix);
59
+ }
60
+ return normalized;
61
+ }
62
+ function isPlainSessionMentionText(value, sessionMentionDisplayPrefix) {
63
+ const trimmed = value.trim();
64
+ if (!trimmed.startsWith("@") || trimmed.startsWith(sessionMentionDisplayPrefix)) {
65
+ return false;
66
+ }
67
+ return PLAIN_SESSION_AGENT_LABELS.some((agentLabel) => {
68
+ const ampersandSeparator = ` & ${agentLabel}`;
69
+ const ampersandIndex = trimmed.indexOf(ampersandSeparator);
70
+ if (ampersandIndex > 1) {
71
+ const trailing = trimmed.slice(
72
+ ampersandIndex + ampersandSeparator.length
73
+ );
74
+ if (trailing === "" || trailing.startsWith(" ")) {
75
+ return true;
76
+ }
77
+ }
78
+ const dottedSeparator = ` \xB7 ${agentLabel} \xB7 `;
79
+ return trimmed.indexOf(dottedSeparator) > 1;
80
+ });
81
+ }
82
+ function sessionMentionDisplayPrefixForLanguage(language) {
83
+ return SESSION_MENTION_DISPLAY_PREFIX_BY_LANGUAGE[language ?? "en"];
84
+ }
85
+ function formatSessionLabel(label, sessionMentionDisplayPrefix) {
86
+ const normalizedLabel = label.trim().replace(/^@+/, "").trim();
87
+ return normalizedLabel ? `${sessionMentionDisplayPrefix}${normalizedLabel}` : label.trim();
88
+ }
89
+ function formatIssueLabel(label) {
90
+ const normalizedLabel = label.trim().replace(/^@+/, "").trim();
91
+ return normalizedLabel ? `@Task \xB7 ${normalizedLabel}` : label.trim();
92
+ }
93
+ function unescapeMarkdownLabel(label) {
94
+ return label.replace(MARKDOWN_LABEL_ESCAPE_PATTERN, "$1");
95
+ }
96
+
97
+ // contexts/settings/domain/agentSettings.providerMeta.ts
98
+ var AGENT_PROVIDER_LABEL = {
99
+ "claude-code": "Claude Code",
100
+ codex: "Codex",
101
+ nexight: "Nexight",
102
+ opencode: "OpenCode",
103
+ gemini: "Gemini CLI",
104
+ openclaw: "OpenClaw",
105
+ hermes: "Hermes Agent"
106
+ };
107
+
108
+ // shared/agentConversationTitleProjection.ts
109
+ function normalizeAgentGUIProviderIdentity(provider) {
110
+ switch (provider?.trim().toLowerCase() ?? "") {
111
+ case "claude-code":
112
+ case "claude":
113
+ case "claude code":
114
+ return "claude-code";
115
+ case "codex":
116
+ return "codex";
117
+ case "nexight":
118
+ case "tutti":
119
+ return "nexight";
120
+ case "gemini":
121
+ return "gemini";
122
+ case "hermes":
123
+ return "hermes";
124
+ case "openclaw":
125
+ return "openclaw";
126
+ default:
127
+ return "unknown";
128
+ }
129
+ }
130
+ function resolveAgentGUIProviderIdentity(input) {
131
+ const candidates = [
132
+ input.sessionProvider,
133
+ input.workspaceSessionProvider,
134
+ input.conversationProvider,
135
+ timelineProviderHint(input.timelineItems ?? [])
136
+ ];
137
+ for (const candidate of candidates) {
138
+ const normalized = normalizeAgentGUIProviderIdentity(candidate);
139
+ if (normalized !== "unknown") {
140
+ return normalized;
141
+ }
142
+ }
143
+ return "unknown";
144
+ }
145
+ function resolveAgentGUIConversationTitle(title, provider) {
146
+ const normalizedTitle = stripAgentGUITitleTrailingPeriod(
147
+ normalizeAgentTitleText(title)
148
+ );
149
+ if (normalizedTitle) {
150
+ return {
151
+ title: normalizedTitle,
152
+ titleFallback: null
153
+ };
154
+ }
155
+ if (provider === "unknown") {
156
+ return {
157
+ title: "",
158
+ titleFallback: "generic-agent"
159
+ };
160
+ }
161
+ return {
162
+ title: AGENT_PROVIDER_LABEL[provider],
163
+ titleFallback: null
164
+ };
165
+ }
166
+ function resolveAgentGUIConversationDisplayTitle(input, fallbackAgentLabel) {
167
+ if (input.title) {
168
+ return stripAgentGUITitleTrailingPeriod(
169
+ normalizeAgentTitleText(input.title)
170
+ );
171
+ }
172
+ if (input.titleFallback === "generic-agent") {
173
+ return stripAgentGUITitleTrailingPeriod(fallbackAgentLabel);
174
+ }
175
+ return "";
176
+ }
177
+ function formatAgentGUIConversationPlainTitle(input, options = {}) {
178
+ return formatAgentSessionMentionText(
179
+ resolveAgentGUIConversationDisplayTitle(
180
+ input,
181
+ options.fallbackAgentLabel ?? "Agent"
182
+ ),
183
+ {
184
+ language: options.language
185
+ }
186
+ );
187
+ }
188
+ function resolveAgentGUIDockConversationTitle(input) {
189
+ return resolveAgentGUIExplicitConversationTitle(input);
190
+ }
191
+ function resolveAgentGUIExplicitConversationTitle(input) {
192
+ if (input.titleFallback) {
193
+ return null;
194
+ }
195
+ const title = stripAgentGUITitleTrailingPeriod(
196
+ normalizeAgentTitleText(input.title)
197
+ );
198
+ if (!title) {
199
+ return null;
200
+ }
201
+ if (isAgentGUIUntitledTaskTitle(title)) {
202
+ return null;
203
+ }
204
+ if (input.provider !== "unknown" && title === AGENT_PROVIDER_LABEL[input.provider]) {
205
+ return null;
206
+ }
207
+ return title;
208
+ }
209
+ function resolveAgentGUIProviderDisplayLabel(provider, fallbackAgentLabel) {
210
+ const resolvedProvider = normalizeAgentGUIProviderIdentity(provider);
211
+ if (resolvedProvider === "unknown") {
212
+ return fallbackAgentLabel;
213
+ }
214
+ return AGENT_PROVIDER_LABEL[resolvedProvider];
215
+ }
216
+ function firstAgentGUIUserMessageTitle(messages) {
217
+ const userMessage = [...messages].filter(
218
+ (message) => messageRole(message) === "user" && messageText(message).length > 0
219
+ ).sort(compareMessagesAscending)[0];
220
+ return userMessage ? messageText(userMessage) : "";
221
+ }
222
+ function messageRole(message) {
223
+ const role = message.role?.trim().toLowerCase();
224
+ if (role === "user") {
225
+ return "user";
226
+ }
227
+ if (role === "assistant" || role === "agent") {
228
+ return "agent";
229
+ }
230
+ const kind = message.kind?.trim().toLowerCase() ?? "";
231
+ if (kind === "message.user") {
232
+ return "user";
233
+ }
234
+ if (kind === "message.assistant" || kind === "message.agent") {
235
+ return "agent";
236
+ }
237
+ return null;
238
+ }
239
+ function messageText(message) {
240
+ const payload = message.payload;
241
+ const displayPrompt = typeof payload?.displayPrompt === "string" ? payload.displayPrompt : "";
242
+ const text = typeof payload?.text === "string" ? payload.text : "";
243
+ const content = typeof payload?.content === "string" ? payload.content : "";
244
+ return normalizeAgentTitleText(displayPrompt || text || content);
245
+ }
246
+ function compareMessagesAscending(left, right) {
247
+ const leftTime = left.occurredAtUnixMs ?? left.completedAtUnixMs ?? left.startedAtUnixMs ?? 0;
248
+ const rightTime = right.occurredAtUnixMs ?? right.completedAtUnixMs ?? right.startedAtUnixMs ?? 0;
249
+ const timeDiff = leftTime - rightTime;
250
+ if (timeDiff !== 0) {
251
+ return timeDiff;
252
+ }
253
+ const sequenceDiff = messageSequence(left) - messageSequence(right) || (left.messageId ?? "").localeCompare(right.messageId ?? "");
254
+ return sequenceDiff;
255
+ }
256
+ function messageSequence(message) {
257
+ const numericId = typeof message.id === "number" && Number.isFinite(message.id) ? message.id : 0;
258
+ return message.version ?? numericId;
259
+ }
260
+ function stripAgentGUITitleTrailingPeriod(title) {
261
+ return title.trimEnd().replace(/[.。]+$/u, "").trimEnd();
262
+ }
263
+ function isAgentGUIUntitledTaskTitle(title) {
264
+ return localizedAgentGUIUntitledTaskLabels().has(compactTitleText(title));
265
+ }
266
+ function localizedAgentGUIUntitledTaskLabels() {
267
+ return new Set(
268
+ ["en", "zh-CN"].map(
269
+ (language) => compactTitleText(
270
+ translateInUiLanguage(
271
+ language,
272
+ "agentHost.workspaceAgentsUntitledTask"
273
+ )
274
+ )
275
+ ).filter(Boolean)
276
+ );
277
+ }
278
+ function timelineProviderHint(timelineItems) {
279
+ for (const item of timelineItems) {
280
+ if (isUserTimelineItem(item)) {
281
+ continue;
282
+ }
283
+ const normalized = normalizeAgentGUIProviderIdentity(item.actorId);
284
+ if (normalized !== "unknown") {
285
+ return normalized;
286
+ }
287
+ }
288
+ return null;
289
+ }
290
+ function isUserTimelineItem(item) {
291
+ const role = item.role?.trim().toLowerCase();
292
+ if (role === "user") {
293
+ return true;
294
+ }
295
+ const actorType = item.actorType.trim().toLowerCase();
296
+ if (actorType === "user") {
297
+ return true;
298
+ }
299
+ return item.itemType.trim().toLowerCase() === "message.user";
300
+ }
301
+ function compactTitleText(value) {
302
+ return value.trim().replace(/\s+/g, " ");
303
+ }
304
+
305
+ export {
306
+ AGENT_PROVIDER_LABEL,
307
+ formatAgentSessionMentionText,
308
+ normalizeAgentGUIProviderIdentity,
309
+ resolveAgentGUIProviderIdentity,
310
+ resolveAgentGUIConversationTitle,
311
+ formatAgentGUIConversationPlainTitle,
312
+ resolveAgentGUIDockConversationTitle,
313
+ resolveAgentGUIExplicitConversationTitle,
314
+ resolveAgentGUIProviderDisplayLabel,
315
+ firstAgentGUIUserMessageTitle
316
+ };
317
+ //# sourceMappingURL=chunk-FJG2EH4V.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../shared/utils/agentSessionMentionText.ts","../contexts/settings/domain/agentSettings.providerMeta.ts","../shared/agentConversationTitleProjection.ts"],"sourcesContent":["import type { UiLanguage } from \"../../contexts/settings/domain/agentSettings\";\nimport { normalizeAgentTitleText } from \"./agentTitleText.ts\";\nimport {\n isRichTextMentionHref,\n parseRichTextMentionHref\n} from \"@tutti-os/ui-rich-text/core\";\n\nconst MARKDOWN_LINK_PATTERN = /\\[((?:\\\\.|[^\\]\\\\])*)\\]\\(([^)\\s]+)\\)/g;\nconst MARKDOWN_LABEL_ESCAPE_PATTERN = /\\\\([\\\\[\\]()])/g;\nconst SESSION_MENTION_DISPLAY_PREFIX_BY_LANGUAGE: Record<UiLanguage, string> = {\n \"zh-CN\": \"@会话 · \",\n en: \"@session · \"\n};\nconst PLAIN_SESSION_AGENT_LABELS = [\n \"Claude Code\",\n \"Gemini CLI\",\n \"Hermes Agent\",\n \"OpenClaw\",\n \"Nexight\",\n \"Gemini\",\n \"Hermes\",\n \"Codex\"\n] as const;\n\nexport interface FormatAgentSessionMentionTextOptions {\n language?: UiLanguage;\n}\n\nexport function formatAgentSessionMentionText(\n value: string | null | undefined,\n options: FormatAgentSessionMentionTextOptions = {}\n): string {\n const trimmed = value?.trim() ?? \"\";\n if (!trimmed) {\n return \"\";\n }\n const sessionMentionDisplayPrefix = sessionMentionDisplayPrefixForLanguage(\n options.language\n );\n\n const withSessionMentionsNormalized = trimmed.replace(\n MARKDOWN_LINK_PATTERN,\n (fullMatch, rawLabel: string, href: string) => {\n const label = unescapeMarkdownLabel(rawLabel);\n const mention = parseRichTextMentionHref(href, label);\n if (!mention) {\n return isRichTextMentionHref(href) ? label : fullMatch;\n }\n const providerId = mention.providerId.trim().toLowerCase();\n const displayLabel = label || mention.label;\n if (providerId === \"agent-session\") {\n return formatSessionLabel(displayLabel, sessionMentionDisplayPrefix);\n }\n if (providerId === \"workspace-issue\") {\n return formatIssueLabel(displayLabel);\n }\n return displayLabel;\n }\n );\n const normalized = normalizeAgentTitleText(withSessionMentionsNormalized);\n if (isPlainSessionMentionText(normalized, sessionMentionDisplayPrefix)) {\n return formatSessionLabel(normalized, sessionMentionDisplayPrefix);\n }\n return normalized;\n}\n\nfunction isPlainSessionMentionText(\n value: string,\n sessionMentionDisplayPrefix: string\n): boolean {\n const trimmed = value.trim();\n if (\n !trimmed.startsWith(\"@\") ||\n trimmed.startsWith(sessionMentionDisplayPrefix)\n ) {\n return false;\n }\n\n return PLAIN_SESSION_AGENT_LABELS.some((agentLabel) => {\n const ampersandSeparator = ` & ${agentLabel}`;\n const ampersandIndex = trimmed.indexOf(ampersandSeparator);\n if (ampersandIndex > 1) {\n const trailing = trimmed.slice(\n ampersandIndex + ampersandSeparator.length\n );\n if (trailing === \"\" || trailing.startsWith(\" \")) {\n return true;\n }\n }\n\n const dottedSeparator = ` · ${agentLabel} · `;\n return trimmed.indexOf(dottedSeparator) > 1;\n });\n}\n\nfunction sessionMentionDisplayPrefixForLanguage(\n language: UiLanguage | undefined\n): string {\n return SESSION_MENTION_DISPLAY_PREFIX_BY_LANGUAGE[language ?? \"en\"];\n}\n\nfunction formatSessionLabel(\n label: string,\n sessionMentionDisplayPrefix: string\n): string {\n const normalizedLabel = label.trim().replace(/^@+/, \"\").trim();\n return normalizedLabel\n ? `${sessionMentionDisplayPrefix}${normalizedLabel}`\n : label.trim();\n}\n\nfunction formatIssueLabel(label: string): string {\n const normalizedLabel = label.trim().replace(/^@+/, \"\").trim();\n return normalizedLabel ? `@Task · ${normalizedLabel}` : label.trim();\n}\n\nfunction unescapeMarkdownLabel(label: string): string {\n return label.replace(MARKDOWN_LABEL_ESCAPE_PATTERN, \"$1\");\n}\n","import type { AgentProvider } from \"./agentSettings\";\n\nexport const AGENT_PROVIDER_LABEL: Record<AgentProvider, string> = {\n \"claude-code\": \"Claude Code\",\n codex: \"Codex\",\n nexight: \"Nexight\",\n opencode: \"OpenCode\",\n gemini: \"Gemini CLI\",\n openclaw: \"OpenClaw\",\n hermes: \"Hermes Agent\"\n};\n\nexport interface AgentProviderCapabilities {\n runtimeObservation: \"jsonl\" | \"provider-api\" | \"none\";\n experimental: boolean;\n}\n\nexport const AGENT_PROVIDER_CAPABILITIES: Record<\n AgentProvider,\n AgentProviderCapabilities\n> = {\n \"claude-code\": {\n runtimeObservation: \"jsonl\",\n experimental: false\n },\n codex: {\n runtimeObservation: \"jsonl\",\n experimental: false\n },\n nexight: {\n runtimeObservation: \"jsonl\",\n experimental: false\n },\n opencode: {\n runtimeObservation: \"provider-api\",\n experimental: false\n },\n gemini: {\n runtimeObservation: \"none\",\n experimental: false\n },\n openclaw: {\n runtimeObservation: \"jsonl\",\n experimental: false\n },\n hermes: {\n runtimeObservation: \"jsonl\",\n experimental: false\n }\n};\n","import { AGENT_PROVIDER_LABEL } from \"../contexts/settings/domain/agentSettings.providerMeta.ts\";\nimport type { UiLanguage } from \"../contexts/settings/domain/agentSettings.ts\";\nimport { translateInUiLanguage } from \"../i18n/runtime.ts\";\nimport type { AgentGUIProvider } from \"../types.ts\";\nimport type { WorkspaceAgentActivityTimelineItem } from \"./workspaceAgentActivityTypes.ts\";\nimport { formatAgentSessionMentionText } from \"./utils/agentSessionMentionText.ts\";\nimport { normalizeAgentTitleText } from \"./utils/agentTitleText.ts\";\n\nexport type AgentGUIResolvedProvider = AgentGUIProvider | \"unknown\";\nexport type AgentGUIConversationTitleFallback = \"generic-agent\" | null;\n\nexport interface AgentGUIConversationPlainTitleOptions {\n fallbackAgentLabel?: string;\n language?: UiLanguage;\n}\n\nexport interface AgentGUIConversationTitleMessage {\n id?: number | string | null;\n messageId?: string | null;\n version?: number | null;\n role?: string | null;\n kind?: string | null;\n payload?: {\n content?: unknown;\n displayPrompt?: unknown;\n text?: unknown;\n } | null;\n occurredAtUnixMs?: number | null;\n completedAtUnixMs?: number | null;\n startedAtUnixMs?: number | null;\n}\n\nexport function normalizeAgentGUIProviderIdentity(\n provider: string | null | undefined\n): AgentGUIResolvedProvider {\n switch (provider?.trim().toLowerCase() ?? \"\") {\n case \"claude-code\":\n case \"claude\":\n case \"claude code\":\n return \"claude-code\";\n case \"codex\":\n return \"codex\";\n case \"nexight\":\n case \"tutti\":\n return \"nexight\";\n case \"gemini\":\n return \"gemini\";\n case \"hermes\":\n return \"hermes\";\n case \"openclaw\":\n return \"openclaw\";\n default:\n return \"unknown\";\n }\n}\n\nexport function resolveAgentGUIProviderIdentity(input: {\n sessionProvider?: string | null;\n workspaceSessionProvider?: string | null;\n conversationProvider?: string | null;\n timelineItems?: readonly WorkspaceAgentActivityTimelineItem[];\n}): AgentGUIResolvedProvider {\n const candidates = [\n input.sessionProvider,\n input.workspaceSessionProvider,\n input.conversationProvider,\n timelineProviderHint(input.timelineItems ?? [])\n ];\n for (const candidate of candidates) {\n const normalized = normalizeAgentGUIProviderIdentity(candidate);\n if (normalized !== \"unknown\") {\n return normalized;\n }\n }\n return \"unknown\";\n}\n\nexport function resolveAgentGUIConversationTitle(\n title: string | null | undefined,\n provider: AgentGUIResolvedProvider\n): {\n title: string;\n titleFallback: AgentGUIConversationTitleFallback;\n} {\n const normalizedTitle = stripAgentGUITitleTrailingPeriod(\n normalizeAgentTitleText(title)\n );\n if (normalizedTitle) {\n return {\n title: normalizedTitle,\n titleFallback: null\n };\n }\n if (provider === \"unknown\") {\n return {\n title: \"\",\n titleFallback: \"generic-agent\"\n };\n }\n return {\n title: AGENT_PROVIDER_LABEL[provider],\n titleFallback: null\n };\n}\n\nexport function resolveAgentGUIConversationDisplayTitle(\n input: {\n title: string;\n titleFallback?: AgentGUIConversationTitleFallback;\n },\n fallbackAgentLabel: string\n): string {\n if (input.title) {\n return stripAgentGUITitleTrailingPeriod(\n normalizeAgentTitleText(input.title)\n );\n }\n if (input.titleFallback === \"generic-agent\") {\n return stripAgentGUITitleTrailingPeriod(fallbackAgentLabel);\n }\n return \"\";\n}\n\nexport function formatAgentGUIConversationPlainTitle(\n input: {\n title: string;\n titleFallback?: AgentGUIConversationTitleFallback;\n },\n options: AgentGUIConversationPlainTitleOptions = {}\n): string {\n return formatAgentSessionMentionText(\n resolveAgentGUIConversationDisplayTitle(\n input,\n options.fallbackAgentLabel ?? \"Agent\"\n ),\n {\n language: options.language\n }\n );\n}\n\nexport function resolveAgentGUIDockConversationTitle(input: {\n provider: AgentGUIResolvedProvider;\n title: string;\n titleFallback?: AgentGUIConversationTitleFallback;\n}): string | null {\n return resolveAgentGUIExplicitConversationTitle(input);\n}\n\nexport function resolveAgentGUIExplicitConversationTitle(input: {\n provider: AgentGUIResolvedProvider;\n title: string;\n titleFallback?: AgentGUIConversationTitleFallback;\n}): string | null {\n if (input.titleFallback) {\n return null;\n }\n\n const title = stripAgentGUITitleTrailingPeriod(\n normalizeAgentTitleText(input.title)\n );\n if (!title) {\n return null;\n }\n if (isAgentGUIUntitledTaskTitle(title)) {\n return null;\n }\n\n if (\n input.provider !== \"unknown\" &&\n title === AGENT_PROVIDER_LABEL[input.provider]\n ) {\n return null;\n }\n\n return title;\n}\n\nexport function resolveAgentGUIProviderDisplayLabel(\n provider: string | null | undefined,\n fallbackAgentLabel: string\n): string {\n const resolvedProvider = normalizeAgentGUIProviderIdentity(provider);\n if (resolvedProvider === \"unknown\") {\n return fallbackAgentLabel;\n }\n return AGENT_PROVIDER_LABEL[resolvedProvider];\n}\n\nexport function firstAgentGUIUserMessageTitle(\n messages: readonly AgentGUIConversationTitleMessage[]\n): string {\n const userMessage = [...messages]\n .filter(\n (message) =>\n messageRole(message) === \"user\" && messageText(message).length > 0\n )\n .sort(compareMessagesAscending)[0];\n return userMessage ? messageText(userMessage) : \"\";\n}\n\nfunction messageRole(\n message: AgentGUIConversationTitleMessage\n): \"user\" | \"agent\" | null {\n const role = message.role?.trim().toLowerCase();\n if (role === \"user\") {\n return \"user\";\n }\n if (role === \"assistant\" || role === \"agent\") {\n return \"agent\";\n }\n const kind = message.kind?.trim().toLowerCase() ?? \"\";\n if (kind === \"message.user\") {\n return \"user\";\n }\n if (kind === \"message.assistant\" || kind === \"message.agent\") {\n return \"agent\";\n }\n return null;\n}\n\nfunction messageText(message: AgentGUIConversationTitleMessage): string {\n const payload = message.payload;\n const displayPrompt =\n typeof payload?.displayPrompt === \"string\" ? payload.displayPrompt : \"\";\n const text = typeof payload?.text === \"string\" ? payload.text : \"\";\n const content = typeof payload?.content === \"string\" ? payload.content : \"\";\n return normalizeAgentTitleText(displayPrompt || text || content);\n}\n\nfunction compareMessagesAscending(\n left: AgentGUIConversationTitleMessage,\n right: AgentGUIConversationTitleMessage\n): number {\n const leftTime =\n left.occurredAtUnixMs ??\n left.completedAtUnixMs ??\n left.startedAtUnixMs ??\n 0;\n const rightTime =\n right.occurredAtUnixMs ??\n right.completedAtUnixMs ??\n right.startedAtUnixMs ??\n 0;\n const timeDiff = leftTime - rightTime;\n if (timeDiff !== 0) {\n return timeDiff;\n }\n const sequenceDiff =\n messageSequence(left) - messageSequence(right) ||\n (left.messageId ?? \"\").localeCompare(right.messageId ?? \"\");\n return sequenceDiff;\n}\n\nfunction messageSequence(message: AgentGUIConversationTitleMessage): number {\n const numericId =\n typeof message.id === \"number\" && Number.isFinite(message.id)\n ? message.id\n : 0;\n return message.version ?? numericId;\n}\n\nfunction stripAgentGUITitleTrailingPeriod(title: string): string {\n return title\n .trimEnd()\n .replace(/[.。]+$/u, \"\")\n .trimEnd();\n}\n\nfunction isAgentGUIUntitledTaskTitle(title: string): boolean {\n return localizedAgentGUIUntitledTaskLabels().has(compactTitleText(title));\n}\n\nfunction localizedAgentGUIUntitledTaskLabels(): Set<string> {\n return new Set(\n ([\"en\", \"zh-CN\"] as const)\n .map((language) =>\n compactTitleText(\n translateInUiLanguage(\n language,\n \"agentHost.workspaceAgentsUntitledTask\"\n )\n )\n )\n .filter(Boolean)\n );\n}\n\nfunction timelineProviderHint(\n timelineItems: readonly WorkspaceAgentActivityTimelineItem[]\n): string | null {\n for (const item of timelineItems) {\n if (isUserTimelineItem(item)) {\n continue;\n }\n const normalized = normalizeAgentGUIProviderIdentity(item.actorId);\n if (normalized !== \"unknown\") {\n return normalized;\n }\n }\n return null;\n}\n\nfunction isUserTimelineItem(item: WorkspaceAgentActivityTimelineItem): boolean {\n const role = item.role?.trim().toLowerCase();\n if (role === \"user\") {\n return true;\n }\n const actorType = item.actorType.trim().toLowerCase();\n if (actorType === \"user\") {\n return true;\n }\n return item.itemType.trim().toLowerCase() === \"message.user\";\n}\n\nfunction compactTitleText(value: string): string {\n return value.trim().replace(/\\s+/g, \" \");\n}\n"],"mappings":"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","names":[]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  translate,
3
3
  useTranslation
4
- } from "./chunk-IGXC7NRW.js";
4
+ } from "./chunk-EIC7XS3C.js";
5
5
  import {
6
6
  resolveAgentMentionFileThumbnailUrl,
7
7
  resolveAgentMentionFileVisualKind
@@ -28,6 +28,11 @@ import {
28
28
  TruncatingPillLabel
29
29
  } from "@tutti-os/ui-system/components";
30
30
  import { CloseIcon } from "@tutti-os/ui-system/icons";
31
+
32
+ // agent-gui/agentGuiNode/agentRichText/agentRichTextCaretAnchor.ts
33
+ var AGENT_RICH_TEXT_CARET_ANCHOR = "\u200B";
34
+
35
+ // agent-gui/agentGuiNode/agentRichText/AgentMentionNodeView.tsx
31
36
  import { jsx, jsxs } from "react/jsx-runtime";
32
37
  function parseFileCountAttr(value) {
33
38
  const parsed = typeof value === "string" ? Number.parseInt(value.trim(), 10) : Number.NaN;
@@ -194,7 +199,7 @@ function hasPromptContentAfterMentionRemoval(doc) {
194
199
  hasContent = true;
195
200
  return false;
196
201
  }
197
- if (node.isText && node.textContent.trim().length > 0) {
202
+ if (node.isText && node.textContent.replaceAll(AGENT_RICH_TEXT_CARET_ANCHOR, "").trim().length > 0) {
198
203
  hasContent = true;
199
204
  return false;
200
205
  }
@@ -241,7 +246,7 @@ function AgentMentionLegacyFileNodeView({
241
246
  {
242
247
  as: "span",
243
248
  "aria-label": mention.ariaLabel,
244
- className: `group tsh-agent-object-token tsh-agent-object-token--file ${selected ? "is-selected" : ""}`,
249
+ className: `agent-rich-text-mention-node group tsh-agent-object-token tsh-agent-object-token--file ${selected ? "is-selected" : ""}`,
245
250
  contentEditable: false,
246
251
  "data-agent-file-directory-path": mention.directoryPath,
247
252
  "data-agent-file-entry-kind": mention.entryKind,
@@ -356,7 +361,7 @@ function AgentMentionNodeView(props) {
356
361
  {
357
362
  as: "span",
358
363
  "aria-label": mention.ariaLabel,
359
- className: `inline-flex max-w-[min(100%,var(--agent-mention-max-width,16rem))] align-baseline ${selected ? "is-selected" : ""}`,
364
+ className: `agent-rich-text-mention-node inline-flex max-w-[min(100%,var(--agent-mention-max-width,16rem))] align-middle ${selected ? "is-selected" : ""}`,
360
365
  contentEditable: false,
361
366
  "data-agent-file-mention": "true",
362
367
  "data-agent-mention-href": mention.href,
@@ -365,7 +370,7 @@ function AgentMentionNodeView(props) {
365
370
  children: /* @__PURE__ */ jsxs(
366
371
  "span",
367
372
  {
368
- className: "group relative top-[3px] inline-flex max-w-[min(100%,var(--agent-mention-max-width,16rem))] cursor-pointer items-center gap-1 overflow-hidden rounded-[4px] border border-transparent bg-transparent px-1 py-0.5 align-baseline text-[13px] font-medium leading-5 text-[var(--accent)] no-underline transition-colors hover:border-transparent hover:bg-[color-mix(in_srgb,currentColor_12%,transparent)]",
373
+ className: "group relative top-0 inline-flex max-w-[min(100%,var(--agent-mention-max-width,16rem))] cursor-pointer items-center gap-1 overflow-hidden rounded-[4px] border border-transparent bg-transparent px-1 py-0 align-middle text-[13px] font-medium leading-6 text-[var(--accent)] no-underline transition-colors hover:border-transparent hover:bg-[color-mix(in_srgb,currentColor_12%,transparent)]",
369
374
  "data-agent-mention-kind": mention.kind,
370
375
  "data-slot": "mention-pill",
371
376
  children: [
@@ -417,12 +422,13 @@ function AgentMentionNodeView(props) {
417
422
  NodeViewWrapper,
418
423
  {
419
424
  as: "span",
420
- className: `inline-flex max-w-[min(100%,var(--agent-mention-max-width,16rem))] align-baseline ${selected ? "is-selected" : ""}`,
425
+ className: `agent-rich-text-mention-node inline-flex max-w-[min(100%,var(--agent-mention-max-width,16rem))] align-middle ${selected ? "is-selected" : ""}`,
421
426
  contentEditable: false,
422
427
  children: /* @__PURE__ */ jsx(
423
428
  MentionPill,
424
429
  {
425
430
  "aria-label": mention.ariaLabel,
431
+ className: "top-0 h-6 py-0 align-middle leading-6",
426
432
  "data-agent-mention-href": mention.href,
427
433
  "data-agent-mention-kind": mention.kind,
428
434
  kind: mention.kind === "session" ? "session" : "issue",
@@ -644,7 +650,19 @@ function createAgentFileMentionExtension(options = {}) {
644
650
  return isRichTextTriggerPrefixBoundary(previous, "whitespace");
645
651
  },
646
652
  command: ({ editor, range, props }) => {
653
+ const prefixCaretAnchor = range.from <= 1 || editor.state.doc.textBetween(
654
+ Math.max(1, range.from - 1),
655
+ range.from,
656
+ "\n",
657
+ "\n"
658
+ ) === "\n";
647
659
  editor.chain().focus().insertContentAt(range, [
660
+ ...prefixCaretAnchor ? [
661
+ {
662
+ type: "text",
663
+ text: AGENT_RICH_TEXT_CARET_ANCHOR
664
+ }
665
+ ] : [],
648
666
  {
649
667
  type: this.name,
650
668
  attrs: mentionItemToAttrs(props)
@@ -1196,6 +1214,7 @@ function dirnameFromPath2(path) {
1196
1214
  }
1197
1215
 
1198
1216
  export {
1217
+ AGENT_RICH_TEXT_CARET_ANCHOR,
1199
1218
  exitAgentFileMentionSuggestion,
1200
1219
  createAgentFileMentionExtension,
1201
1220
  normalizeAgentSessionMentionTitle,
@@ -1205,4 +1224,4 @@ export {
1205
1224
  mentionItemToAttrs,
1206
1225
  attrsToMentionItem
1207
1226
  };
1208
- //# sourceMappingURL=chunk-64OSXJRE.js.map
1227
+ //# sourceMappingURL=chunk-FRG36S6N.js.map