@tutti-os/agent-gui 0.0.12 → 0.0.14
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.
- package/dist/agent-conversation/index.d.ts +5 -52
- package/dist/agent-conversation/index.js +4 -3
- package/dist/agent-conversation/index.js.map +1 -1
- package/dist/agent-message-center/index.d.ts +15 -5
- package/dist/agent-message-center/index.js +47 -28
- package/dist/agent-message-center/index.js.map +1 -1
- package/dist/{agentConversationVM-BtHYOTgv.d.ts → agentConversationVM-BVe64P2E.d.ts} +1 -1
- package/dist/app/renderer/agentactivity.css +111 -134
- package/dist/app/renderer/assets/icons/agents/manage-agent-tutti.png +0 -0
- package/dist/app/renderer/assets/icons/agents/tutti-doc-rounded.png +0 -0
- package/dist/app/renderer/assets/icons/agents/workspace-dock-agent-nexight.png +0 -0
- package/dist/chunk-3YZX5EUC.js +1993 -0
- package/dist/chunk-3YZX5EUC.js.map +1 -0
- package/dist/{chunk-QU4F2RSS.js → chunk-ASAZDEQE.js} +7 -7
- package/dist/chunk-ASAZDEQE.js.map +1 -0
- package/dist/{chunk-Y3AQGWJA.js → chunk-FSTZDNRM.js} +43 -3
- package/dist/chunk-FSTZDNRM.js.map +1 -0
- package/dist/{chunk-72YSPOHX.js → chunk-GZHQPPK2.js} +626 -1915
- package/dist/chunk-GZHQPPK2.js.map +1 -0
- package/dist/{chunk-Y5O7BVGU.js → chunk-HSXDSFKB.js} +10 -1123
- package/dist/chunk-HSXDSFKB.js.map +1 -0
- package/dist/{chunk-PKCJR6GC.js → chunk-KEKPOVQD.js} +14 -7
- package/dist/chunk-KEKPOVQD.js.map +1 -0
- package/dist/{chunk-4ASBZ4X7.js → chunk-MTFSQWZ6.js} +2 -2
- package/dist/chunk-MU2LODEV.js +1211 -0
- package/dist/chunk-MU2LODEV.js.map +1 -0
- package/dist/{chunk-R5Q2UDDH.js → chunk-Q75AK47T.js} +2 -2
- package/dist/{chunk-PONEQEJ5.js → chunk-RLPVFX7V.js} +137 -31
- package/dist/chunk-RLPVFX7V.js.map +1 -0
- package/dist/chunk-VDNMTW2E.js +9 -0
- package/dist/chunk-VDNMTW2E.js.map +1 -0
- package/dist/chunk-WME2V26J.js +1124 -0
- package/dist/chunk-WME2V26J.js.map +1 -0
- package/dist/chunk-YXSO4ITT.js +10 -0
- package/dist/chunk-YXSO4ITT.js.map +1 -0
- package/dist/{chunk-3735XYFZ.js → chunk-ZO3SZCIX.js} +54 -3
- package/dist/chunk-ZO3SZCIX.js.map +1 -0
- package/dist/context-mention-palette/index.d.ts +203 -0
- package/dist/context-mention-palette/index.js +30 -0
- package/dist/context-mention-provider.d.ts +51 -0
- package/dist/context-mention-provider.js +7 -0
- package/dist/context-mention-provider.js.map +1 -0
- package/dist/i18n/index.d.ts +42 -2
- package/dist/i18n/index.js +1 -1
- package/dist/index.d.ts +33 -6
- package/dist/index.js +2486 -3690
- package/dist/index.js.map +1 -1
- package/dist/plan-decision-ops.d.ts +2 -2
- package/dist/workbench/contribution.js +5 -5
- package/dist/workbench/index.d.ts +2 -2
- package/dist/workbench/index.js +10 -6
- package/dist/workbench/launch.d.ts +19 -2
- package/dist/workbench/launch.js +7 -2
- package/dist/workbench/types.d.ts +6 -1
- package/dist/workbench/types.js +5 -3
- package/dist/workspace-agent-generated-files.d.ts +1 -1
- package/dist/workspace-agent-generated-files.js +2 -2
- package/dist/{workspaceAgentActivityListViewModel-BLLYGuFO.d.ts → workspaceAgentActivityListViewModel-BK_J3aNX.d.ts} +8 -5
- package/dist/{workspaceLinkActions-Bwa-phu8.d.ts → workspaceLinkActions-BlLN8Pvz.d.ts} +7 -1
- package/package.json +24 -15
- package/dist/agent-rich-text-at-provider.d.ts +0 -49
- package/dist/agent-rich-text-at-provider.js +0 -7
- package/dist/chunk-3735XYFZ.js.map +0 -1
- package/dist/chunk-6AZ2KF6R.js +0 -7
- package/dist/chunk-6AZ2KF6R.js.map +0 -1
- package/dist/chunk-72YSPOHX.js.map +0 -1
- package/dist/chunk-KCC3GNPB.js +0 -13
- package/dist/chunk-KCC3GNPB.js.map +0 -1
- package/dist/chunk-PKCJR6GC.js.map +0 -1
- package/dist/chunk-PONEQEJ5.js.map +0 -1
- package/dist/chunk-QU4F2RSS.js.map +0 -1
- package/dist/chunk-Y3AQGWJA.js.map +0 -1
- package/dist/chunk-Y5O7BVGU.js.map +0 -1
- /package/dist/{chunk-4ASBZ4X7.js.map → chunk-MTFSQWZ6.js.map} +0 -0
- /package/dist/{chunk-R5Q2UDDH.js.map → chunk-Q75AK47T.js.map} +0 -0
- /package/dist/{agent-rich-text-at-provider.js.map → context-mention-palette/index.js.map} +0 -0
|
@@ -0,0 +1,1211 @@
|
|
|
1
|
+
import {
|
|
2
|
+
translate,
|
|
3
|
+
useTranslation
|
|
4
|
+
} from "./chunk-FSTZDNRM.js";
|
|
5
|
+
import {
|
|
6
|
+
resolveAgentMentionFileThumbnailUrl,
|
|
7
|
+
resolveAgentMentionFileVisualKind
|
|
8
|
+
} from "./chunk-LUGELG5V.js";
|
|
9
|
+
|
|
10
|
+
// agent-gui/agentGuiNode/agentRichText/agentFileMentionExtension.ts
|
|
11
|
+
import { mergeAttributes, Node } from "@tiptap/core";
|
|
12
|
+
import { PluginKey } from "@tiptap/pm/state";
|
|
13
|
+
import { ReactNodeViewRenderer } from "@tiptap/react";
|
|
14
|
+
import Suggestion, { exitSuggestion } from "@tiptap/suggestion";
|
|
15
|
+
import { isRichTextTriggerPrefixBoundary } from "@tutti-os/ui-rich-text/editor";
|
|
16
|
+
|
|
17
|
+
// agent-gui/agentGuiNode/agentRichText/AgentMentionNodeView.tsx
|
|
18
|
+
import { useEffect, useState } from "react";
|
|
19
|
+
import { NodeViewWrapper } from "@tiptap/react";
|
|
20
|
+
import { MentionPill } from "@tutti-os/ui-system/components";
|
|
21
|
+
import { CloseIcon } from "@tutti-os/ui-system/icons";
|
|
22
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
23
|
+
function attrString(attrs, key) {
|
|
24
|
+
const value = attrs[key];
|
|
25
|
+
return typeof value === "string" ? value : "";
|
|
26
|
+
}
|
|
27
|
+
function normalizeKind(value) {
|
|
28
|
+
if (value === "session" || value === "agent-session") {
|
|
29
|
+
return "session";
|
|
30
|
+
}
|
|
31
|
+
if (value === "workspace-issue") {
|
|
32
|
+
return "workspace-issue";
|
|
33
|
+
}
|
|
34
|
+
if (value === "workspace-app") {
|
|
35
|
+
return "workspace-app";
|
|
36
|
+
}
|
|
37
|
+
if (value === "workspace-app-factory") {
|
|
38
|
+
return "workspace-app-factory";
|
|
39
|
+
}
|
|
40
|
+
return "file";
|
|
41
|
+
}
|
|
42
|
+
function buildMentionHref(resource, attrs) {
|
|
43
|
+
const workspaceId = attrString(attrs, "workspaceId").trim();
|
|
44
|
+
const targetId = attrString(attrs, "targetId").trim();
|
|
45
|
+
if (resource === "workspace-issue") {
|
|
46
|
+
return buildAgentGenericMentionHref(resource, targetId, {
|
|
47
|
+
topicId: attrString(attrs, "topicId").trim(),
|
|
48
|
+
workspaceId
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
if (resource === "workspace-app") {
|
|
52
|
+
const appId = attrString(attrs, "appId").trim() || targetId;
|
|
53
|
+
return buildAgentGenericMentionHref(resource, appId, { workspaceId });
|
|
54
|
+
}
|
|
55
|
+
if (resource === "workspace-app-factory") {
|
|
56
|
+
const jobId = attrString(attrs, "jobId").trim() || targetId;
|
|
57
|
+
return buildAgentGenericMentionHref(resource, jobId || "create", {
|
|
58
|
+
action: attrString(attrs, "action").trim(),
|
|
59
|
+
contextPath: attrString(attrs, "contextPath").trim(),
|
|
60
|
+
workspaceId
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return buildAgentGenericMentionHref(resource, targetId, { workspaceId });
|
|
64
|
+
}
|
|
65
|
+
function buildAgentGenericMentionHref(providerId, entityId, scope) {
|
|
66
|
+
const normalizedProviderId = providerId.trim();
|
|
67
|
+
const normalizedEntityId = entityId.trim();
|
|
68
|
+
if (!normalizedProviderId || !normalizedEntityId) {
|
|
69
|
+
return "";
|
|
70
|
+
}
|
|
71
|
+
const params = new URLSearchParams();
|
|
72
|
+
Object.entries(scope ?? {}).map(([key, value]) => [key.trim(), value?.trim() ?? ""]).filter(([key, value]) => key && value).sort(([left], [right]) => left.localeCompare(right)).forEach(([key, value]) => {
|
|
73
|
+
params.set(key, value);
|
|
74
|
+
});
|
|
75
|
+
const query = params.toString();
|
|
76
|
+
const href = `mention://${encodeURIComponent(
|
|
77
|
+
normalizedProviderId
|
|
78
|
+
)}/${encodeURIComponent(normalizedEntityId)}`;
|
|
79
|
+
return query ? `${href}?${query}` : href;
|
|
80
|
+
}
|
|
81
|
+
function normalizeSessionTitle(value) {
|
|
82
|
+
const trimmed = value.trim();
|
|
83
|
+
const withoutMentionPrefix = trimmed.replace(/^@+/, "").trim();
|
|
84
|
+
return withoutMentionPrefix || trimmed;
|
|
85
|
+
}
|
|
86
|
+
function parseDottedSessionText(value) {
|
|
87
|
+
const parts = value.split("\xB7").map((part) => part.trim()).filter(Boolean);
|
|
88
|
+
if (parts.length < 3) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
participant: `${parts[0]} & ${parts[1]}`,
|
|
93
|
+
summary: normalizeSessionTitle(parts.slice(2).join(" "))
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function sessionPresentation(attrs) {
|
|
97
|
+
const name = attrString(attrs, "name").trim();
|
|
98
|
+
const initiatorName = attrString(attrs, "initiatorName").trim();
|
|
99
|
+
const agentName = attrString(attrs, "agentName").trim();
|
|
100
|
+
const title = normalizeSessionTitle(attrString(attrs, "title") || name);
|
|
101
|
+
const inputPreview = attrString(attrs, "inputPreview").trim();
|
|
102
|
+
if (initiatorName && agentName) {
|
|
103
|
+
const dottedTitle = parseDottedSessionText(title);
|
|
104
|
+
return {
|
|
105
|
+
// i18n-check-ignore: Dynamic participant display names.
|
|
106
|
+
label: `${initiatorName} & ${agentName}`,
|
|
107
|
+
summary: dottedTitle?.summary || (title && title !== name ? title : inputPreview)
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
const dottedName = parseDottedSessionText(name);
|
|
111
|
+
if (dottedName) {
|
|
112
|
+
return {
|
|
113
|
+
label: dottedName.participant,
|
|
114
|
+
summary: dottedName.summary
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
label: name,
|
|
119
|
+
summary: title && title !== name ? title : inputPreview
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function dirnameFromPath(path) {
|
|
123
|
+
const parts = path.split("/").filter(Boolean);
|
|
124
|
+
if (parts.length <= 1) {
|
|
125
|
+
return path.startsWith("/") ? "/" : "";
|
|
126
|
+
}
|
|
127
|
+
return `/${parts.slice(0, -1).join("/")}`;
|
|
128
|
+
}
|
|
129
|
+
function mentionViewModel(attrs, t) {
|
|
130
|
+
const kind = normalizeKind(attrString(attrs, "kind"));
|
|
131
|
+
const name = attrString(attrs, "name");
|
|
132
|
+
const href = attrString(attrs, "href");
|
|
133
|
+
if (kind === "session") {
|
|
134
|
+
const presentation = sessionPresentation(attrs);
|
|
135
|
+
const primary = `${presentation.label} ${presentation.summary}`.trim();
|
|
136
|
+
return {
|
|
137
|
+
ariaLabel: `${t("agentHost.agentGui.mentionKindSession")} ${primary}`.trim(),
|
|
138
|
+
directoryPath: "",
|
|
139
|
+
entryKind: "",
|
|
140
|
+
href: href || buildMentionHref("agent-session", attrs),
|
|
141
|
+
kind,
|
|
142
|
+
label: presentation.label,
|
|
143
|
+
summary: presentation.summary
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
if (kind === "workspace-issue") {
|
|
147
|
+
return {
|
|
148
|
+
ariaLabel: `${t("agentHost.agentGui.mentionKindIssue")} ${name}`.trim(),
|
|
149
|
+
directoryPath: "",
|
|
150
|
+
entryKind: "",
|
|
151
|
+
href: href || buildMentionHref("workspace-issue", attrs),
|
|
152
|
+
kind,
|
|
153
|
+
label: name
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
if (kind === "workspace-app") {
|
|
157
|
+
return {
|
|
158
|
+
ariaLabel: `${t("agentHost.agentGui.mentionKindApp")} ${name}`.trim(),
|
|
159
|
+
directoryPath: "",
|
|
160
|
+
entryKind: "",
|
|
161
|
+
href: href || buildMentionHref("workspace-app", attrs),
|
|
162
|
+
iconUrl: attrString(attrs, "iconUrl").trim() || void 0,
|
|
163
|
+
kind,
|
|
164
|
+
label: name
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
if (kind === "workspace-app-factory") {
|
|
168
|
+
return {
|
|
169
|
+
ariaLabel: `${t("agentHost.agentGui.mentionKindAppFactory")} ${name}`.trim(),
|
|
170
|
+
directoryPath: "",
|
|
171
|
+
entryKind: "",
|
|
172
|
+
href: href || buildMentionHref("workspace-app-factory", attrs),
|
|
173
|
+
kind,
|
|
174
|
+
label: name
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
const path = attrString(attrs, "path") || href;
|
|
178
|
+
const entryKind = attrString(attrs, "entryKind") || "unknown";
|
|
179
|
+
return {
|
|
180
|
+
ariaLabel: name,
|
|
181
|
+
directoryPath: attrString(attrs, "directoryPath") || dirnameFromPath(path),
|
|
182
|
+
entryKind,
|
|
183
|
+
href: href || path,
|
|
184
|
+
kind,
|
|
185
|
+
label: name,
|
|
186
|
+
thumbnailUrl: resolveAgentMentionFileThumbnailUrl({
|
|
187
|
+
entryKind,
|
|
188
|
+
href: href || path,
|
|
189
|
+
name,
|
|
190
|
+
path,
|
|
191
|
+
thumbnailUrl: attrString(attrs, "thumbnailUrl")
|
|
192
|
+
})
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
function fileVisualKind(entryKind, path) {
|
|
196
|
+
return resolveAgentMentionFileVisualKind({ entryKind, path });
|
|
197
|
+
}
|
|
198
|
+
function hasPromptContentAfterMentionRemoval(doc) {
|
|
199
|
+
let hasContent = false;
|
|
200
|
+
doc.descendants((node) => {
|
|
201
|
+
if (hasContent) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
if (node.type.name === "agentFileMention") {
|
|
205
|
+
hasContent = true;
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
if (node.isText && node.textContent.trim().length > 0) {
|
|
209
|
+
hasContent = true;
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
return true;
|
|
213
|
+
});
|
|
214
|
+
return hasContent;
|
|
215
|
+
}
|
|
216
|
+
function AgentMentionLegacyFileNodeView({
|
|
217
|
+
deleteNode,
|
|
218
|
+
editor,
|
|
219
|
+
extension,
|
|
220
|
+
node,
|
|
221
|
+
selected
|
|
222
|
+
}) {
|
|
223
|
+
const mention = mentionViewModel(node.attrs ?? {}, () => "");
|
|
224
|
+
const [isEditable, setIsEditable] = useState(editor.isEditable);
|
|
225
|
+
const extensionOptions = extension.options;
|
|
226
|
+
const removeActionAriaLabel = typeof extensionOptions.removeActionAriaLabel === "string" ? extensionOptions.removeActionAriaLabel : void 0;
|
|
227
|
+
useEffect(() => {
|
|
228
|
+
const syncEditable = () => {
|
|
229
|
+
setIsEditable(editor.isEditable);
|
|
230
|
+
};
|
|
231
|
+
syncEditable();
|
|
232
|
+
editor.on("transaction", syncEditable);
|
|
233
|
+
editor.on("update", syncEditable);
|
|
234
|
+
return () => {
|
|
235
|
+
editor.off("transaction", syncEditable);
|
|
236
|
+
editor.off("update", syncEditable);
|
|
237
|
+
};
|
|
238
|
+
}, [editor]);
|
|
239
|
+
const handleRemove = (event) => {
|
|
240
|
+
event.preventDefault();
|
|
241
|
+
event.stopPropagation();
|
|
242
|
+
if (!editor.isEditable) {
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
deleteNode();
|
|
246
|
+
if (!hasPromptContentAfterMentionRemoval(editor.state.doc)) {
|
|
247
|
+
editor.commands.clearContent();
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
return /* @__PURE__ */ jsxs(
|
|
251
|
+
NodeViewWrapper,
|
|
252
|
+
{
|
|
253
|
+
as: "span",
|
|
254
|
+
"aria-label": mention.ariaLabel,
|
|
255
|
+
className: `group tsh-agent-object-token tsh-agent-object-token--file ${selected ? "is-selected" : ""}`,
|
|
256
|
+
contentEditable: false,
|
|
257
|
+
"data-agent-file-directory-path": mention.directoryPath,
|
|
258
|
+
"data-agent-file-entry-kind": mention.entryKind,
|
|
259
|
+
"data-agent-file-mention": "true",
|
|
260
|
+
...mention.thumbnailUrl ? {} : {
|
|
261
|
+
"data-agent-file-visual-kind": fileVisualKind(
|
|
262
|
+
mention.entryKind,
|
|
263
|
+
mention.href || mention.label
|
|
264
|
+
)
|
|
265
|
+
},
|
|
266
|
+
"data-agent-mention-href": mention.href,
|
|
267
|
+
"data-agent-mention-kind": mention.kind,
|
|
268
|
+
...mention.thumbnailUrl ? { "data-agent-mention-thumbnail-url": mention.thumbnailUrl } : {},
|
|
269
|
+
children: [
|
|
270
|
+
mention.thumbnailUrl ? /* @__PURE__ */ jsxs(
|
|
271
|
+
"span",
|
|
272
|
+
{
|
|
273
|
+
className: "agent-gui-node__mention-file-thumb relative",
|
|
274
|
+
"data-agent-mention-file-thumb": "true",
|
|
275
|
+
"aria-hidden": isEditable ? void 0 : true,
|
|
276
|
+
children: [
|
|
277
|
+
/* @__PURE__ */ jsx(
|
|
278
|
+
"img",
|
|
279
|
+
{
|
|
280
|
+
src: mention.thumbnailUrl,
|
|
281
|
+
alt: "",
|
|
282
|
+
className: `h-full w-full object-cover transition-opacity ${isEditable ? "group-hover:opacity-0 group-focus-within:opacity-0" : ""}`,
|
|
283
|
+
decoding: "async",
|
|
284
|
+
loading: "lazy",
|
|
285
|
+
draggable: false
|
|
286
|
+
}
|
|
287
|
+
),
|
|
288
|
+
isEditable ? /* @__PURE__ */ jsx(
|
|
289
|
+
"button",
|
|
290
|
+
{
|
|
291
|
+
"aria-label": removeActionAriaLabel,
|
|
292
|
+
className: "absolute left-1/2 top-1/2 inline-flex size-5 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-sm text-[var(--text-secondary)] opacity-0 transition-opacity hover:bg-transparency-block hover:text-[var(--text-primary)] focus-visible:opacity-100 group-hover:opacity-100",
|
|
293
|
+
type: "button",
|
|
294
|
+
onMouseDown: handleRemove,
|
|
295
|
+
children: /* @__PURE__ */ jsx(CloseIcon, { className: "size-3.5" })
|
|
296
|
+
}
|
|
297
|
+
) : null
|
|
298
|
+
]
|
|
299
|
+
}
|
|
300
|
+
) : /* @__PURE__ */ jsxs(
|
|
301
|
+
"span",
|
|
302
|
+
{
|
|
303
|
+
className: "relative grid size-4 shrink-0 place-items-center",
|
|
304
|
+
"aria-hidden": isEditable ? void 0 : true,
|
|
305
|
+
children: [
|
|
306
|
+
/* @__PURE__ */ jsx(
|
|
307
|
+
"span",
|
|
308
|
+
{
|
|
309
|
+
className: `tsh-agent-object-token__icon transition-opacity ${isEditable ? "group-hover:opacity-0 group-focus-within:opacity-0" : ""}`,
|
|
310
|
+
"aria-hidden": "true"
|
|
311
|
+
}
|
|
312
|
+
),
|
|
313
|
+
isEditable ? /* @__PURE__ */ jsx(
|
|
314
|
+
"button",
|
|
315
|
+
{
|
|
316
|
+
"aria-label": removeActionAriaLabel,
|
|
317
|
+
className: "absolute left-1/2 top-1/2 inline-flex size-5 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-sm text-[var(--text-secondary)] opacity-0 transition-opacity hover:bg-transparency-block hover:text-[var(--text-primary)] focus-visible:opacity-100 group-hover:opacity-100",
|
|
318
|
+
type: "button",
|
|
319
|
+
onMouseDown: handleRemove,
|
|
320
|
+
children: /* @__PURE__ */ jsx(CloseIcon, { className: "size-3.5" })
|
|
321
|
+
}
|
|
322
|
+
) : null
|
|
323
|
+
]
|
|
324
|
+
}
|
|
325
|
+
),
|
|
326
|
+
/* @__PURE__ */ jsx("span", { className: "tsh-agent-object-token__main", children: mention.label })
|
|
327
|
+
]
|
|
328
|
+
}
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
function AgentMentionNodeView(props) {
|
|
332
|
+
const { deleteNode, editor, extension, node, selected } = props;
|
|
333
|
+
const { t } = useTranslation();
|
|
334
|
+
const mention = mentionViewModel(node.attrs ?? {}, t);
|
|
335
|
+
const [isEditable, setIsEditable] = useState(editor.isEditable);
|
|
336
|
+
const extensionOptions = extension.options;
|
|
337
|
+
const removeActionAriaLabel = typeof extensionOptions.removeActionAriaLabel === "string" ? extensionOptions.removeActionAriaLabel : void 0;
|
|
338
|
+
useEffect(() => {
|
|
339
|
+
const syncEditable = () => {
|
|
340
|
+
setIsEditable(editor.isEditable);
|
|
341
|
+
};
|
|
342
|
+
syncEditable();
|
|
343
|
+
editor.on("transaction", syncEditable);
|
|
344
|
+
editor.on("update", syncEditable);
|
|
345
|
+
return () => {
|
|
346
|
+
editor.off("transaction", syncEditable);
|
|
347
|
+
editor.off("update", syncEditable);
|
|
348
|
+
};
|
|
349
|
+
}, [editor]);
|
|
350
|
+
const handleRemove = (event) => {
|
|
351
|
+
event.preventDefault();
|
|
352
|
+
event.stopPropagation();
|
|
353
|
+
if (!editor.isEditable) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
deleteNode();
|
|
357
|
+
if (!hasPromptContentAfterMentionRemoval(editor.state.doc)) {
|
|
358
|
+
editor.commands.clearContent();
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
if (mention.kind === "file") {
|
|
362
|
+
return /* @__PURE__ */ jsx(AgentMentionLegacyFileNodeView, { ...props });
|
|
363
|
+
}
|
|
364
|
+
if (mention.kind === "workspace-app") {
|
|
365
|
+
return /* @__PURE__ */ jsx(
|
|
366
|
+
NodeViewWrapper,
|
|
367
|
+
{
|
|
368
|
+
as: "span",
|
|
369
|
+
"aria-label": mention.ariaLabel,
|
|
370
|
+
className: `inline-flex max-w-full align-baseline ${selected ? "is-selected" : ""}`,
|
|
371
|
+
contentEditable: false,
|
|
372
|
+
"data-agent-file-mention": "true",
|
|
373
|
+
"data-agent-mention-href": mention.href,
|
|
374
|
+
"data-agent-mention-icon-url": mention.iconUrl,
|
|
375
|
+
"data-agent-mention-kind": mention.kind,
|
|
376
|
+
children: /* @__PURE__ */ jsxs(
|
|
377
|
+
"span",
|
|
378
|
+
{
|
|
379
|
+
className: "group relative top-[3px] inline-flex max-w-full cursor-default 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)]",
|
|
380
|
+
"data-agent-mention-kind": mention.kind,
|
|
381
|
+
"data-slot": "mention-pill",
|
|
382
|
+
children: [
|
|
383
|
+
/* @__PURE__ */ jsxs(
|
|
384
|
+
"span",
|
|
385
|
+
{
|
|
386
|
+
"aria-hidden": isEditable ? void 0 : true,
|
|
387
|
+
className: "relative grid size-4 shrink-0 place-items-center overflow-hidden rounded-[4px] bg-block",
|
|
388
|
+
"data-agent-mention-app-icon": "true",
|
|
389
|
+
"data-workspace-app-icon": "true",
|
|
390
|
+
children: [
|
|
391
|
+
mention.iconUrl ? /* @__PURE__ */ jsx(
|
|
392
|
+
"img",
|
|
393
|
+
{
|
|
394
|
+
src: mention.iconUrl,
|
|
395
|
+
alt: "",
|
|
396
|
+
className: `size-full object-cover transition-opacity ${isEditable ? "group-hover:opacity-0 group-focus-within:opacity-0" : ""}`,
|
|
397
|
+
decoding: "async",
|
|
398
|
+
loading: "lazy",
|
|
399
|
+
draggable: false
|
|
400
|
+
}
|
|
401
|
+
) : /* @__PURE__ */ jsx(
|
|
402
|
+
"span",
|
|
403
|
+
{
|
|
404
|
+
className: `tsh-agent-object-token__kind-icon size-4 transition-opacity ${isEditable ? "group-hover:opacity-0 group-focus-within:opacity-0" : ""}`
|
|
405
|
+
}
|
|
406
|
+
),
|
|
407
|
+
isEditable ? /* @__PURE__ */ jsx(
|
|
408
|
+
"button",
|
|
409
|
+
{
|
|
410
|
+
"aria-label": removeActionAriaLabel,
|
|
411
|
+
className: "absolute left-1/2 top-1/2 inline-flex size-5 -translate-x-1/2 -translate-y-1/2 items-center justify-center rounded-sm text-[var(--text-secondary)] opacity-0 transition-opacity hover:bg-transparency-block hover:text-[var(--text-primary)] focus-visible:opacity-100 group-hover:opacity-100",
|
|
412
|
+
type: "button",
|
|
413
|
+
onMouseDown: handleRemove,
|
|
414
|
+
children: /* @__PURE__ */ jsx(CloseIcon, { className: "size-3.5" })
|
|
415
|
+
}
|
|
416
|
+
) : null
|
|
417
|
+
]
|
|
418
|
+
}
|
|
419
|
+
),
|
|
420
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 overflow-hidden text-ellipsis whitespace-nowrap", children: mention.label })
|
|
421
|
+
]
|
|
422
|
+
}
|
|
423
|
+
)
|
|
424
|
+
}
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
return /* @__PURE__ */ jsx(
|
|
428
|
+
NodeViewWrapper,
|
|
429
|
+
{
|
|
430
|
+
as: "span",
|
|
431
|
+
className: `inline-flex max-w-full align-baseline ${selected ? "is-selected" : ""}`,
|
|
432
|
+
contentEditable: false,
|
|
433
|
+
children: /* @__PURE__ */ jsx(
|
|
434
|
+
MentionPill,
|
|
435
|
+
{
|
|
436
|
+
"aria-label": mention.ariaLabel,
|
|
437
|
+
"data-agent-mention-href": mention.href,
|
|
438
|
+
"data-agent-mention-kind": mention.kind,
|
|
439
|
+
kind: mention.kind === "session" ? "session" : "issue",
|
|
440
|
+
label: mention.label,
|
|
441
|
+
removable: isEditable,
|
|
442
|
+
removeButtonProps: isEditable ? {
|
|
443
|
+
"aria-label": removeActionAriaLabel,
|
|
444
|
+
onMouseDown: handleRemove
|
|
445
|
+
} : void 0,
|
|
446
|
+
summary: mention.summary
|
|
447
|
+
}
|
|
448
|
+
)
|
|
449
|
+
}
|
|
450
|
+
);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// agent-gui/agentGuiNode/agentRichText/agentFileMentionExtension.ts
|
|
454
|
+
var agentFileMentionPluginKey = new PluginKey(
|
|
455
|
+
"agentFileMentionSuggestion"
|
|
456
|
+
);
|
|
457
|
+
function exitAgentFileMentionSuggestion(editor) {
|
|
458
|
+
exitSuggestion(editor.view, agentFileMentionPluginKey);
|
|
459
|
+
}
|
|
460
|
+
function createAgentFileMentionExtension(options = {}) {
|
|
461
|
+
return Node.create({
|
|
462
|
+
name: "agentFileMention",
|
|
463
|
+
group: "inline",
|
|
464
|
+
inline: true,
|
|
465
|
+
atom: true,
|
|
466
|
+
selectable: false,
|
|
467
|
+
addOptions() {
|
|
468
|
+
return options;
|
|
469
|
+
},
|
|
470
|
+
addAttributes() {
|
|
471
|
+
return {
|
|
472
|
+
name: { default: "" },
|
|
473
|
+
kind: { default: "file" },
|
|
474
|
+
href: { default: "" },
|
|
475
|
+
path: { default: "" },
|
|
476
|
+
entryKind: { default: "unknown" },
|
|
477
|
+
directoryPath: { default: "" },
|
|
478
|
+
workspaceId: { default: "" },
|
|
479
|
+
targetId: { default: "" },
|
|
480
|
+
scope: { default: "" },
|
|
481
|
+
title: { default: "" },
|
|
482
|
+
initiatorName: { default: "" },
|
|
483
|
+
agentName: { default: "" },
|
|
484
|
+
status: { default: "" },
|
|
485
|
+
inputPreview: { default: "" },
|
|
486
|
+
summaryPreview: { default: "" },
|
|
487
|
+
creatorName: { default: "" },
|
|
488
|
+
topicId: { default: "" },
|
|
489
|
+
appId: { default: "" },
|
|
490
|
+
jobId: { default: "" },
|
|
491
|
+
action: { default: "" },
|
|
492
|
+
contextPath: { default: "" },
|
|
493
|
+
description: { default: "" },
|
|
494
|
+
iconUrl: { default: "" },
|
|
495
|
+
contentPreview: { default: "" },
|
|
496
|
+
thumbnailUrl: { default: "" }
|
|
497
|
+
};
|
|
498
|
+
},
|
|
499
|
+
parseHTML() {
|
|
500
|
+
return [
|
|
501
|
+
{
|
|
502
|
+
tag: "span[data-agent-file-mention]",
|
|
503
|
+
getAttrs: parseAgentMentionHTMLElementAttrs
|
|
504
|
+
},
|
|
505
|
+
{
|
|
506
|
+
tag: "a[data-agent-file-mention]",
|
|
507
|
+
getAttrs: parseAgentMentionHTMLElementAttrs
|
|
508
|
+
}
|
|
509
|
+
];
|
|
510
|
+
},
|
|
511
|
+
renderHTML({ HTMLAttributes }) {
|
|
512
|
+
const item = attrsToMentionItem(HTMLAttributes);
|
|
513
|
+
const fileThumbnailUrl = item.kind === "file" ? resolveAgentMentionFileThumbnailUrl(item) : void 0;
|
|
514
|
+
const href = item.href;
|
|
515
|
+
const tagName = options.renderAsLink ? "a" : "span";
|
|
516
|
+
const visual = mentionVisual(item);
|
|
517
|
+
const sessionVisual = item.kind === "session" ? sessionMentionVisual(item) : null;
|
|
518
|
+
const sharedAttributes = {
|
|
519
|
+
"data-agent-file-mention": "true",
|
|
520
|
+
"data-agent-mention-href": href,
|
|
521
|
+
"data-agent-mention-kind": item.kind,
|
|
522
|
+
"aria-label": item.kind === "file" ? visual.primary : `${visual.kindLabel} ${visual.primary}`.trim()
|
|
523
|
+
};
|
|
524
|
+
return [
|
|
525
|
+
tagName,
|
|
526
|
+
mergeAttributes(HTMLAttributes, {
|
|
527
|
+
...sharedAttributes,
|
|
528
|
+
...item.kind === "file" ? {
|
|
529
|
+
"data-agent-file-entry-kind": item.entryKind,
|
|
530
|
+
"data-agent-file-directory-path": item.directoryPath,
|
|
531
|
+
"data-agent-file-visual-kind": resolveAgentMentionFileVisualKind(item)
|
|
532
|
+
} : {},
|
|
533
|
+
...options.renderAsLink ? { href } : {},
|
|
534
|
+
...item.kind === "workspace-app" && item.iconUrl ? { "data-agent-mention-icon-url": item.iconUrl } : {},
|
|
535
|
+
...fileThumbnailUrl ? { "data-agent-mention-thumbnail-url": fileThumbnailUrl } : {},
|
|
536
|
+
class: item.kind === "file" ? "tsh-agent-object-token tsh-agent-object-token--file" : "tsh-agent-object-token tsh-agent-object-token--entity"
|
|
537
|
+
}),
|
|
538
|
+
...item.kind === "file" ? [
|
|
539
|
+
fileThumbnailUrl ? [
|
|
540
|
+
"span",
|
|
541
|
+
{
|
|
542
|
+
class: "agent-gui-node__mention-file-thumb",
|
|
543
|
+
"data-agent-mention-file-thumb": "true",
|
|
544
|
+
"aria-hidden": "true"
|
|
545
|
+
},
|
|
546
|
+
[
|
|
547
|
+
"img",
|
|
548
|
+
{
|
|
549
|
+
src: fileThumbnailUrl,
|
|
550
|
+
alt: "",
|
|
551
|
+
decoding: "async",
|
|
552
|
+
loading: "lazy",
|
|
553
|
+
draggable: "false"
|
|
554
|
+
}
|
|
555
|
+
]
|
|
556
|
+
] : [
|
|
557
|
+
"span",
|
|
558
|
+
{
|
|
559
|
+
class: "tsh-agent-object-token__icon",
|
|
560
|
+
"aria-hidden": "true"
|
|
561
|
+
},
|
|
562
|
+
""
|
|
563
|
+
],
|
|
564
|
+
[
|
|
565
|
+
"span",
|
|
566
|
+
{ class: "tsh-agent-object-token__main" },
|
|
567
|
+
visual.primary
|
|
568
|
+
]
|
|
569
|
+
] : item.kind === "session" ? [
|
|
570
|
+
[
|
|
571
|
+
"span",
|
|
572
|
+
{
|
|
573
|
+
class: "tsh-agent-object-token__kind",
|
|
574
|
+
"aria-hidden": "true"
|
|
575
|
+
},
|
|
576
|
+
[
|
|
577
|
+
"span",
|
|
578
|
+
{
|
|
579
|
+
class: "tsh-agent-object-token__kind-icon",
|
|
580
|
+
"aria-hidden": "true"
|
|
581
|
+
},
|
|
582
|
+
""
|
|
583
|
+
]
|
|
584
|
+
],
|
|
585
|
+
[
|
|
586
|
+
"span",
|
|
587
|
+
{ class: "tsh-agent-object-token__main" },
|
|
588
|
+
[
|
|
589
|
+
"span",
|
|
590
|
+
{ class: "tsh-agent-object-token__participant" },
|
|
591
|
+
sessionVisual?.participant ?? ""
|
|
592
|
+
],
|
|
593
|
+
[
|
|
594
|
+
"span",
|
|
595
|
+
{ class: "tsh-agent-object-token__summary" },
|
|
596
|
+
sessionVisual?.summary ? ` ${sessionVisual.summary}` : ""
|
|
597
|
+
]
|
|
598
|
+
]
|
|
599
|
+
] : [
|
|
600
|
+
[
|
|
601
|
+
"span",
|
|
602
|
+
{
|
|
603
|
+
class: "tsh-agent-object-token__kind",
|
|
604
|
+
"aria-hidden": "true"
|
|
605
|
+
},
|
|
606
|
+
[
|
|
607
|
+
"span",
|
|
608
|
+
{
|
|
609
|
+
class: "tsh-agent-object-token__kind-icon",
|
|
610
|
+
"aria-hidden": "true"
|
|
611
|
+
},
|
|
612
|
+
""
|
|
613
|
+
]
|
|
614
|
+
],
|
|
615
|
+
[
|
|
616
|
+
"span",
|
|
617
|
+
{ class: "tsh-agent-object-token__main" },
|
|
618
|
+
visual.primary
|
|
619
|
+
]
|
|
620
|
+
]
|
|
621
|
+
];
|
|
622
|
+
},
|
|
623
|
+
renderText({ node }) {
|
|
624
|
+
return formatAgentMentionMarkdown(attrsToMentionItem(node.attrs ?? {}));
|
|
625
|
+
},
|
|
626
|
+
addNodeView() {
|
|
627
|
+
return ReactNodeViewRenderer(AgentMentionNodeView);
|
|
628
|
+
},
|
|
629
|
+
addProseMirrorPlugins() {
|
|
630
|
+
if (options.enableSuggestions === false) {
|
|
631
|
+
return [];
|
|
632
|
+
}
|
|
633
|
+
return [
|
|
634
|
+
Suggestion({
|
|
635
|
+
editor: this.editor,
|
|
636
|
+
pluginKey: agentFileMentionPluginKey,
|
|
637
|
+
char: "@",
|
|
638
|
+
allowedPrefixes: [" ", "\n", " "],
|
|
639
|
+
allowSpaces: true,
|
|
640
|
+
items: () => [],
|
|
641
|
+
allow: ({ state, range }) => {
|
|
642
|
+
if (range.from <= 1) {
|
|
643
|
+
return true;
|
|
644
|
+
}
|
|
645
|
+
const previous = state.doc.textBetween(
|
|
646
|
+
range.from - 1,
|
|
647
|
+
range.from,
|
|
648
|
+
"\n",
|
|
649
|
+
"\n"
|
|
650
|
+
);
|
|
651
|
+
return isRichTextTriggerPrefixBoundary(previous, "whitespace");
|
|
652
|
+
},
|
|
653
|
+
command: ({ editor, range, props }) => {
|
|
654
|
+
editor.chain().focus().insertContentAt(range, [
|
|
655
|
+
{
|
|
656
|
+
type: this.name,
|
|
657
|
+
attrs: mentionItemToAttrs(props)
|
|
658
|
+
},
|
|
659
|
+
{ type: "text", text: " " }
|
|
660
|
+
]).run();
|
|
661
|
+
},
|
|
662
|
+
render: () => ({
|
|
663
|
+
onStart: (props) => {
|
|
664
|
+
options.onSuggestionChange?.({
|
|
665
|
+
editor: props.editor,
|
|
666
|
+
range: props.range,
|
|
667
|
+
query: props.query,
|
|
668
|
+
text: props.text,
|
|
669
|
+
command: props.command,
|
|
670
|
+
clientRect: props.clientRect
|
|
671
|
+
});
|
|
672
|
+
},
|
|
673
|
+
onUpdate: (props) => {
|
|
674
|
+
options.onSuggestionChange?.({
|
|
675
|
+
editor: props.editor,
|
|
676
|
+
range: props.range,
|
|
677
|
+
query: props.query,
|
|
678
|
+
text: props.text,
|
|
679
|
+
command: props.command,
|
|
680
|
+
clientRect: props.clientRect
|
|
681
|
+
});
|
|
682
|
+
},
|
|
683
|
+
onExit: () => {
|
|
684
|
+
options.onSuggestionChange?.(null);
|
|
685
|
+
},
|
|
686
|
+
onKeyDown: (props) => options.onSuggestionKeyDown?.(props.event) ?? false
|
|
687
|
+
})
|
|
688
|
+
})
|
|
689
|
+
];
|
|
690
|
+
}
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
function buildAgentSessionMentionHref(workspaceId, agentSessionId, _provider) {
|
|
694
|
+
return buildAgentGenericMentionHref2("agent-session", agentSessionId, {
|
|
695
|
+
workspaceId
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
function buildAgentWorkspaceIssueMentionHref(workspaceId, issueId, input) {
|
|
699
|
+
return buildAgentGenericMentionHref2("workspace-issue", issueId, {
|
|
700
|
+
workspaceId,
|
|
701
|
+
topicId: input?.topicId ?? void 0
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
function buildAgentWorkspaceAppMentionHref(workspaceId, appId) {
|
|
705
|
+
return buildAgentGenericMentionHref2("workspace-app", appId, {
|
|
706
|
+
workspaceId
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
function buildAgentWorkspaceAppFactoryMentionHref(workspaceId, jobId, input) {
|
|
710
|
+
const params = new URLSearchParams();
|
|
711
|
+
const trimmedWorkspaceId = workspaceId?.trim() ?? "";
|
|
712
|
+
const trimmedJobId = jobId?.trim() ?? "";
|
|
713
|
+
const action = input?.action?.trim() ?? "";
|
|
714
|
+
const contextPath = input?.contextPath?.trim() ?? "";
|
|
715
|
+
if (trimmedWorkspaceId) {
|
|
716
|
+
params.set("workspaceId", trimmedWorkspaceId);
|
|
717
|
+
}
|
|
718
|
+
if (trimmedJobId) {
|
|
719
|
+
params.set("jobId", trimmedJobId);
|
|
720
|
+
}
|
|
721
|
+
if (action) {
|
|
722
|
+
params.set("action", action);
|
|
723
|
+
}
|
|
724
|
+
if (contextPath) {
|
|
725
|
+
params.set("contextPath", contextPath);
|
|
726
|
+
}
|
|
727
|
+
return buildAgentGenericMentionHref2(
|
|
728
|
+
"workspace-app-factory",
|
|
729
|
+
trimmedJobId || "create",
|
|
730
|
+
Object.fromEntries(params)
|
|
731
|
+
);
|
|
732
|
+
}
|
|
733
|
+
function normalizeAgentSessionMentionTitle(value) {
|
|
734
|
+
const trimmed = value.trim();
|
|
735
|
+
const withoutMentionPrefix = trimmed.replace(/^@+/, "").trim();
|
|
736
|
+
return withoutMentionPrefix || trimmed;
|
|
737
|
+
}
|
|
738
|
+
function formatAgentMentionMarkdown(item) {
|
|
739
|
+
const label = item.name.trim().startsWith("@") ? item.name : `@${item.name}`;
|
|
740
|
+
return `[${escapeMarkdownLinkLabel(label)}](${escapeMarkdownLinkTarget(item.href)})`;
|
|
741
|
+
}
|
|
742
|
+
function parseAgentMentionMarkdown(value, start = 0) {
|
|
743
|
+
if (!value.startsWith("[", start)) {
|
|
744
|
+
return null;
|
|
745
|
+
}
|
|
746
|
+
let index = start + 1;
|
|
747
|
+
const prefixedMention = value[index] === "@";
|
|
748
|
+
if (prefixedMention) {
|
|
749
|
+
index += 1;
|
|
750
|
+
}
|
|
751
|
+
let name = "";
|
|
752
|
+
while (index < value.length) {
|
|
753
|
+
const current = value[index];
|
|
754
|
+
if (current === "\\") {
|
|
755
|
+
const escaped = value[index + 1];
|
|
756
|
+
if (escaped === "\\" || escaped === "[" || escaped === "]") {
|
|
757
|
+
name += escaped;
|
|
758
|
+
index += 2;
|
|
759
|
+
continue;
|
|
760
|
+
}
|
|
761
|
+
name += current;
|
|
762
|
+
index += 1;
|
|
763
|
+
continue;
|
|
764
|
+
}
|
|
765
|
+
if (current === "]") {
|
|
766
|
+
break;
|
|
767
|
+
}
|
|
768
|
+
name += current;
|
|
769
|
+
index += 1;
|
|
770
|
+
}
|
|
771
|
+
if (value[index] !== "]" || value[index + 1] !== "(") {
|
|
772
|
+
return null;
|
|
773
|
+
}
|
|
774
|
+
index += 2;
|
|
775
|
+
let href = "";
|
|
776
|
+
while (index < value.length) {
|
|
777
|
+
const current = value[index];
|
|
778
|
+
if (current === "\\") {
|
|
779
|
+
const escaped = value[index + 1];
|
|
780
|
+
if (escaped === "\\" || escaped === ")") {
|
|
781
|
+
href += escaped;
|
|
782
|
+
index += 2;
|
|
783
|
+
continue;
|
|
784
|
+
}
|
|
785
|
+
href += current;
|
|
786
|
+
index += 1;
|
|
787
|
+
continue;
|
|
788
|
+
}
|
|
789
|
+
if (current === ")") {
|
|
790
|
+
const item = parseMentionItemFromHref({ name, href });
|
|
791
|
+
if (!item) {
|
|
792
|
+
return null;
|
|
793
|
+
}
|
|
794
|
+
if (item.kind !== "file" && !prefixedMention) {
|
|
795
|
+
return null;
|
|
796
|
+
}
|
|
797
|
+
return {
|
|
798
|
+
item,
|
|
799
|
+
end: index + 1
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
href += current;
|
|
803
|
+
index += 1;
|
|
804
|
+
}
|
|
805
|
+
return null;
|
|
806
|
+
}
|
|
807
|
+
function parseMentionItemFromHref(input) {
|
|
808
|
+
const href = input.href.trim();
|
|
809
|
+
if (!href) {
|
|
810
|
+
return null;
|
|
811
|
+
}
|
|
812
|
+
if (!href.startsWith("mention://")) {
|
|
813
|
+
return {
|
|
814
|
+
kind: "file",
|
|
815
|
+
href,
|
|
816
|
+
path: href,
|
|
817
|
+
name: input.name,
|
|
818
|
+
entryKind: isLocalDirectoryMentionHref(href) ? "directory" : "unknown",
|
|
819
|
+
directoryPath: dirnameFromPath2(href)
|
|
820
|
+
};
|
|
821
|
+
}
|
|
822
|
+
let url;
|
|
823
|
+
try {
|
|
824
|
+
url = new URL(href);
|
|
825
|
+
} catch {
|
|
826
|
+
return null;
|
|
827
|
+
}
|
|
828
|
+
const resource = url.hostname.trim().toLowerCase();
|
|
829
|
+
if (!resource || hasLegacyMentionQueryParams(url)) {
|
|
830
|
+
return null;
|
|
831
|
+
}
|
|
832
|
+
const targetId = decodeURIComponent(url.pathname.replace(/^\/+/, "")).trim();
|
|
833
|
+
if (!targetId) {
|
|
834
|
+
return null;
|
|
835
|
+
}
|
|
836
|
+
const workspaceId = workspaceIdFromMentionUrl(url);
|
|
837
|
+
if (resource === "agent-session") {
|
|
838
|
+
if (!workspaceId) {
|
|
839
|
+
return null;
|
|
840
|
+
}
|
|
841
|
+
return {
|
|
842
|
+
kind: "session",
|
|
843
|
+
href,
|
|
844
|
+
workspaceId,
|
|
845
|
+
targetId,
|
|
846
|
+
name: input.name,
|
|
847
|
+
title: input.name,
|
|
848
|
+
scope: "collab_sessions",
|
|
849
|
+
initiatorName: "",
|
|
850
|
+
agentName: ""
|
|
851
|
+
};
|
|
852
|
+
}
|
|
853
|
+
if (resource === "workspace-issue") {
|
|
854
|
+
if (!workspaceId) {
|
|
855
|
+
return null;
|
|
856
|
+
}
|
|
857
|
+
return {
|
|
858
|
+
kind: "workspace-issue",
|
|
859
|
+
href,
|
|
860
|
+
workspaceId,
|
|
861
|
+
targetId,
|
|
862
|
+
topicId: url.searchParams.get("topicId")?.trim() || void 0,
|
|
863
|
+
name: input.name,
|
|
864
|
+
title: input.name
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
if (resource === "workspace-app") {
|
|
868
|
+
if (!workspaceId) {
|
|
869
|
+
return null;
|
|
870
|
+
}
|
|
871
|
+
return {
|
|
872
|
+
kind: "workspace-app",
|
|
873
|
+
href,
|
|
874
|
+
workspaceId,
|
|
875
|
+
targetId,
|
|
876
|
+
appId: targetId,
|
|
877
|
+
name: input.name
|
|
878
|
+
};
|
|
879
|
+
}
|
|
880
|
+
if (resource === "workspace-app-factory") {
|
|
881
|
+
return {
|
|
882
|
+
kind: "workspace-app-factory",
|
|
883
|
+
href,
|
|
884
|
+
workspaceId,
|
|
885
|
+
targetId,
|
|
886
|
+
jobId: targetId === "create" ? "" : targetId,
|
|
887
|
+
name: input.name || translate("agentHost.agentGui.workspaceAppFactoryMentionFallback"),
|
|
888
|
+
action: url.searchParams.get("action")?.trim() || void 0,
|
|
889
|
+
contextPath: url.searchParams.get("contextPath")?.trim() || void 0
|
|
890
|
+
};
|
|
891
|
+
}
|
|
892
|
+
return null;
|
|
893
|
+
}
|
|
894
|
+
function isLocalDirectoryMentionHref(href) {
|
|
895
|
+
return href.endsWith("/") && !/^[a-zA-Z][a-zA-Z\d+.-]*:/.test(href);
|
|
896
|
+
}
|
|
897
|
+
function mentionItemToAttrs(item) {
|
|
898
|
+
if (item.kind === "file") {
|
|
899
|
+
return {
|
|
900
|
+
name: item.name,
|
|
901
|
+
kind: item.kind,
|
|
902
|
+
href: item.href,
|
|
903
|
+
path: item.path,
|
|
904
|
+
entryKind: item.entryKind,
|
|
905
|
+
directoryPath: item.directoryPath,
|
|
906
|
+
thumbnailUrl: resolveAgentMentionFileThumbnailUrl(item) ?? ""
|
|
907
|
+
};
|
|
908
|
+
}
|
|
909
|
+
if (item.kind === "session") {
|
|
910
|
+
return {
|
|
911
|
+
name: item.name,
|
|
912
|
+
kind: item.kind,
|
|
913
|
+
href: item.href,
|
|
914
|
+
...workspaceMentionAttrs(item.workspaceId),
|
|
915
|
+
targetId: item.targetId,
|
|
916
|
+
scope: item.scope,
|
|
917
|
+
title: item.title,
|
|
918
|
+
initiatorName: item.initiatorName,
|
|
919
|
+
agentName: item.agentName,
|
|
920
|
+
status: item.status ?? "",
|
|
921
|
+
inputPreview: item.inputPreview ?? "",
|
|
922
|
+
summaryPreview: item.summaryPreview ?? ""
|
|
923
|
+
};
|
|
924
|
+
}
|
|
925
|
+
if (item.kind === "workspace-app") {
|
|
926
|
+
return {
|
|
927
|
+
name: item.name,
|
|
928
|
+
kind: item.kind,
|
|
929
|
+
href: item.href,
|
|
930
|
+
...workspaceMentionAttrs(item.workspaceId),
|
|
931
|
+
targetId: item.targetId,
|
|
932
|
+
appId: item.appId,
|
|
933
|
+
description: item.description ?? "",
|
|
934
|
+
iconUrl: item.iconUrl ?? ""
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
if (item.kind === "workspace-app-factory") {
|
|
938
|
+
return {
|
|
939
|
+
name: item.name,
|
|
940
|
+
kind: item.kind,
|
|
941
|
+
href: item.href,
|
|
942
|
+
...workspaceMentionAttrs(item.workspaceId),
|
|
943
|
+
targetId: item.targetId,
|
|
944
|
+
jobId: item.jobId,
|
|
945
|
+
action: item.action ?? "",
|
|
946
|
+
contextPath: item.contextPath ?? ""
|
|
947
|
+
};
|
|
948
|
+
}
|
|
949
|
+
return {
|
|
950
|
+
name: item.name,
|
|
951
|
+
kind: item.kind,
|
|
952
|
+
href: item.href,
|
|
953
|
+
...workspaceMentionAttrs(item.workspaceId),
|
|
954
|
+
targetId: item.targetId,
|
|
955
|
+
topicId: item.topicId ?? "",
|
|
956
|
+
title: item.title,
|
|
957
|
+
creatorName: item.creatorName ?? "",
|
|
958
|
+
status: item.status ?? "",
|
|
959
|
+
contentPreview: item.contentPreview ?? ""
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
function workspaceMentionAttrs(workspaceId) {
|
|
963
|
+
const normalizedWorkspaceId = workspaceId.trim();
|
|
964
|
+
return {
|
|
965
|
+
workspaceId: normalizedWorkspaceId
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
function attrsToMentionItem(attrs) {
|
|
969
|
+
const kind = normalizeMentionKind(attrs.kind);
|
|
970
|
+
const name = typeof attrs.name === "string" ? attrs.name : "";
|
|
971
|
+
const href = typeof attrs.href === "string" && attrs.href.trim() ? attrs.href : "";
|
|
972
|
+
if (kind === "session") {
|
|
973
|
+
const workspaceId = workspaceIdFromMentionAttrs(attrs);
|
|
974
|
+
const targetId = typeof attrs.targetId === "string" ? attrs.targetId : "";
|
|
975
|
+
return {
|
|
976
|
+
kind,
|
|
977
|
+
href: href || buildAgentSessionMentionHref(workspaceId, targetId),
|
|
978
|
+
workspaceId,
|
|
979
|
+
targetId,
|
|
980
|
+
name,
|
|
981
|
+
title: typeof attrs.title === "string" && attrs.title.trim() ? attrs.title : name,
|
|
982
|
+
scope: attrs.scope === "my_sessions" || attrs.scope === "collab_sessions" ? attrs.scope : "collab_sessions",
|
|
983
|
+
initiatorName: typeof attrs.initiatorName === "string" ? attrs.initiatorName : "",
|
|
984
|
+
agentName: typeof attrs.agentName === "string" ? attrs.agentName : "",
|
|
985
|
+
status: typeof attrs.status === "string" ? attrs.status : void 0,
|
|
986
|
+
inputPreview: typeof attrs.inputPreview === "string" ? attrs.inputPreview : void 0,
|
|
987
|
+
summaryPreview: typeof attrs.summaryPreview === "string" ? attrs.summaryPreview : void 0
|
|
988
|
+
};
|
|
989
|
+
}
|
|
990
|
+
if (kind === "workspace-issue") {
|
|
991
|
+
const workspaceId = workspaceIdFromMentionAttrs(attrs);
|
|
992
|
+
const targetId = typeof attrs.targetId === "string" ? attrs.targetId : "";
|
|
993
|
+
const topicId = typeof attrs.topicId === "string" && attrs.topicId.trim() ? attrs.topicId.trim() : void 0;
|
|
994
|
+
return {
|
|
995
|
+
kind,
|
|
996
|
+
href: href || buildAgentWorkspaceIssueMentionHref(workspaceId, targetId, {
|
|
997
|
+
topicId
|
|
998
|
+
}),
|
|
999
|
+
workspaceId,
|
|
1000
|
+
targetId,
|
|
1001
|
+
topicId,
|
|
1002
|
+
name,
|
|
1003
|
+
title: typeof attrs.title === "string" && attrs.title.trim() ? attrs.title : name,
|
|
1004
|
+
creatorName: typeof attrs.creatorName === "string" ? attrs.creatorName : void 0,
|
|
1005
|
+
status: typeof attrs.status === "string" ? attrs.status : void 0,
|
|
1006
|
+
contentPreview: typeof attrs.contentPreview === "string" ? attrs.contentPreview : void 0
|
|
1007
|
+
};
|
|
1008
|
+
}
|
|
1009
|
+
if (kind === "workspace-app") {
|
|
1010
|
+
const workspaceId = workspaceIdFromMentionAttrs(attrs);
|
|
1011
|
+
const appId = typeof attrs.appId === "string" && attrs.appId.trim() ? attrs.appId.trim() : typeof attrs.targetId === "string" ? attrs.targetId.trim() : "";
|
|
1012
|
+
return {
|
|
1013
|
+
kind,
|
|
1014
|
+
href: href || buildAgentWorkspaceAppMentionHref(workspaceId, appId),
|
|
1015
|
+
workspaceId,
|
|
1016
|
+
targetId: appId,
|
|
1017
|
+
appId,
|
|
1018
|
+
name,
|
|
1019
|
+
description: typeof attrs.description === "string" ? attrs.description : void 0,
|
|
1020
|
+
iconUrl: typeof attrs.iconUrl === "string" && attrs.iconUrl.trim() ? attrs.iconUrl.trim() : void 0
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
1023
|
+
if (kind === "workspace-app-factory") {
|
|
1024
|
+
const workspaceId = workspaceIdFromMentionAttrs(attrs);
|
|
1025
|
+
const jobId = typeof attrs.jobId === "string" && attrs.jobId.trim() ? attrs.jobId.trim() : typeof attrs.targetId === "string" ? attrs.targetId.trim() : "";
|
|
1026
|
+
const action = typeof attrs.action === "string" && attrs.action.trim() ? attrs.action.trim() : void 0;
|
|
1027
|
+
const contextPath = typeof attrs.contextPath === "string" && attrs.contextPath.trim() ? attrs.contextPath.trim() : void 0;
|
|
1028
|
+
return {
|
|
1029
|
+
kind,
|
|
1030
|
+
href: href || buildAgentWorkspaceAppFactoryMentionHref(workspaceId, jobId, {
|
|
1031
|
+
action,
|
|
1032
|
+
contextPath
|
|
1033
|
+
}),
|
|
1034
|
+
workspaceId,
|
|
1035
|
+
targetId: jobId,
|
|
1036
|
+
jobId,
|
|
1037
|
+
name,
|
|
1038
|
+
action,
|
|
1039
|
+
contextPath
|
|
1040
|
+
};
|
|
1041
|
+
}
|
|
1042
|
+
const path = typeof attrs.path === "string" && attrs.path.trim() ? attrs.path : typeof attrs.href === "string" ? attrs.href : "";
|
|
1043
|
+
return {
|
|
1044
|
+
kind: "file",
|
|
1045
|
+
href: href || path,
|
|
1046
|
+
path,
|
|
1047
|
+
name,
|
|
1048
|
+
entryKind: normalizeEntryKind(attrs.entryKind),
|
|
1049
|
+
directoryPath: typeof attrs.directoryPath === "string" && attrs.directoryPath.trim() ? attrs.directoryPath : dirnameFromPath2(path),
|
|
1050
|
+
thumbnailUrl: resolveAgentMentionFileThumbnailUrl({
|
|
1051
|
+
entryKind: normalizeEntryKind(attrs.entryKind),
|
|
1052
|
+
href: href || path,
|
|
1053
|
+
name,
|
|
1054
|
+
path,
|
|
1055
|
+
thumbnailUrl: typeof attrs.thumbnailUrl === "string" ? attrs.thumbnailUrl : void 0
|
|
1056
|
+
})
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
1059
|
+
function workspaceIdFromMentionAttrs(attrs) {
|
|
1060
|
+
return typeof attrs.workspaceId === "string" ? attrs.workspaceId.trim() : "";
|
|
1061
|
+
}
|
|
1062
|
+
function parseAgentMentionHTMLElementAttrs(node) {
|
|
1063
|
+
if (typeof node === "string") {
|
|
1064
|
+
return false;
|
|
1065
|
+
}
|
|
1066
|
+
const href = node.getAttribute("data-agent-mention-href") || node.getAttribute("data-agent-link-href") || node.getAttribute("href") || "";
|
|
1067
|
+
const name = node.getAttribute("name") || (node.textContent ?? "").replace(/^@+/, "").trim();
|
|
1068
|
+
const parsedItem = href ? parseMentionItemFromHref({ name, href }) : null;
|
|
1069
|
+
const parsedAttrs = parsedItem ? mentionItemToAttrs(parsedItem) : {};
|
|
1070
|
+
const iconUrl = node.getAttribute("data-agent-mention-icon-url") || "";
|
|
1071
|
+
return {
|
|
1072
|
+
...parsedAttrs,
|
|
1073
|
+
name,
|
|
1074
|
+
kind: node.getAttribute("data-agent-mention-kind") || node.getAttribute("kind") || parsedAttrs.kind || "file",
|
|
1075
|
+
href,
|
|
1076
|
+
...iconUrl ? { iconUrl } : {}
|
|
1077
|
+
};
|
|
1078
|
+
}
|
|
1079
|
+
function workspaceIdFromMentionUrl(url) {
|
|
1080
|
+
return url.searchParams.get("workspaceId")?.trim() ?? "";
|
|
1081
|
+
}
|
|
1082
|
+
function buildAgentGenericMentionHref2(providerId, entityId, scope) {
|
|
1083
|
+
const normalizedProviderId = providerId.trim();
|
|
1084
|
+
const normalizedEntityId = entityId.trim();
|
|
1085
|
+
if (!normalizedProviderId || !normalizedEntityId) {
|
|
1086
|
+
return "";
|
|
1087
|
+
}
|
|
1088
|
+
const params = new URLSearchParams();
|
|
1089
|
+
Object.entries(scope ?? {}).map(([key, value]) => [key.trim(), value?.trim() ?? ""]).filter(([key, value]) => key && value).sort(([left], [right]) => left.localeCompare(right)).forEach(([key, value]) => {
|
|
1090
|
+
params.set(key, value);
|
|
1091
|
+
});
|
|
1092
|
+
const query = params.toString();
|
|
1093
|
+
const href = `mention://${encodeURIComponent(
|
|
1094
|
+
normalizedProviderId
|
|
1095
|
+
)}/${encodeURIComponent(normalizedEntityId)}`;
|
|
1096
|
+
return query ? `${href}?${query}` : href;
|
|
1097
|
+
}
|
|
1098
|
+
function hasLegacyMentionQueryParams(url) {
|
|
1099
|
+
return [...url.searchParams.keys()].some(
|
|
1100
|
+
(key) => key === "appId" || key === "id" || key === "kind" || key === "link" || key === "provider" || key === "v" || key === "version" || key.startsWith("meta.")
|
|
1101
|
+
);
|
|
1102
|
+
}
|
|
1103
|
+
function normalizeMentionKind(value) {
|
|
1104
|
+
if (value === "session" || value === "agent-session") {
|
|
1105
|
+
return "session";
|
|
1106
|
+
}
|
|
1107
|
+
if (value === "workspace-issue") {
|
|
1108
|
+
return "workspace-issue";
|
|
1109
|
+
}
|
|
1110
|
+
if (value === "workspace-app") {
|
|
1111
|
+
return "workspace-app";
|
|
1112
|
+
}
|
|
1113
|
+
if (value === "workspace-app-factory") {
|
|
1114
|
+
return "workspace-app-factory";
|
|
1115
|
+
}
|
|
1116
|
+
return "file";
|
|
1117
|
+
}
|
|
1118
|
+
function normalizeEntryKind(value) {
|
|
1119
|
+
return value === "directory" || value === "file" ? value : "unknown";
|
|
1120
|
+
}
|
|
1121
|
+
function mentionVisual(item) {
|
|
1122
|
+
if (item.kind === "file") {
|
|
1123
|
+
return {
|
|
1124
|
+
kindLabel: "File",
|
|
1125
|
+
primary: item.name
|
|
1126
|
+
};
|
|
1127
|
+
}
|
|
1128
|
+
if (item.kind === "session") {
|
|
1129
|
+
const visual = sessionMentionVisual(item);
|
|
1130
|
+
return {
|
|
1131
|
+
kindLabel: "Session",
|
|
1132
|
+
primary: `${visual.participant} ${visual.summary}`.trim()
|
|
1133
|
+
};
|
|
1134
|
+
}
|
|
1135
|
+
if (item.kind === "workspace-app") {
|
|
1136
|
+
return {
|
|
1137
|
+
kindLabel: "App",
|
|
1138
|
+
primary: item.name
|
|
1139
|
+
};
|
|
1140
|
+
}
|
|
1141
|
+
if (item.kind === "workspace-app-factory") {
|
|
1142
|
+
return {
|
|
1143
|
+
kindLabel: "App Factory",
|
|
1144
|
+
primary: item.name
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
return {
|
|
1148
|
+
kindLabel: "Issue",
|
|
1149
|
+
primary: item.name
|
|
1150
|
+
};
|
|
1151
|
+
}
|
|
1152
|
+
function sessionMentionVisual(item) {
|
|
1153
|
+
const initiatorName = item.initiatorName.trim();
|
|
1154
|
+
const agentName = item.agentName.trim();
|
|
1155
|
+
const title = normalizeAgentSessionMentionTitle(item.title);
|
|
1156
|
+
if (initiatorName && agentName) {
|
|
1157
|
+
const dottedTitle = parseDottedSessionMentionText(title);
|
|
1158
|
+
return {
|
|
1159
|
+
participant: `${initiatorName} & ${agentName}`,
|
|
1160
|
+
summary: dottedTitle?.summary || (title && title !== item.name.trim() ? title : item.inputPreview?.trim() || "")
|
|
1161
|
+
};
|
|
1162
|
+
}
|
|
1163
|
+
const dottedName = parseDottedSessionMentionText(item.name);
|
|
1164
|
+
if (dottedName) {
|
|
1165
|
+
return {
|
|
1166
|
+
participant: dottedName.participant,
|
|
1167
|
+
summary: dottedName.summary
|
|
1168
|
+
};
|
|
1169
|
+
}
|
|
1170
|
+
return {
|
|
1171
|
+
participant: item.name.trim(),
|
|
1172
|
+
summary: title && title !== item.name.trim() ? title : item.inputPreview?.trim() || ""
|
|
1173
|
+
};
|
|
1174
|
+
}
|
|
1175
|
+
function parseDottedSessionMentionText(value) {
|
|
1176
|
+
const parts = value.split("\xB7").map((part) => part.trim()).filter(Boolean);
|
|
1177
|
+
if (parts.length < 3) {
|
|
1178
|
+
return null;
|
|
1179
|
+
}
|
|
1180
|
+
return {
|
|
1181
|
+
participant: `${parts[0]} & ${parts[1]}`,
|
|
1182
|
+
summary: normalizeAgentSessionMentionTitle(parts.slice(2).join(" "))
|
|
1183
|
+
};
|
|
1184
|
+
}
|
|
1185
|
+
function dirnameFromPath2(path) {
|
|
1186
|
+
const parts = path.split("/").filter(Boolean);
|
|
1187
|
+
if (parts.length <= 1) {
|
|
1188
|
+
return path.startsWith("/") ? "/" : "";
|
|
1189
|
+
}
|
|
1190
|
+
return `/${parts.slice(0, -1).join("/")}`;
|
|
1191
|
+
}
|
|
1192
|
+
function escapeMarkdownLinkLabel(value) {
|
|
1193
|
+
return value.replace(/([\\[\]])/g, "\\$1");
|
|
1194
|
+
}
|
|
1195
|
+
function escapeMarkdownLinkTarget(value) {
|
|
1196
|
+
return value.replace(/\\/g, "\\\\").replace(/\)/g, "\\)");
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
export {
|
|
1200
|
+
exitAgentFileMentionSuggestion,
|
|
1201
|
+
createAgentFileMentionExtension,
|
|
1202
|
+
buildAgentSessionMentionHref,
|
|
1203
|
+
buildAgentWorkspaceIssueMentionHref,
|
|
1204
|
+
buildAgentWorkspaceAppMentionHref,
|
|
1205
|
+
normalizeAgentSessionMentionTitle,
|
|
1206
|
+
formatAgentMentionMarkdown,
|
|
1207
|
+
parseAgentMentionMarkdown,
|
|
1208
|
+
attrsToMentionItem,
|
|
1209
|
+
buildAgentGenericMentionHref2 as buildAgentGenericMentionHref
|
|
1210
|
+
};
|
|
1211
|
+
//# sourceMappingURL=chunk-MU2LODEV.js.map
|