@tutti-os/ui-rich-text 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/README.md +50 -57
- package/dist/at-panel/index.css +190 -0
- package/dist/at-panel/index.css.map +1 -0
- package/dist/at-panel/index.d.ts +63 -0
- package/dist/at-panel/index.js +1165 -0
- package/dist/at-panel/index.js.map +1 -0
- package/dist/at-panel/model.d.ts +386 -0
- package/dist/at-panel/model.js +39 -0
- package/dist/at-panel/model.js.map +1 -0
- package/dist/chunk-E4PWFY3N.js +264 -0
- package/dist/chunk-E4PWFY3N.js.map +1 -0
- package/dist/{chunk-K5POY2YJ.js → chunk-QK6NMNYN.js} +124 -46
- package/dist/chunk-QK6NMNYN.js.map +1 -0
- package/dist/{chunk-52PIIFZA.js → chunk-QOVFZUZN.js} +58 -49
- package/dist/chunk-QOVFZUZN.js.map +1 -0
- package/dist/core/index.d.ts +4 -4
- package/dist/core/index.js +1 -1
- package/dist/editor/index.d.ts +30 -13
- package/dist/editor/index.js +501 -171
- package/dist/editor/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{mention-QICvf4wE.d.ts → mention-CgUcsO8r.d.ts} +35 -19
- package/dist/plugins/index.d.ts +8 -8
- package/dist/plugins/index.js +8 -8
- package/dist/types/index.d.ts +36 -24
- package/package.json +17 -3
- package/dist/chunk-52PIIFZA.js.map +0 -1
- package/dist/chunk-K5POY2YJ.js.map +0 -1
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
// src/at-panel/searchHelpers.ts
|
|
2
|
+
var RICH_TEXT_AT_ALL_FILTER_ID = "all";
|
|
3
|
+
var DEFAULT_RICH_TEXT_AT_PANEL_PAGE_SIZE = 5;
|
|
4
|
+
function normalizeAtPanelQuery(value) {
|
|
5
|
+
return value.replace(/\s+/g, " ").trim();
|
|
6
|
+
}
|
|
7
|
+
function buildDefaultRichTextTriggerProviderGroups(input) {
|
|
8
|
+
return input.providers.map((provider) => ({
|
|
9
|
+
id: provider.id,
|
|
10
|
+
label: input.labels?.[provider.id] ?? provider.id,
|
|
11
|
+
providerIds: [provider.id],
|
|
12
|
+
filterId: provider.id
|
|
13
|
+
}));
|
|
14
|
+
}
|
|
15
|
+
function buildRichTextAtFilterTabs(input) {
|
|
16
|
+
const seen = /* @__PURE__ */ new Set([RICH_TEXT_AT_ALL_FILTER_ID]);
|
|
17
|
+
const tabs = [
|
|
18
|
+
{
|
|
19
|
+
id: RICH_TEXT_AT_ALL_FILTER_ID,
|
|
20
|
+
label: input.allLabel
|
|
21
|
+
}
|
|
22
|
+
];
|
|
23
|
+
for (const group of input.groups) {
|
|
24
|
+
const filterId = group.filterId ?? group.id;
|
|
25
|
+
if (seen.has(filterId)) {
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
seen.add(filterId);
|
|
29
|
+
tabs.push({
|
|
30
|
+
id: filterId,
|
|
31
|
+
label: input.labels?.[filterId] ?? group.label
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return tabs;
|
|
35
|
+
}
|
|
36
|
+
function filterGroupsForRichTextAtPanel(input) {
|
|
37
|
+
if (input.filterId === RICH_TEXT_AT_ALL_FILTER_ID) {
|
|
38
|
+
return input.groups;
|
|
39
|
+
}
|
|
40
|
+
return input.groups.filter(
|
|
41
|
+
(group) => (group.filterId ?? group.id) === input.filterId
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
function groupRichTextAtMatches(input) {
|
|
45
|
+
const visibleGroups = filterGroupsForRichTextAtPanel({
|
|
46
|
+
filterId: input.filterId,
|
|
47
|
+
groups: input.groups
|
|
48
|
+
});
|
|
49
|
+
const pageSize = input.pageSize ?? DEFAULT_RICH_TEXT_AT_PANEL_PAGE_SIZE;
|
|
50
|
+
return visibleGroups.map((group) => {
|
|
51
|
+
const providerIds = new Set(group.providerIds);
|
|
52
|
+
const items = input.matches.filter(
|
|
53
|
+
(match) => providerIds.has(match.providerId)
|
|
54
|
+
);
|
|
55
|
+
const groupPageSize = group.pageSize ?? pageSize;
|
|
56
|
+
const visibleCount = Math.min(
|
|
57
|
+
items.length,
|
|
58
|
+
input.expandedCounts?.[group.id] ?? groupPageSize
|
|
59
|
+
);
|
|
60
|
+
if (items.length === 0 && !group.emptyLabel) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
id: group.id,
|
|
65
|
+
label: group.label,
|
|
66
|
+
items: items.slice(0, visibleCount),
|
|
67
|
+
totalCount: items.length,
|
|
68
|
+
visibleCount,
|
|
69
|
+
hasMore: items.length > visibleCount,
|
|
70
|
+
emptyLabel: group.emptyLabel
|
|
71
|
+
};
|
|
72
|
+
}).filter((group) => group !== null);
|
|
73
|
+
}
|
|
74
|
+
function richTextAtGroupExpandCount(group, pageSize = DEFAULT_RICH_TEXT_AT_PANEL_PAGE_SIZE) {
|
|
75
|
+
const remaining = Math.max(0, group.totalCount - group.visibleCount);
|
|
76
|
+
return Math.min(pageSize, remaining);
|
|
77
|
+
}
|
|
78
|
+
function findRichTextTriggerProviderGroup(groups, groupId) {
|
|
79
|
+
return groups.find((group) => group.id === groupId);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/at-panel/buildMentionPaletteState.ts
|
|
83
|
+
function buildMentionPaletteState(input) {
|
|
84
|
+
const searchGroups = groupRichTextAtMatches({
|
|
85
|
+
expandedCounts: input.expandedCounts,
|
|
86
|
+
filterId: input.activeFilterId,
|
|
87
|
+
groups: input.providerGroups,
|
|
88
|
+
matches: input.matches,
|
|
89
|
+
pageSize: input.pageSize
|
|
90
|
+
});
|
|
91
|
+
const groups = searchGroups.map((group) => ({
|
|
92
|
+
id: group.id,
|
|
93
|
+
label: input.shouldRenderGroupLabel != null && !input.shouldRenderGroupLabel(group.id, searchGroups.length) ? void 0 : group.label,
|
|
94
|
+
items: group.items,
|
|
95
|
+
totalCount: group.totalCount,
|
|
96
|
+
visibleCount: group.visibleCount,
|
|
97
|
+
hasMore: group.hasMore,
|
|
98
|
+
emptyLabel: group.emptyLabel,
|
|
99
|
+
expandLabel: group.hasMore && input.showMoreLabel != null ? input.showMoreLabel(group.totalCount - group.visibleCount) : void 0
|
|
100
|
+
}));
|
|
101
|
+
const categories = input.filterTabs;
|
|
102
|
+
const filter = input.activeFilterId;
|
|
103
|
+
const query = input.query;
|
|
104
|
+
const isEmptyQuery = query === "";
|
|
105
|
+
if (input.isLoading) {
|
|
106
|
+
return {
|
|
107
|
+
status: "loading",
|
|
108
|
+
query,
|
|
109
|
+
mode: isEmptyQuery ? "browse" : "results",
|
|
110
|
+
filter,
|
|
111
|
+
categories,
|
|
112
|
+
groups,
|
|
113
|
+
error: null
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
if (isEmptyQuery) {
|
|
117
|
+
return {
|
|
118
|
+
status: "idle",
|
|
119
|
+
query,
|
|
120
|
+
mode: "browse",
|
|
121
|
+
filter,
|
|
122
|
+
categories,
|
|
123
|
+
groups,
|
|
124
|
+
error: null
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
status: "ready",
|
|
129
|
+
query,
|
|
130
|
+
mode: "results",
|
|
131
|
+
filter,
|
|
132
|
+
categories,
|
|
133
|
+
groups,
|
|
134
|
+
error: null
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// src/at-panel/mentionPaletteEntries.ts
|
|
139
|
+
function hasInteractiveGroupEntries(groups) {
|
|
140
|
+
return groups.some((group) => group.items.length > 0 || group.hasMore);
|
|
141
|
+
}
|
|
142
|
+
function flattenMentionPaletteEntries(state, getItemKey) {
|
|
143
|
+
if (state.mode === "browse" && !hasInteractiveGroupEntries(state.groups)) {
|
|
144
|
+
return state.categories.map((category) => ({
|
|
145
|
+
key: `category:${category.id}`,
|
|
146
|
+
type: "category",
|
|
147
|
+
categoryId: category.id
|
|
148
|
+
}));
|
|
149
|
+
}
|
|
150
|
+
const entries = [];
|
|
151
|
+
for (const group of state.groups) {
|
|
152
|
+
group.items.forEach((item, index) => {
|
|
153
|
+
entries.push({
|
|
154
|
+
key: `${group.id}:${getItemKey(item, group.id)}`,
|
|
155
|
+
type: "item",
|
|
156
|
+
groupId: group.id,
|
|
157
|
+
itemIndex: index
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
if (group.hasMore) {
|
|
161
|
+
entries.push({
|
|
162
|
+
key: `expand:${group.id}`,
|
|
163
|
+
type: "expand",
|
|
164
|
+
groupId: group.id
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return entries;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// src/at-panel/mentionStatusTone.ts
|
|
172
|
+
function activityMentionStatusBadgeClassName(tone) {
|
|
173
|
+
switch (tone) {
|
|
174
|
+
case "blue":
|
|
175
|
+
return "bg-sky-500/10 text-sky-700";
|
|
176
|
+
case "amber":
|
|
177
|
+
return "bg-[color:color-mix(in_srgb,var(--color-amber-500)_12%,transparent)] text-[var(--color-amber-500)]";
|
|
178
|
+
case "green":
|
|
179
|
+
return "bg-[var(--tsh-ui-pill-success-bg)] text-[var(--tsh-ui-pill-success-fg)]";
|
|
180
|
+
case "red":
|
|
181
|
+
return "bg-[var(--on-danger)] text-[var(--state-danger)]";
|
|
182
|
+
default:
|
|
183
|
+
return "bg-[var(--transparency-block)] text-[var(--text-secondary)]";
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function issueMentionStatusBadgeClassName(tone) {
|
|
187
|
+
switch (tone) {
|
|
188
|
+
case "green":
|
|
189
|
+
return "bg-[color:color-mix(in_srgb,var(--state-success)_12%,transparent)] text-[var(--state-success)]";
|
|
190
|
+
case "red":
|
|
191
|
+
return "bg-[var(--on-danger)] text-[var(--state-danger)]";
|
|
192
|
+
default:
|
|
193
|
+
return "bg-[var(--transparency-block)] text-[var(--text-secondary)]";
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function mentionStatusBadgeClassName(input) {
|
|
197
|
+
return input.variant === "issue" ? issueMentionStatusBadgeClassName(input.tone) : activityMentionStatusBadgeClassName(input.tone);
|
|
198
|
+
}
|
|
199
|
+
function activityMentionStatusTone(status) {
|
|
200
|
+
switch (status.trim().toLowerCase()) {
|
|
201
|
+
case "working":
|
|
202
|
+
return "blue";
|
|
203
|
+
case "waiting":
|
|
204
|
+
case "canceled":
|
|
205
|
+
return "amber";
|
|
206
|
+
case "completed":
|
|
207
|
+
case "idle":
|
|
208
|
+
return "green";
|
|
209
|
+
case "failed":
|
|
210
|
+
return "red";
|
|
211
|
+
default:
|
|
212
|
+
return "neutral";
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
function issueMentionStatusTone(status) {
|
|
216
|
+
switch (status.trim().toLowerCase()) {
|
|
217
|
+
case "completed":
|
|
218
|
+
return "green";
|
|
219
|
+
case "failed":
|
|
220
|
+
case "canceled":
|
|
221
|
+
return "red";
|
|
222
|
+
default:
|
|
223
|
+
return "neutral";
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// src/at-panel/mentionFileVisualKind.ts
|
|
228
|
+
function resolveMentionFileVisualKind(input) {
|
|
229
|
+
if (input.mentionNavigation === "agent-generated-folder-back") {
|
|
230
|
+
return "back";
|
|
231
|
+
}
|
|
232
|
+
if (input.entryKind === "directory") {
|
|
233
|
+
return "folder";
|
|
234
|
+
}
|
|
235
|
+
return input.baseVisualKind;
|
|
236
|
+
}
|
|
237
|
+
function resolveMentionFileThumbnailUrl(input) {
|
|
238
|
+
if (input.visualKind !== "image") {
|
|
239
|
+
return void 0;
|
|
240
|
+
}
|
|
241
|
+
const thumbnailUrl = input.thumbnailUrl?.trim() ?? "";
|
|
242
|
+
return thumbnailUrl || void 0;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export {
|
|
246
|
+
RICH_TEXT_AT_ALL_FILTER_ID,
|
|
247
|
+
DEFAULT_RICH_TEXT_AT_PANEL_PAGE_SIZE,
|
|
248
|
+
normalizeAtPanelQuery,
|
|
249
|
+
buildDefaultRichTextTriggerProviderGroups,
|
|
250
|
+
buildRichTextAtFilterTabs,
|
|
251
|
+
groupRichTextAtMatches,
|
|
252
|
+
richTextAtGroupExpandCount,
|
|
253
|
+
findRichTextTriggerProviderGroup,
|
|
254
|
+
buildMentionPaletteState,
|
|
255
|
+
flattenMentionPaletteEntries,
|
|
256
|
+
activityMentionStatusBadgeClassName,
|
|
257
|
+
issueMentionStatusBadgeClassName,
|
|
258
|
+
mentionStatusBadgeClassName,
|
|
259
|
+
activityMentionStatusTone,
|
|
260
|
+
issueMentionStatusTone,
|
|
261
|
+
resolveMentionFileVisualKind,
|
|
262
|
+
resolveMentionFileThumbnailUrl
|
|
263
|
+
};
|
|
264
|
+
//# sourceMappingURL=chunk-E4PWFY3N.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/at-panel/searchHelpers.ts","../src/at-panel/buildMentionPaletteState.ts","../src/at-panel/mentionPaletteEntries.ts","../src/at-panel/mentionStatusTone.ts","../src/at-panel/mentionFileVisualKind.ts"],"sourcesContent":["import type { RichTextTriggerQueryMatch as RichTextAtQueryMatch } from \"../types/trigger.ts\";\nimport type {\n RichTextAtFilterId,\n RichTextAtFilterTab,\n RichTextAtGroupId,\n RichTextTriggerProviderGroup,\n RichTextAtSearchGroup\n} from \"./types.ts\";\n\nexport const RICH_TEXT_AT_ALL_FILTER_ID = \"all\";\nexport const DEFAULT_RICH_TEXT_AT_PANEL_PAGE_SIZE = 5;\n\nexport function normalizeAtPanelQuery(value: string): string {\n return value.replace(/\\s+/g, \" \").trim();\n}\n\nexport function buildDefaultRichTextTriggerProviderGroups(input: {\n providers: readonly { id: string }[];\n labels?: Readonly<Record<string, string>>;\n}): RichTextTriggerProviderGroup[] {\n return input.providers.map((provider) => ({\n id: provider.id,\n label: input.labels?.[provider.id] ?? provider.id,\n providerIds: [provider.id],\n filterId: provider.id\n }));\n}\n\nexport function buildRichTextAtFilterTabs(input: {\n allLabel: string;\n groups: readonly RichTextTriggerProviderGroup[];\n labels?: Readonly<Record<string, string>>;\n}): RichTextAtFilterTab[] {\n const seen = new Set<string>([RICH_TEXT_AT_ALL_FILTER_ID]);\n const tabs: RichTextAtFilterTab[] = [\n {\n id: RICH_TEXT_AT_ALL_FILTER_ID,\n label: input.allLabel\n }\n ];\n for (const group of input.groups) {\n const filterId = group.filterId ?? group.id;\n if (seen.has(filterId)) {\n continue;\n }\n seen.add(filterId);\n tabs.push({\n id: filterId,\n label: input.labels?.[filterId] ?? group.label\n });\n }\n return tabs;\n}\n\nexport function filterGroupsForRichTextAtPanel(input: {\n filterId: RichTextAtFilterId;\n groups: readonly RichTextTriggerProviderGroup[];\n}): readonly RichTextTriggerProviderGroup[] {\n if (input.filterId === RICH_TEXT_AT_ALL_FILTER_ID) {\n return input.groups;\n }\n return input.groups.filter(\n (group) => (group.filterId ?? group.id) === input.filterId\n );\n}\n\nexport function groupRichTextAtMatches(input: {\n expandedCounts?: Readonly<Record<string, number | undefined>>;\n filterId: RichTextAtFilterId;\n groups: readonly RichTextTriggerProviderGroup[];\n matches: readonly RichTextAtQueryMatch[];\n pageSize?: number;\n}): RichTextAtSearchGroup[] {\n const visibleGroups = filterGroupsForRichTextAtPanel({\n filterId: input.filterId,\n groups: input.groups\n });\n const pageSize = input.pageSize ?? DEFAULT_RICH_TEXT_AT_PANEL_PAGE_SIZE;\n return visibleGroups\n .map<RichTextAtSearchGroup | null>((group) => {\n const providerIds = new Set(group.providerIds);\n const items = input.matches.filter((match) =>\n providerIds.has(match.providerId)\n );\n const groupPageSize = group.pageSize ?? pageSize;\n const visibleCount = Math.min(\n items.length,\n input.expandedCounts?.[group.id] ?? groupPageSize\n );\n if (items.length === 0 && !group.emptyLabel) {\n return null;\n }\n return {\n id: group.id,\n label: group.label,\n items: items.slice(0, visibleCount),\n totalCount: items.length,\n visibleCount,\n hasMore: items.length > visibleCount,\n emptyLabel: group.emptyLabel\n } satisfies RichTextAtSearchGroup;\n })\n .filter((group): group is RichTextAtSearchGroup => group !== null);\n}\n\nexport function richTextAtGroupExpandCount(\n group: RichTextAtSearchGroup,\n pageSize = DEFAULT_RICH_TEXT_AT_PANEL_PAGE_SIZE\n): number {\n const remaining = Math.max(0, group.totalCount - group.visibleCount);\n return Math.min(pageSize, remaining);\n}\n\nexport function findRichTextTriggerProviderGroup(\n groups: readonly RichTextTriggerProviderGroup[],\n groupId: RichTextAtGroupId\n): RichTextTriggerProviderGroup | undefined {\n return groups.find((group) => group.id === groupId);\n}\n","import type { RichTextTriggerQueryMatch as RichTextAtQueryMatch } from \"../types/trigger.ts\";\nimport type {\n MentionPaletteGroup,\n MentionPaletteState\n} from \"./mentionPaletteTypes.ts\";\nimport { groupRichTextAtMatches } from \"./searchHelpers.ts\";\nimport type { RichTextTriggerProviderGroup } from \"./types.ts\";\n\nexport function buildMentionPaletteState(input: {\n matches: readonly RichTextAtQueryMatch[];\n providerGroups: readonly RichTextTriggerProviderGroup[];\n filterTabs: readonly { id: string; label: string }[];\n activeFilterId: string;\n expandedCounts: Record<string, number | undefined>;\n query: string;\n isLoading: boolean;\n pageSize?: number;\n showMoreLabel?: (count: number) => string;\n /**\n * Optional predicate gating whether a group's header label is emitted. When\n * provided and it returns false, the group renders without a label (matching\n * the agent composer's conditional `shouldRenderMentionGroupLabel` rule, e.g.\n * hiding a single group's header when it just duplicates the active filter\n * tab). When omitted, the group label is always emitted (legacy behavior).\n */\n shouldRenderGroupLabel?: (groupId: string, groupCount: number) => boolean;\n}): MentionPaletteState<RichTextAtQueryMatch> {\n const searchGroups = groupRichTextAtMatches({\n expandedCounts: input.expandedCounts,\n filterId: input.activeFilterId,\n groups: input.providerGroups,\n matches: input.matches,\n pageSize: input.pageSize\n });\n\n const groups: readonly MentionPaletteGroup<RichTextAtQueryMatch>[] =\n searchGroups.map((group) => ({\n id: group.id,\n label:\n input.shouldRenderGroupLabel != null &&\n !input.shouldRenderGroupLabel(group.id, searchGroups.length)\n ? undefined\n : group.label,\n items: group.items,\n totalCount: group.totalCount,\n visibleCount: group.visibleCount,\n hasMore: group.hasMore,\n emptyLabel: group.emptyLabel,\n expandLabel:\n group.hasMore && input.showMoreLabel != null\n ? input.showMoreLabel(group.totalCount - group.visibleCount)\n : undefined\n }));\n\n const categories = input.filterTabs;\n const filter = input.activeFilterId;\n const query = input.query;\n const isEmptyQuery = query === \"\";\n\n if (input.isLoading) {\n return {\n status: \"loading\",\n query,\n mode: isEmptyQuery ? \"browse\" : \"results\",\n filter,\n categories,\n groups,\n error: null\n };\n }\n\n if (isEmptyQuery) {\n return {\n status: \"idle\",\n query,\n mode: \"browse\",\n filter,\n categories,\n groups,\n error: null\n };\n }\n\n return {\n status: \"ready\",\n query,\n mode: \"results\",\n filter,\n categories,\n groups,\n error: null\n };\n}\n","import type {\n MentionPaletteEntry,\n MentionPaletteState\n} from \"./mentionPaletteTypes.ts\";\n\n/**\n * Returns true when at least one group has items or a \"load more\" trigger,\n * i.e. there is something interactive to render beyond category headers.\n */\nfunction hasInteractiveGroupEntries<TItem>(\n groups: MentionPaletteState<TItem>[\"groups\"]\n): boolean {\n return groups.some((group) => group.items.length > 0 || group.hasMore);\n}\n\n/**\n * Flatten the palette state into a stable, ordered list of navigable entries.\n *\n * Mirrors the ordering and key format of `flattenAgentMentionPaletteEntries`\n * from AgentFileMentionPalette.tsx, but is generic over item type.\n *\n * Key formats:\n * category entry → `category:<categoryId>`\n * item entry → `<groupId>:<getItemKey(item, groupId)>`\n * expand entry → `expand:<groupId>`\n */\nexport function flattenMentionPaletteEntries<TItem>(\n state: MentionPaletteState<TItem>,\n getItemKey: (item: TItem, groupId: string) => string\n): MentionPaletteEntry[] {\n // Browse mode with no interactive group content → show category nav only\n if (state.mode === \"browse\" && !hasInteractiveGroupEntries(state.groups)) {\n return state.categories.map((category) => ({\n key: `category:${category.id}`,\n type: \"category\" as const,\n categoryId: category.id\n }));\n }\n\n const entries: MentionPaletteEntry[] = [];\n\n for (const group of state.groups) {\n group.items.forEach((item, index) => {\n entries.push({\n key: `${group.id}:${getItemKey(item, group.id)}`,\n type: \"item\",\n groupId: group.id,\n itemIndex: index\n });\n });\n\n if (group.hasMore) {\n entries.push({\n key: `expand:${group.id}`,\n type: \"expand\",\n groupId: group.id\n });\n }\n }\n\n return entries;\n}\n","/**\n * Tone → className maps for the {@link MentionStatusBadge} rendered inside a\n * {@link MentionRow}. The surface resolves a status into a data-only\n * {@link MentionRowStatusTag} (label + tone + variant); this module owns the\n * presentational mapping so the styling stays in one place and identical across\n * surfaces.\n */\nexport type MentionRowStatusTone =\n | \"amber\"\n | \"blue\"\n | \"green\"\n | \"neutral\"\n | \"red\";\n\nexport type MentionRowStatusVariant = \"activity\" | \"issue\";\n\n/**\n * Background/text classes for the agent activity status badge. Ported verbatim\n * from the agent's `mentionStatusBadgeClassName` so the rendered DOM is\n * unchanged.\n */\nexport function activityMentionStatusBadgeClassName(\n tone: MentionRowStatusTone\n): string {\n switch (tone) {\n case \"blue\":\n return \"bg-sky-500/10 text-sky-700\";\n case \"amber\":\n return \"bg-[color:color-mix(in_srgb,var(--color-amber-500)_12%,transparent)] text-[var(--color-amber-500)]\";\n case \"green\":\n return \"bg-[var(--tsh-ui-pill-success-bg)] text-[var(--tsh-ui-pill-success-fg)]\";\n case \"red\":\n return \"bg-[var(--on-danger)] text-[var(--state-danger)]\";\n default:\n return \"bg-[var(--transparency-block)] text-[var(--text-secondary)]\";\n }\n}\n\n/**\n * Background/text classes for the issue status badge. Ported verbatim from the\n * agent's `issueMentionStatusBadgeClassName` (keyed by the issue tone the\n * surface resolves).\n */\nexport function issueMentionStatusBadgeClassName(\n tone: MentionRowStatusTone\n): string {\n switch (tone) {\n case \"green\":\n return \"bg-[color:color-mix(in_srgb,var(--state-success)_12%,transparent)] text-[var(--state-success)]\";\n case \"red\":\n return \"bg-[var(--on-danger)] text-[var(--state-danger)]\";\n default:\n return \"bg-[var(--transparency-block)] text-[var(--text-secondary)]\";\n }\n}\n\nexport function mentionStatusBadgeClassName(input: {\n tone: MentionRowStatusTone;\n variant: MentionRowStatusVariant;\n}): string {\n return input.variant === \"issue\"\n ? issueMentionStatusBadgeClassName(input.tone)\n : activityMentionStatusBadgeClassName(input.tone);\n}\n\n/**\n * Map a normalized agent-activity display status to its badge tone. Shared by\n * every `@`-mention surface that renders a session row (agent composer,\n * issue-manager) so the activity status badge color is identical across\n * surfaces. Mirrors the agent composer's local `mentionStatusTone` mapping\n * verbatim (the agent keeps its own copy producing identical values). The label\n * is resolved by each surface; only the tone lives here.\n */\nexport function activityMentionStatusTone(\n status: string\n): MentionRowStatusTone {\n switch (status.trim().toLowerCase()) {\n case \"working\":\n return \"blue\";\n case \"waiting\":\n case \"canceled\":\n return \"amber\";\n case \"completed\":\n case \"idle\":\n return \"green\";\n case \"failed\":\n return \"red\";\n default:\n return \"neutral\";\n }\n}\n\n/**\n * Map an issue status string to its badge tone. Shared by every `@`-mention\n * surface that renders an issue row (agent composer, issue-manager) so the\n * status badge color is identical across surfaces. The label is resolved by\n * each surface's own i18n; only the tone lives here.\n */\nexport function issueMentionStatusTone(status: string): MentionRowStatusTone {\n switch (status.trim().toLowerCase()) {\n case \"completed\":\n return \"green\";\n case \"failed\":\n case \"canceled\":\n return \"red\";\n default:\n return \"neutral\";\n }\n}\n","/**\n * Pure, dependency-free file visual-kind helpers shared by every `@`-mention\n * surface that renders a {@link MentionRow}. The *base* extension → kind\n * resolution lives in each surface (the agent maps file-manager kinds, etc.);\n * this module owns only the surface-agnostic vocabulary and the thumbnail rule\n * so the shared row renderer never imports a workspace feature.\n */\nexport type MentionFileVisualKind =\n | \"back\"\n | \"document\"\n | \"code\"\n | \"markdown\"\n | \"image\"\n | \"video\"\n | \"folder\";\n\nexport interface MentionFileVisualKindInput {\n entryKind?: string | null;\n mentionNavigation?: string | null;\n /**\n * The base visual kind already resolved from the file extension/name by the\n * surface (e.g. the agent's file-manager mapping). Used as the fallback when\n * the entry is neither a back-navigation marker nor a directory.\n */\n baseVisualKind: MentionFileVisualKind;\n}\n\n/**\n * Resolve the row's visual kind from a pre-resolved {@link MentionFileVisualKindInput.baseVisualKind}\n * plus the structural markers (back navigation, directory) that override it.\n */\nexport function resolveMentionFileVisualKind(\n input: MentionFileVisualKindInput\n): MentionFileVisualKind {\n if (input.mentionNavigation === \"agent-generated-folder-back\") {\n return \"back\";\n }\n if (input.entryKind === \"directory\") {\n return \"folder\";\n }\n return input.baseVisualKind;\n}\n\n/**\n * The thumbnail is only shown for image entries with a non-empty thumbnail URL.\n */\nexport function resolveMentionFileThumbnailUrl(input: {\n visualKind: MentionFileVisualKind;\n thumbnailUrl?: string | null;\n}): string | undefined {\n if (input.visualKind !== \"image\") {\n return undefined;\n }\n const thumbnailUrl = input.thumbnailUrl?.trim() ?? \"\";\n return thumbnailUrl || undefined;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createRichTextLinkMarkdown,
|
|
3
3
|
createRichTextMentionMarkdown
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-QOVFZUZN.js";
|
|
5
5
|
|
|
6
6
|
// src/plugins/mention.ts
|
|
7
7
|
var richTextMentionTrigger = "@";
|
|
@@ -9,22 +9,52 @@ function normalizeOptionalString(value) {
|
|
|
9
9
|
const trimmed = value?.trim();
|
|
10
10
|
return trimmed ? trimmed : void 0;
|
|
11
11
|
}
|
|
12
|
-
function
|
|
13
|
-
|
|
12
|
+
function normalizeMentionLabel(value) {
|
|
13
|
+
return value.trim().replace(/^@+/, "").trim();
|
|
14
|
+
}
|
|
15
|
+
function normalizeStringRecord(values) {
|
|
16
|
+
if (!values) {
|
|
14
17
|
return void 0;
|
|
15
18
|
}
|
|
16
|
-
const nextEntries = Object.entries(
|
|
19
|
+
const nextEntries = Object.entries(values).map(([key, value]) => [key.trim(), value.trim()]).filter(([key, value]) => key.length > 0 && value.length > 0);
|
|
17
20
|
if (nextEntries.length === 0) {
|
|
18
21
|
return void 0;
|
|
19
22
|
}
|
|
20
23
|
return Object.freeze(Object.fromEntries(nextEntries));
|
|
21
24
|
}
|
|
22
|
-
function
|
|
23
|
-
|
|
25
|
+
function normalizeMentionPresentation(presentation) {
|
|
26
|
+
if (!presentation) {
|
|
27
|
+
return void 0;
|
|
28
|
+
}
|
|
29
|
+
const normalized = {};
|
|
30
|
+
const iconUrl = normalizeOptionalString(presentation.iconUrl);
|
|
31
|
+
const thumbnailUrl = normalizeOptionalString(presentation.thumbnailUrl);
|
|
32
|
+
const subtitle = normalizeOptionalString(presentation.subtitle);
|
|
33
|
+
const description = normalizeOptionalString(presentation.description);
|
|
34
|
+
const status = normalizeOptionalString(presentation.status);
|
|
35
|
+
if (iconUrl) {
|
|
36
|
+
normalized.iconUrl = iconUrl;
|
|
37
|
+
}
|
|
38
|
+
if (thumbnailUrl) {
|
|
39
|
+
normalized.thumbnailUrl = thumbnailUrl;
|
|
40
|
+
}
|
|
41
|
+
if (subtitle) {
|
|
42
|
+
normalized.subtitle = subtitle;
|
|
43
|
+
}
|
|
44
|
+
if (description) {
|
|
45
|
+
normalized.description = description;
|
|
46
|
+
}
|
|
47
|
+
if (status) {
|
|
48
|
+
normalized.status = status;
|
|
49
|
+
}
|
|
50
|
+
return Object.keys(normalized).length > 0 ? Object.freeze(normalized) : void 0;
|
|
51
|
+
}
|
|
52
|
+
function createRichTextMentionAttrs(providerId, mention) {
|
|
53
|
+
const normalizedProviderId = providerId.trim();
|
|
24
54
|
const entityId = mention.entityId.trim();
|
|
25
|
-
const label = mention.label
|
|
26
|
-
if (!
|
|
27
|
-
throw new Error("Rich text mention
|
|
55
|
+
const label = normalizeMentionLabel(mention.label);
|
|
56
|
+
if (!normalizedProviderId) {
|
|
57
|
+
throw new Error("Rich text mention provider id is required.");
|
|
28
58
|
}
|
|
29
59
|
if (!entityId) {
|
|
30
60
|
throw new Error("Rich text mention entityId is required.");
|
|
@@ -32,37 +62,44 @@ function createRichTextMentionAttrs(pluginId, mention) {
|
|
|
32
62
|
if (!label) {
|
|
33
63
|
throw new Error("Rich text mention label is required.");
|
|
34
64
|
}
|
|
35
|
-
|
|
65
|
+
const attrs = {
|
|
36
66
|
trigger: richTextMentionTrigger,
|
|
37
|
-
|
|
67
|
+
providerId: normalizedProviderId,
|
|
38
68
|
entityId,
|
|
39
|
-
label
|
|
40
|
-
href: normalizeOptionalString(mention.href),
|
|
41
|
-
kind: normalizeOptionalString(mention.kind),
|
|
42
|
-
version: normalizeOptionalString(mention.version),
|
|
43
|
-
meta: normalizeMentionMeta(mention.meta)
|
|
69
|
+
label
|
|
44
70
|
};
|
|
71
|
+
const scope = normalizeStringRecord(mention.scope);
|
|
72
|
+
const presentation = normalizeMentionPresentation(mention.presentation);
|
|
73
|
+
if (scope) {
|
|
74
|
+
attrs.scope = scope;
|
|
75
|
+
}
|
|
76
|
+
if (presentation) {
|
|
77
|
+
attrs.presentation = presentation;
|
|
78
|
+
}
|
|
79
|
+
return attrs;
|
|
45
80
|
}
|
|
46
81
|
function isRichTextMentionAttrs(value) {
|
|
47
82
|
if (!value || typeof value !== "object") {
|
|
48
83
|
return false;
|
|
49
84
|
}
|
|
50
85
|
const candidate = value;
|
|
51
|
-
return candidate.trigger === richTextMentionTrigger && typeof candidate.
|
|
86
|
+
return candidate.trigger === richTextMentionTrigger && typeof candidate.providerId === "string" && candidate.providerId.trim().length > 0 && typeof candidate.entityId === "string" && candidate.entityId.trim().length > 0 && typeof candidate.label === "string" && candidate.label.trim().length > 0;
|
|
52
87
|
}
|
|
53
88
|
function getRichTextMentionDisplayText(attrs) {
|
|
54
|
-
|
|
89
|
+
const label = normalizeMentionLabel(attrs.label);
|
|
90
|
+
return label ? `@${label}` : "";
|
|
55
91
|
}
|
|
56
92
|
function resolveRichTextMentionView(mention, resolved) {
|
|
57
93
|
const state = resolved?.state ?? "active";
|
|
58
|
-
const label = resolved?.label
|
|
59
|
-
const href = normalizeOptionalString(resolved?.href);
|
|
94
|
+
const label = normalizeMentionLabel(resolved?.label ?? mention.label);
|
|
60
95
|
const tooltip = normalizeOptionalString(resolved?.tooltip);
|
|
61
96
|
return {
|
|
62
97
|
state,
|
|
63
98
|
label,
|
|
64
99
|
tooltip,
|
|
65
|
-
|
|
100
|
+
presentation: normalizeMentionPresentation(
|
|
101
|
+
resolved?.presentation ?? mention.presentation
|
|
102
|
+
),
|
|
66
103
|
entity: resolved?.entity,
|
|
67
104
|
interactive: state === "active"
|
|
68
105
|
};
|
|
@@ -79,8 +116,7 @@ function createRichTextMentionPlugin(plugin) {
|
|
|
79
116
|
};
|
|
80
117
|
}
|
|
81
118
|
|
|
82
|
-
// src/plugins/
|
|
83
|
-
var richTextAtTrigger = "@";
|
|
119
|
+
// src/plugins/trigger.ts
|
|
84
120
|
function normalizeRequiredString(value, fieldName) {
|
|
85
121
|
const trimmed = value.trim();
|
|
86
122
|
if (!trimmed) {
|
|
@@ -107,7 +143,7 @@ function createRichTextMentionInsertResult(mention) {
|
|
|
107
143
|
mention
|
|
108
144
|
};
|
|
109
145
|
}
|
|
110
|
-
function
|
|
146
|
+
function renderRichTextTriggerInsertResult(providerId, result) {
|
|
111
147
|
switch (result.kind) {
|
|
112
148
|
case "mention":
|
|
113
149
|
return createRichTextMentionMarkdown(
|
|
@@ -125,37 +161,74 @@ function renderRichTextAtInsertResult(providerId, result) {
|
|
|
125
161
|
return "";
|
|
126
162
|
}
|
|
127
163
|
}
|
|
128
|
-
function
|
|
164
|
+
function createRichTextTriggerProvider(provider) {
|
|
129
165
|
const id = normalizeRequiredString(provider.id, "provider id");
|
|
130
166
|
return {
|
|
131
167
|
...provider,
|
|
132
|
-
id
|
|
133
|
-
trigger: richTextAtTrigger
|
|
168
|
+
id
|
|
134
169
|
};
|
|
135
170
|
}
|
|
136
171
|
|
|
137
|
-
// src/plugins/
|
|
172
|
+
// src/plugins/triggerRegistry.ts
|
|
138
173
|
function normalizeProviderId(providerId) {
|
|
139
174
|
return providerId.trim();
|
|
140
175
|
}
|
|
141
|
-
function
|
|
176
|
+
function normalizeProviderTrigger(provider) {
|
|
177
|
+
return provider.trigger;
|
|
178
|
+
}
|
|
179
|
+
function normalizeProviderBoundary(provider) {
|
|
180
|
+
return provider.boundary ?? "punctuation";
|
|
181
|
+
}
|
|
182
|
+
function normalizeProviderTriggerConfig(provider) {
|
|
183
|
+
return {
|
|
184
|
+
trigger: normalizeProviderTrigger(provider),
|
|
185
|
+
boundary: normalizeProviderBoundary(provider)
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function normalizeOptionalThumbnailUrl(value) {
|
|
189
|
+
const trimmed = value?.trim();
|
|
190
|
+
return trimmed ? trimmed : void 0;
|
|
191
|
+
}
|
|
192
|
+
async function resolveItemThumbnailUrl(provider, item) {
|
|
193
|
+
if (!provider.getItemThumbnailUrl) {
|
|
194
|
+
return void 0;
|
|
195
|
+
}
|
|
196
|
+
try {
|
|
197
|
+
return normalizeOptionalThumbnailUrl(
|
|
198
|
+
await Promise.resolve(provider.getItemThumbnailUrl(item))
|
|
199
|
+
);
|
|
200
|
+
} catch {
|
|
201
|
+
return void 0;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
function createRichTextTriggerRegistry(providers) {
|
|
142
205
|
const providerMap = /* @__PURE__ */ new Map();
|
|
206
|
+
const triggerConfigKeys = /* @__PURE__ */ new Set();
|
|
207
|
+
const triggerConfigs = [];
|
|
143
208
|
for (const provider of providers) {
|
|
144
209
|
const providerId = normalizeProviderId(provider.id);
|
|
145
210
|
if (!providerId) {
|
|
146
|
-
throw new Error("Rich text
|
|
211
|
+
throw new Error("Rich text trigger provider id is required.");
|
|
147
212
|
}
|
|
148
213
|
if (providerMap.has(providerId)) {
|
|
149
|
-
throw new Error(`Duplicate rich text
|
|
214
|
+
throw new Error(`Duplicate rich text trigger provider id: ${providerId}`);
|
|
150
215
|
}
|
|
151
216
|
providerMap.set(providerId, provider);
|
|
217
|
+
const triggerConfig = normalizeProviderTriggerConfig(provider);
|
|
218
|
+
const triggerConfigKey = `${triggerConfig.trigger}:${triggerConfig.boundary}`;
|
|
219
|
+
if (!triggerConfigKeys.has(triggerConfigKey)) {
|
|
220
|
+
triggerConfigKeys.add(triggerConfigKey);
|
|
221
|
+
triggerConfigs.push(triggerConfig);
|
|
222
|
+
}
|
|
152
223
|
}
|
|
153
224
|
async function query(input) {
|
|
154
225
|
if (input.abortSignal?.aborted) {
|
|
155
226
|
return [];
|
|
156
227
|
}
|
|
157
228
|
const matches = await Promise.all(
|
|
158
|
-
[...providerMap.values()].
|
|
229
|
+
[...providerMap.values()].filter(
|
|
230
|
+
(provider) => normalizeProviderTrigger(provider) === input.trigger
|
|
231
|
+
).map(async (provider) => {
|
|
159
232
|
if (input.abortSignal?.aborted) {
|
|
160
233
|
return [];
|
|
161
234
|
}
|
|
@@ -163,15 +236,19 @@ function createRichTextAtRegistry(providers) {
|
|
|
163
236
|
if (input.abortSignal?.aborted) {
|
|
164
237
|
return [];
|
|
165
238
|
}
|
|
166
|
-
return
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
239
|
+
return Promise.all(
|
|
240
|
+
items.map(async (item) => ({
|
|
241
|
+
providerId: provider.id,
|
|
242
|
+
trigger: input.trigger,
|
|
243
|
+
key: provider.getItemKey(item),
|
|
244
|
+
label: provider.getItemLabel(item),
|
|
245
|
+
subtitle: provider.getItemSubtitle?.(item) || void 0,
|
|
246
|
+
thumbnailUrl: await resolveItemThumbnailUrl(provider, item),
|
|
247
|
+
keywords: provider.getItemKeywords?.(item),
|
|
248
|
+
item,
|
|
249
|
+
insertResult: provider.toInsertResult(item)
|
|
250
|
+
}))
|
|
251
|
+
);
|
|
175
252
|
})
|
|
176
253
|
);
|
|
177
254
|
const flatMatches = matches.flat();
|
|
@@ -184,6 +261,7 @@ function createRichTextAtRegistry(providers) {
|
|
|
184
261
|
return {
|
|
185
262
|
listProviders: () => [...providerMap.values()],
|
|
186
263
|
getProvider: (providerId) => providerMap.get(normalizeProviderId(providerId)),
|
|
264
|
+
listTriggerConfigs: () => [...triggerConfigs],
|
|
187
265
|
query
|
|
188
266
|
};
|
|
189
267
|
}
|
|
@@ -227,7 +305,7 @@ function createRichTextMentionRegistry(plugins) {
|
|
|
227
305
|
return flatMatches;
|
|
228
306
|
}
|
|
229
307
|
async function resolve(input) {
|
|
230
|
-
const plugin = pluginMap.get(input.mention.
|
|
308
|
+
const plugin = pluginMap.get(input.mention.providerId);
|
|
231
309
|
if (!plugin) {
|
|
232
310
|
return resolveRichTextMentionView(input.mention, {
|
|
233
311
|
state: "missing"
|
|
@@ -260,9 +338,9 @@ export {
|
|
|
260
338
|
createRichTextTextInsertResult,
|
|
261
339
|
createRichTextMarkdownLinkInsertResult,
|
|
262
340
|
createRichTextMentionInsertResult,
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
341
|
+
renderRichTextTriggerInsertResult,
|
|
342
|
+
createRichTextTriggerProvider,
|
|
343
|
+
createRichTextTriggerRegistry,
|
|
266
344
|
createRichTextMentionRegistry
|
|
267
345
|
};
|
|
268
|
-
//# sourceMappingURL=chunk-
|
|
346
|
+
//# sourceMappingURL=chunk-QK6NMNYN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/plugins/mention.ts","../src/plugins/trigger.ts","../src/plugins/triggerRegistry.ts","../src/plugins/mentionRegistry.ts"],"sourcesContent":["import type {\n RichTextMentionAttrs,\n RichTextMentionInsert,\n RichTextMentionPresentation,\n RichTextMentionPlugin,\n RichTextResolvedMention,\n RichTextResolvedMentionView\n} from \"../types/mention.ts\";\n\nconst richTextMentionTrigger = \"@\";\n\nfunction normalizeOptionalString(value?: string | null): string | undefined {\n const trimmed = value?.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction normalizeMentionLabel(value: string): string {\n return value.trim().replace(/^@+/, \"\").trim();\n}\n\nfunction normalizeStringRecord(\n values?: Readonly<Record<string, string>> | null\n): Readonly<Record<string, string>> | undefined {\n if (!values) {\n return undefined;\n }\n\n const nextEntries = Object.entries(values)\n .map(([key, value]) => [key.trim(), value.trim()] as const)\n .filter(([key, value]) => key.length > 0 && value.length > 0);\n\n if (nextEntries.length === 0) {\n return undefined;\n }\n\n return Object.freeze(Object.fromEntries(nextEntries));\n}\n\nfunction normalizeMentionPresentation(\n presentation?: RichTextMentionPresentation | null\n): RichTextMentionPresentation | undefined {\n if (!presentation) {\n return undefined;\n }\n\n const normalized: RichTextMentionPresentation = {};\n const iconUrl = normalizeOptionalString(presentation.iconUrl);\n const thumbnailUrl = normalizeOptionalString(presentation.thumbnailUrl);\n const subtitle = normalizeOptionalString(presentation.subtitle);\n const description = normalizeOptionalString(presentation.description);\n const status = normalizeOptionalString(presentation.status);\n\n if (iconUrl) {\n normalized.iconUrl = iconUrl;\n }\n if (thumbnailUrl) {\n normalized.thumbnailUrl = thumbnailUrl;\n }\n if (subtitle) {\n normalized.subtitle = subtitle;\n }\n if (description) {\n normalized.description = description;\n }\n if (status) {\n normalized.status = status;\n }\n\n return Object.keys(normalized).length > 0\n ? Object.freeze(normalized)\n : undefined;\n}\n\nexport function createRichTextMentionAttrs(\n providerId: string,\n mention: RichTextMentionInsert\n): RichTextMentionAttrs {\n const normalizedProviderId = providerId.trim();\n const entityId = mention.entityId.trim();\n const label = normalizeMentionLabel(mention.label);\n\n if (!normalizedProviderId) {\n throw new Error(\"Rich text mention provider id is required.\");\n }\n if (!entityId) {\n throw new Error(\"Rich text mention entityId is required.\");\n }\n if (!label) {\n throw new Error(\"Rich text mention label is required.\");\n }\n\n const attrs: RichTextMentionAttrs = {\n trigger: richTextMentionTrigger,\n providerId: normalizedProviderId,\n entityId,\n label\n };\n const scope = normalizeStringRecord(mention.scope);\n const presentation = normalizeMentionPresentation(mention.presentation);\n if (scope) {\n attrs.scope = scope;\n }\n if (presentation) {\n attrs.presentation = presentation;\n }\n return attrs;\n}\n\nexport function isRichTextMentionAttrs(\n value: unknown\n): value is RichTextMentionAttrs {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n\n const candidate = value as Partial<RichTextMentionAttrs>;\n return (\n candidate.trigger === richTextMentionTrigger &&\n typeof candidate.providerId === \"string\" &&\n candidate.providerId.trim().length > 0 &&\n typeof candidate.entityId === \"string\" &&\n candidate.entityId.trim().length > 0 &&\n typeof candidate.label === \"string\" &&\n candidate.label.trim().length > 0\n );\n}\n\nexport function getRichTextMentionDisplayText(\n attrs: RichTextMentionAttrs\n): string {\n const label = normalizeMentionLabel(attrs.label);\n return label ? `@${label}` : \"\";\n}\n\nexport function resolveRichTextMentionView(\n mention: RichTextMentionAttrs,\n resolved?: RichTextResolvedMention | null\n): RichTextResolvedMentionView {\n const state = resolved?.state ?? \"active\";\n const label = normalizeMentionLabel(resolved?.label ?? mention.label);\n const tooltip = normalizeOptionalString(resolved?.tooltip);\n\n return {\n state,\n label,\n tooltip,\n presentation: normalizeMentionPresentation(\n resolved?.presentation ?? mention.presentation\n ),\n entity: resolved?.entity,\n interactive: state === \"active\"\n };\n}\n\nexport function createRichTextMentionPlugin<TItem, TResolved = unknown>(\n plugin: RichTextMentionPlugin<TItem, TResolved>\n): RichTextMentionPlugin<TItem, TResolved> {\n const id = plugin.id.trim();\n if (!id) {\n throw new Error(\"Rich text mention plugin id is required.\");\n }\n\n return {\n ...plugin,\n id,\n trigger: richTextMentionTrigger\n };\n}\n","import { createRichTextMentionAttrs } from \"./mention.ts\";\nimport {\n createRichTextMentionMarkdown,\n createRichTextLinkMarkdown\n} from \"../core/richTextDocument.ts\";\nimport type {\n RichTextTriggerProvider,\n RichTextMarkdownLinkInsertResult,\n RichTextMentionTriggerInsertResult,\n RichTextTriggerInsertResult,\n RichTextTextInsertResult\n} from \"../types/trigger.ts\";\n\nfunction normalizeRequiredString(value: string, fieldName: string): string {\n const trimmed = value.trim();\n if (!trimmed) {\n throw new Error(`Rich text ${fieldName} is required.`);\n }\n return trimmed;\n}\n\nexport function createRichTextTextInsertResult(\n text: string\n): RichTextTextInsertResult {\n return {\n kind: \"text\",\n text\n };\n}\n\nexport function createRichTextMarkdownLinkInsertResult(\n label: string,\n href: string\n): RichTextMarkdownLinkInsertResult {\n return {\n kind: \"markdown-link\",\n label: normalizeRequiredString(label, \"insert label\"),\n href: normalizeRequiredString(href, \"insert href\")\n };\n}\n\nexport function createRichTextMentionInsertResult(\n mention: RichTextMentionTriggerInsertResult[\"mention\"]\n): RichTextMentionTriggerInsertResult {\n return {\n kind: \"mention\",\n mention\n };\n}\n\nexport function renderRichTextTriggerInsertResult(\n providerId: string,\n result: RichTextTriggerInsertResult\n): string {\n switch (result.kind) {\n case \"mention\":\n return createRichTextMentionMarkdown(\n createRichTextMentionAttrs(providerId, result.mention)\n );\n case \"markdown-link\":\n return createRichTextLinkMarkdown({\n name: result.label,\n path: result.href,\n kind: result.href.endsWith(\"/\") ? \"folder\" : \"file\"\n });\n case \"text\":\n return result.text;\n default:\n return \"\";\n }\n}\n\nexport function createRichTextTriggerProvider<TItem>(\n provider: RichTextTriggerProvider<TItem>\n): RichTextTriggerProvider<TItem> {\n const id = normalizeRequiredString(provider.id, \"provider id\");\n\n return {\n ...provider,\n id\n };\n}\n","import type {\n RichTextTrigger,\n RichTextTriggerBoundary,\n RichTextTriggerConfig,\n RichTextTriggerProvider,\n RichTextTriggerQueryInput,\n RichTextTriggerQueryMatch,\n RichTextTriggerRegistry\n} from \"../types/trigger.ts\";\n\nfunction normalizeProviderId(providerId: string): string {\n return providerId.trim();\n}\n\nfunction normalizeProviderTrigger(\n provider: RichTextTriggerProvider\n): RichTextTrigger {\n return provider.trigger;\n}\n\nfunction normalizeProviderBoundary(\n provider: RichTextTriggerProvider\n): RichTextTriggerBoundary {\n return provider.boundary ?? \"punctuation\";\n}\n\nfunction normalizeProviderTriggerConfig(\n provider: RichTextTriggerProvider\n): RichTextTriggerConfig {\n return {\n trigger: normalizeProviderTrigger(provider),\n boundary: normalizeProviderBoundary(provider)\n };\n}\n\nfunction normalizeOptionalThumbnailUrl(\n value: string | null | undefined\n): string | undefined {\n const trimmed = value?.trim();\n return trimmed ? trimmed : undefined;\n}\n\nasync function resolveItemThumbnailUrl<TItem>(\n provider: RichTextTriggerProvider<TItem>,\n item: TItem\n): Promise<string | undefined> {\n if (!provider.getItemThumbnailUrl) {\n return undefined;\n }\n try {\n return normalizeOptionalThumbnailUrl(\n await Promise.resolve(provider.getItemThumbnailUrl(item))\n );\n } catch {\n return undefined;\n }\n}\n\nexport function createRichTextTriggerRegistry(\n providers: readonly RichTextTriggerProvider[]\n): RichTextTriggerRegistry {\n const providerMap = new Map<string, RichTextTriggerProvider>();\n const triggerConfigKeys = new Set<string>();\n const triggerConfigs: RichTextTriggerConfig[] = [];\n\n for (const provider of providers) {\n const providerId = normalizeProviderId(provider.id);\n if (!providerId) {\n throw new Error(\"Rich text trigger provider id is required.\");\n }\n if (providerMap.has(providerId)) {\n throw new Error(`Duplicate rich text trigger provider id: ${providerId}`);\n }\n providerMap.set(providerId, provider);\n const triggerConfig = normalizeProviderTriggerConfig(provider);\n const triggerConfigKey = `${triggerConfig.trigger}:${triggerConfig.boundary}`;\n if (!triggerConfigKeys.has(triggerConfigKey)) {\n triggerConfigKeys.add(triggerConfigKey);\n triggerConfigs.push(triggerConfig);\n }\n }\n\n async function query(\n input: RichTextTriggerQueryInput\n ): Promise<readonly RichTextTriggerQueryMatch[]> {\n if (input.abortSignal?.aborted) {\n return [];\n }\n\n const matches = await Promise.all(\n [...providerMap.values()]\n .filter(\n (provider) => normalizeProviderTrigger(provider) === input.trigger\n )\n .map(async (provider) => {\n if (input.abortSignal?.aborted) {\n return [];\n }\n const items = await provider.query(input);\n if (input.abortSignal?.aborted) {\n return [];\n }\n return Promise.all(\n items.map(async (item) => ({\n providerId: provider.id,\n trigger: input.trigger,\n key: provider.getItemKey(item),\n label: provider.getItemLabel(item),\n subtitle: provider.getItemSubtitle?.(item) || undefined,\n thumbnailUrl: await resolveItemThumbnailUrl(provider, item),\n keywords: provider.getItemKeywords?.(item),\n item,\n insertResult: provider.toInsertResult(item)\n }))\n );\n })\n );\n\n const flatMatches = matches.flat();\n const limit = input.maxResults;\n if (typeof limit === \"number\" && limit >= 0) {\n return flatMatches.slice(0, limit);\n }\n return flatMatches;\n }\n\n return {\n listProviders: () => [...providerMap.values()],\n getProvider: (providerId: string) =>\n providerMap.get(normalizeProviderId(providerId)),\n listTriggerConfigs: () => [...triggerConfigs],\n query\n };\n}\n","import {\n createRichTextMentionAttrs,\n resolveRichTextMentionView\n} from \"./mention.ts\";\nimport type {\n RichTextMentionPlugin,\n RichTextMentionQueryInput,\n RichTextMentionQueryMatch,\n RichTextMentionRegistry,\n RichTextMentionResolveInput,\n RichTextResolvedMentionView\n} from \"../types/mention.ts\";\n\nfunction normalizePluginId(pluginId: string): string {\n return pluginId.trim();\n}\n\nexport function createRichTextMentionRegistry(\n plugins: readonly RichTextMentionPlugin[]\n): RichTextMentionRegistry {\n const pluginMap = new Map<string, RichTextMentionPlugin>();\n\n for (const plugin of plugins) {\n const pluginId = normalizePluginId(plugin.id);\n if (!pluginId) {\n throw new Error(\"Rich text mention plugin id is required.\");\n }\n if (pluginMap.has(pluginId)) {\n throw new Error(`Duplicate rich text mention plugin id: ${pluginId}`);\n }\n pluginMap.set(pluginId, plugin);\n }\n\n async function query(\n input: RichTextMentionQueryInput\n ): Promise<readonly RichTextMentionQueryMatch[]> {\n const matches = await Promise.all(\n [...pluginMap.values()].map(async (plugin) => {\n const items = await plugin.query(input);\n return items.map<RichTextMentionQueryMatch>((item) => ({\n pluginId: plugin.id,\n key: plugin.getItemKey(item),\n label: plugin.getItemLabel(item),\n subtitle: plugin.getItemSubtitle?.(item) || undefined,\n keywords: plugin.getItemKeywords?.(item),\n item,\n mention: createRichTextMentionAttrs(plugin.id, plugin.toMention(item))\n }));\n })\n );\n\n const flatMatches = matches.flat();\n const limit = input.maxResults;\n if (typeof limit === \"number\" && limit >= 0) {\n return flatMatches.slice(0, limit);\n }\n return flatMatches;\n }\n\n async function resolve(\n input: RichTextMentionResolveInput\n ): Promise<RichTextResolvedMentionView> {\n const plugin = pluginMap.get(input.mention.providerId);\n if (!plugin) {\n return resolveRichTextMentionView(input.mention, {\n state: \"missing\"\n });\n }\n\n if (!plugin.resolveMention) {\n return resolveRichTextMentionView(input.mention, {\n state: \"active\"\n });\n }\n\n return resolveRichTextMentionView(\n input.mention,\n await plugin.resolveMention(input)\n );\n }\n\n return {\n listPlugins: () => [...pluginMap.values()],\n getPlugin: (pluginId: string) => pluginMap.get(normalizePluginId(pluginId)),\n query,\n resolve\n };\n}\n"],"mappings":"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","names":[]}
|