@tutti-os/ui-rich-text 0.0.23 → 0.0.24
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 +18 -0
- package/dist/at-panel/index.css +586 -10
- package/dist/at-panel/index.css.map +1 -1
- package/dist/at-panel/index.d.ts +124 -5
- package/dist/at-panel/index.js +921 -175
- package/dist/at-panel/index.js.map +1 -1
- package/dist/at-panel/model.d.ts +72 -86
- package/dist/at-panel/model.js +17 -19
- package/dist/chunk-3ZXEASYU.js +268 -0
- package/dist/chunk-3ZXEASYU.js.map +1 -0
- package/package.json +4 -3
- package/dist/chunk-E4PWFY3N.js +0 -264
- package/dist/chunk-E4PWFY3N.js.map +0 -1
package/dist/chunk-E4PWFY3N.js
DELETED
|
@@ -1,264 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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":[]}
|