@tutti-os/ui-rich-text 0.0.25 → 0.0.26

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 CHANGED
@@ -160,20 +160,161 @@ Current runtime behavior:
160
160
  - mention hydration uses `resolveMention` when the owning trigger provider is
161
161
  available and keeps the label-only fallback when it is not
162
162
 
163
- ## At-Panel Migration
164
-
165
- The `@tutti-os/ui-rich-text/at-panel` subpath now exposes the shared mention
166
- palette shell through:
167
-
168
- - `MentionPaletteFromState`
169
- - `createMentionPaletteStateAdapter`
170
- - `buildMentionPaletteModel`
171
- - `buildMentionPaletteModelFromTriggerMatches`
172
- - `richTextTriggerQueryMatchToMentionRowItem`
173
-
174
- Older helpers such as `buildMentionPaletteState`, `searchHelpers`, and
175
- `RichTextAt*` grouping aliases were removed with the legacy flat grouping model.
176
- Consumers should build category/section config with
177
- `MentionPaletteCategoryConfig`, derive state with
178
- `buildMentionPaletteModelFromTriggerMatches`, and keep app-specific copy,
179
- i18n, provider selection, and insertion behavior in the host application.
163
+ ## External At-Panel Integration
164
+
165
+ External apps should treat `@tutti-os/ui-rich-text` as the generic trigger and
166
+ palette shell, not as an app-domain data source. The app still owns what can be
167
+ mentioned, how those items are queried, and what gets inserted.
168
+
169
+ Tutti workspace apps that already receive mention candidates from
170
+ `window.tuttiExternal.at.query()` should adapt that bridge through
171
+ `@tutti-os/workspace-external-core/rich-text`:
172
+
173
+ ```ts
174
+ import { createTuttiExternalAtRichTextTriggerProviders } from "@tutti-os/workspace-external-core/rich-text";
175
+
176
+ const providers = createTuttiExternalAtRichTextTriggerProviders({
177
+ bridge: window.tuttiExternal,
178
+ providerIds: ["workspace-app", "agent-session"]
179
+ });
180
+ ```
181
+
182
+ Use a custom `RichTextTriggerProvider` only for app-local mention sources or for
183
+ apps that do not use the Tutti external bridge.
184
+
185
+ Minimum integration checklist:
186
+
187
+ 1. Install the package and load the panel CSS once from the app entry point:
188
+
189
+ ```ts
190
+ import "@tutti-os/ui-rich-text/at-panel/index.css";
191
+ ```
192
+
193
+ 2. Provide one or more `RichTextTriggerProvider`s for the app's mentionable
194
+ domains. Host-provided Tutti workspace mentions can come from
195
+ `createTuttiExternalAtRichTextTriggerProviders`; app-local domains can define
196
+ providers directly. A provider owns querying, stable keys, visible labels,
197
+ optional subtitles/icons/keywords, insertion mapping, and optional reverse
198
+ resolution:
199
+
200
+ ```ts
201
+ import type { RichTextTriggerProvider } from "@tutti-os/ui-rich-text/types";
202
+
203
+ const providers: RichTextTriggerProvider[] = [
204
+ {
205
+ id: "primary-record",
206
+ trigger: "@",
207
+ query: async ({ keyword, context }) => searchRecords(keyword, context),
208
+ getItemKey: (record) => record.id,
209
+ getItemLabel: (record) => record.title,
210
+ getItemSubtitle: (record) => record.subtitle,
211
+ getItemIconUrl: (record) => record.iconUrl,
212
+ toInsertResult: (record) => ({
213
+ kind: "mention",
214
+ mention: {
215
+ entityId: record.id,
216
+ label: record.title,
217
+ scope: { ownerId: record.ownerId }
218
+ }
219
+ })
220
+ }
221
+ ];
222
+ ```
223
+
224
+ 3. Query those providers through the rich-text trigger registry or an
225
+ equivalent host bridge and keep the results as
226
+ `RichTextTriggerQueryMatch[]`. Provider ordering remains host-owned. The
227
+ palette only renders the matches it is given.
228
+
229
+ 4. Define palette categories in the app. A category is the top-level tab/filter;
230
+ optional `sections` become second-level groups inside the active category.
231
+ When sections are present, each match is assigned to the first matching
232
+ section in declaration order. A category without sections renders as a
233
+ single group:
234
+
235
+ ```ts
236
+ import type { MentionPaletteCategoryConfig } from "@tutti-os/ui-rich-text/at-panel";
237
+
238
+ const categories: MentionPaletteCategoryConfig[] = [
239
+ {
240
+ id: "primary",
241
+ label: t("mentions.primary"),
242
+ providerIds: ["primary-record"],
243
+ sections: [
244
+ {
245
+ id: "recent",
246
+ label: t("mentions.recent"),
247
+ matches: (match) => match.item.bucket === "recent"
248
+ },
249
+ {
250
+ id: "all",
251
+ label: t("mentions.all"),
252
+ matches: (match) => match.item.bucket !== "recent"
253
+ }
254
+ ]
255
+ },
256
+ {
257
+ id: "secondary",
258
+ label: t("mentions.secondary"),
259
+ providerIds: ["secondary-record"]
260
+ }
261
+ ];
262
+ ```
263
+
264
+ 5. Convert matches into palette state and render the shared shell:
265
+
266
+ ```tsx
267
+ import {
268
+ MentionPaletteFromState,
269
+ buildMentionPaletteModelFromTriggerMatches,
270
+ renderMentionRow,
271
+ richTextTriggerQueryMatchToMentionRowItem
272
+ } from "@tutti-os/ui-rich-text/at-panel";
273
+
274
+ const state = buildMentionPaletteModelFromTriggerMatches({
275
+ activeCategoryId,
276
+ categories,
277
+ matches,
278
+ loading,
279
+ query
280
+ });
281
+
282
+ <MentionPaletteFromState
283
+ state={state}
284
+ highlightedKey={highlightedKey}
285
+ getItemKey={(match, groupId) => `${match.providerId}:${match.key}`}
286
+ callbacks={{
287
+ onActiveCategoryIdChange: setActiveCategoryId,
288
+ onHighlightChange: setHighlightedKey,
289
+ onSelectItem: commitMatch
290
+ }}
291
+ labels={{
292
+ empty: t("mentions.empty"),
293
+ loading: t("mentions.loading")
294
+ }}
295
+ hintLabels={{
296
+ cycleFilter: t("mentions.switchCategory"),
297
+ moveSelection: t("mentions.switchSelection")
298
+ }}
299
+ maxHeightPx={360}
300
+ renderItem={(match) =>
301
+ renderMentionRow(
302
+ richTextTriggerQueryMatchToMentionRowItem(match, {
303
+ getDescription: (candidate) => candidate.subtitle,
304
+ renderLeading: (ctx) => renderAppSpecificLeading(ctx)
305
+ })
306
+ )
307
+ }
308
+ />;
309
+ ```
310
+
311
+ 6. Wire keyboard handling to the state adapter or to `makeAtPanelKeyDown`.
312
+ External apps should keep the exact shortcut policy local; the shared shell
313
+ supports moving selection, cycling categories, expanding groups, and
314
+ committing the highlighted item.
315
+
316
+ 7. Keep app-owned behavior outside the package. This includes i18n strings,
317
+ item-specific icons or avatars, domain data fetches, cache refresh policy,
318
+ app-local bridge calls, and the final insertion side effects. Use
319
+ `renderLeading`, `getDescription`, status helpers, and category/section
320
+ config as customization slots instead of forking the panel shell.
@@ -97,6 +97,13 @@ var RESERVED_MENTION_SCOPE_KEYS = /* @__PURE__ */ new Set([
97
97
  "v",
98
98
  "version"
99
99
  ]);
100
+ var PRESENTATION_MENTION_CONTEXT_KEYS = /* @__PURE__ */ new Set([
101
+ "agentIconUrl",
102
+ "iconUrl",
103
+ "thumbnailUrl",
104
+ "userAvatarPlaceholderUrl"
105
+ ]);
106
+ var DEFAULT_MENTION_CONTEXT_MAX_VALUE_LENGTH = 2048;
100
107
  function normalizeLineEndings(value) {
101
108
  return value.replace(/\r\n?/g, "\n");
102
109
  }
@@ -178,6 +185,52 @@ function normalizeMentionLabel(value) {
178
185
  function isReservedMentionScopeKey(key) {
179
186
  return RESERVED_MENTION_SCOPE_KEYS.has(key) || key.startsWith("meta.");
180
187
  }
188
+ function isPresentationMentionContextKey(key) {
189
+ return PRESENTATION_MENTION_CONTEXT_KEYS.has(key);
190
+ }
191
+ function isUnsafeMentionContextValue(value, maxValueLength) {
192
+ const normalizedValue = value.toLowerCase();
193
+ return value.length > maxValueLength || normalizedValue.startsWith("data:") || normalizedValue.startsWith("blob:");
194
+ }
195
+ function sanitizeRichTextMentionScopeForAgentContext(scope, options = {}) {
196
+ if (!scope) {
197
+ return void 0;
198
+ }
199
+ const maxValueLength = options.maxValueLength && options.maxValueLength > 0 ? options.maxValueLength : DEFAULT_MENTION_CONTEXT_MAX_VALUE_LENGTH;
200
+ const nextScope = {};
201
+ for (const [key, value] of Object.entries(scope).sort(
202
+ ([left], [right]) => left.localeCompare(right)
203
+ )) {
204
+ const nextKey = key.trim();
205
+ if (!nextKey || isReservedMentionScopeKey(nextKey) || isPresentationMentionContextKey(nextKey) || typeof value !== "string") {
206
+ continue;
207
+ }
208
+ const nextValue = value.trim();
209
+ if (!nextValue || isUnsafeMentionContextValue(nextValue, maxValueLength)) {
210
+ continue;
211
+ }
212
+ nextScope[nextKey] = nextValue;
213
+ }
214
+ return Object.keys(nextScope).length ? nextScope : void 0;
215
+ }
216
+ function sanitizeRichTextMentionForAgentContext(mention, options = {}) {
217
+ const providerId = mention.providerId?.trim() ?? "";
218
+ const entityId = mention.entityId?.trim() ?? "";
219
+ const label = normalizeMentionLabel(mention.label ?? "") || entityId;
220
+ if (!providerId || !entityId || !label) {
221
+ return void 0;
222
+ }
223
+ const scope = sanitizeRichTextMentionScopeForAgentContext(
224
+ mention.scope,
225
+ options
226
+ );
227
+ return {
228
+ providerId,
229
+ entityId,
230
+ label,
231
+ ...scope ? { scope } : {}
232
+ };
233
+ }
181
234
  function createMentionQueryParams(mention) {
182
235
  const params = new URLSearchParams();
183
236
  for (const [key, value] of Object.entries(mention.scope ?? {}).sort(
@@ -528,6 +581,8 @@ export {
528
581
  findRichTextMarkdownLinks,
529
582
  normalizeRichTextContent,
530
583
  isRichTextMentionHref,
584
+ sanitizeRichTextMentionScopeForAgentContext,
585
+ sanitizeRichTextMentionForAgentContext,
531
586
  createRichTextMentionHref,
532
587
  createRichTextMentionMarkdown,
533
588
  parseRichTextMentionHref,
@@ -543,4 +598,4 @@ export {
543
598
  parseRichTextContentToDocument,
544
599
  serializeRichTextDocumentToContent
545
600
  };
546
- //# sourceMappingURL=chunk-W2IS5BLZ.js.map
601
+ //# sourceMappingURL=chunk-HO3WOO7V.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/extensions/names.ts","../src/core/richTextMarkdownLinks.ts","../src/core/richTextDocument.ts"],"sourcesContent":["export const workspaceReferenceNodeName = \"workspaceReference\";\nexport const mentionReferenceNodeName = \"mentionReference\";\n","export interface RichTextMarkdownLinkMatch {\n href: string;\n index: number;\n label: string;\n source: string;\n to: number;\n}\n\nexport function* findRichTextMarkdownLinks(\n value: string\n): Generator<RichTextMarkdownLinkMatch> {\n let cursor = 0;\n\n while (cursor < value.length) {\n const labelStart = value.indexOf(\"[\", cursor);\n if (labelStart < 0) {\n return;\n }\n if (labelStart > 0 && value[labelStart - 1] === \"!\") {\n cursor = labelStart + 1;\n continue;\n }\n\n const labelEnd = findMarkdownLabelEnd(value, labelStart + 1);\n if (labelEnd < 0 || value[labelEnd + 1] !== \"(\") {\n cursor = labelStart + 1;\n continue;\n }\n\n const hrefStart = labelEnd + 2;\n const hrefEnd = findMarkdownHrefEnd(value, hrefStart);\n if (hrefEnd < 0) {\n cursor = labelStart + 1;\n continue;\n }\n\n yield {\n href: unescapeMarkdownLinkText(value.slice(hrefStart, hrefEnd)),\n index: labelStart,\n label: unescapeMarkdownLinkText(value.slice(labelStart + 1, labelEnd)),\n source: value.slice(labelStart, hrefEnd + 1),\n to: hrefEnd + 1\n };\n cursor = hrefEnd + 1;\n }\n}\n\nfunction unescapeMarkdownLinkText(value: string): string {\n return value.replace(/\\\\([\\\\[\\]()])/g, \"$1\");\n}\n\nfunction findMarkdownLabelEnd(value: string, cursor: number): number {\n let escaped = false;\n\n for (let index = cursor; index < value.length; index += 1) {\n const char = value[index];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === \"\\\\\") {\n escaped = true;\n continue;\n }\n if (char === \"]\") {\n return index;\n }\n }\n\n return -1;\n}\n\nfunction findMarkdownHrefEnd(value: string, cursor: number): number {\n let escaped = false;\n let depth = 0;\n\n for (let index = cursor; index < value.length; index += 1) {\n const char = value[index];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === \"\\\\\") {\n escaped = true;\n continue;\n }\n if (char === \"(\") {\n depth += 1;\n continue;\n }\n if (char !== \")\") {\n continue;\n }\n if (depth === 0) {\n return index;\n }\n depth -= 1;\n }\n\n return -1;\n}\n","import type { JSONContent } from \"@tiptap/core\";\nimport {\n mentionReferenceNodeName,\n workspaceReferenceNodeName\n} from \"../extensions/names.ts\";\nimport type {\n RichTextMentionAttrs,\n RichTextMentionIdentity\n} from \"../types/mention.ts\";\nimport {\n findRichTextMarkdownLinks,\n type RichTextMarkdownLinkMatch\n} from \"./richTextMarkdownLinks.ts\";\n\nexport type RichTextLinkRef = {\n name: string;\n path: string;\n href: string;\n kind: \"file\" | \"folder\";\n};\n\nexport type RichTextLinkInput = {\n name?: string | null;\n path: string;\n kind?: \"file\" | \"folder\";\n};\n\nexport type RichTextMentionRef = RichTextMentionAttrs;\nexport type RichTextDocument = JSONContent;\n\nconst MARKDOWN_IMAGE_PATTERN = /!\\[([^\\]]*)\\]\\(([^)\\s]+)\\)/g;\nconst EXTERNAL_LINK_PREFIX = /^(?:[a-z]+:)?\\/\\//i;\nconst MENTION_LINK_PREFIX = /^mention:\\/\\//i;\nconst RESERVED_MENTION_SCOPE_KEYS = new Set([\n \"appId\",\n \"id\",\n \"kind\",\n \"link\",\n \"provider\",\n \"v\",\n \"version\"\n]);\nconst PRESENTATION_MENTION_CONTEXT_KEYS = new Set([\n \"agentIconUrl\",\n \"iconUrl\",\n \"thumbnailUrl\",\n \"userAvatarPlaceholderUrl\"\n]);\nconst DEFAULT_MENTION_CONTEXT_MAX_VALUE_LENGTH = 2048;\n\nexport interface RichTextMentionAgentContext {\n providerId: string;\n entityId: string;\n label: string;\n scope?: Readonly<Record<string, string>>;\n}\n\nexport interface SanitizeRichTextMentionContextOptions {\n maxValueLength?: number;\n}\n\ntype LegacyJSONContentNode = {\n type?: string;\n text?: string;\n attrs?: Record<string, unknown>;\n content?: LegacyJSONContentNode[];\n};\n\nfunction normalizeLineEndings(value: string): string {\n return value.replace(/\\r\\n?/g, \"\\n\");\n}\n\nfunction normalizeContentString(value?: string | null): string {\n const trimmed = normalizeLineEndings(value ?? \"\").trim();\n if (!trimmed) {\n return \"\";\n }\n const markdown = convertLegacyDocumentString(trimmed);\n return markdown || trimmed;\n}\n\nexport function normalizeRichTextContent(value?: string | null): string {\n return normalizeContentString(value);\n}\n\nfunction convertLegacyDocumentString(value: string): string {\n try {\n const parsed = JSON.parse(value) as LegacyJSONContentNode;\n if (parsed?.type !== \"doc\" || !Array.isArray(parsed.content)) {\n return \"\";\n }\n return renderLegacyNodesToMarkdown(parsed.content).trim();\n } catch {\n return \"\";\n }\n}\n\nfunction renderLegacyNodesToMarkdown(nodes: LegacyJSONContentNode[]): string {\n return nodes\n .map((node) => renderLegacyNodeToMarkdown(node))\n .filter((part) => part.length > 0)\n .join(\"\\n\\n\");\n}\n\nfunction renderLegacyNodeToMarkdown(\n node: LegacyJSONContentNode | null | undefined\n): string {\n if (!node) {\n return \"\";\n }\n if (node.type === \"text\") {\n return node.text ?? \"\";\n }\n if (node.type === \"workspaceFileLink\") {\n const attrs = node.attrs ?? {};\n const kind = attrs.kind === \"folder\" ? \"folder\" : \"file\";\n const hrefValue =\n (typeof attrs.href === \"string\" ? attrs.href : undefined) ||\n (typeof attrs.path === \"string\" ? attrs.path : undefined) ||\n \"\";\n const href = normalizeRichTextLinkHref(hrefValue, kind);\n const label =\n (typeof attrs.name === \"string\" ? attrs.name : undefined)?.trim() ||\n href.split(\"/\").filter(Boolean).at(-1) ||\n href;\n return href && label ? `[${label}](${href})` : label;\n }\n if (Array.isArray(node.content)) {\n const inline = node.content\n .map((child) => renderLegacyNodeToMarkdown(child))\n .filter((part) => part.length > 0)\n .join(\"\")\n .trim();\n if (!inline) {\n return \"\";\n }\n if (node.type === \"paragraph\") {\n return inline;\n }\n return inline;\n }\n return \"\";\n}\n\nfunction normalizeWorkspacePath(\n pathOrHref: string,\n kind: \"file\" | \"folder\"\n): string {\n const trimmed = pathOrHref.trim();\n if (!trimmed) {\n return \"\";\n }\n if (kind === \"folder\" && !trimmed.endsWith(\"/\")) {\n return `${trimmed}/`;\n }\n return trimmed;\n}\n\nfunction isWorkspaceReferenceHref(href: string): boolean {\n const trimmed = href.trim();\n if (\n !trimmed ||\n MENTION_LINK_PREFIX.test(trimmed) ||\n EXTERNAL_LINK_PREFIX.test(trimmed)\n ) {\n return false;\n }\n return true;\n}\n\nexport function isRichTextMentionHref(href: string): boolean {\n return MENTION_LINK_PREFIX.test(href.trim());\n}\n\nfunction normalizeMentionLabel(value: string): string {\n return value.trim().replace(/^@+/, \"\").trim();\n}\n\nfunction isReservedMentionScopeKey(key: string): boolean {\n return RESERVED_MENTION_SCOPE_KEYS.has(key) || key.startsWith(\"meta.\");\n}\n\nfunction isPresentationMentionContextKey(key: string): boolean {\n return PRESENTATION_MENTION_CONTEXT_KEYS.has(key);\n}\n\nfunction isUnsafeMentionContextValue(value: string, maxValueLength: number) {\n const normalizedValue = value.toLowerCase();\n return (\n value.length > maxValueLength ||\n normalizedValue.startsWith(\"data:\") ||\n normalizedValue.startsWith(\"blob:\")\n );\n}\n\nexport function sanitizeRichTextMentionScopeForAgentContext(\n scope?: Readonly<Record<string, unknown>> | null,\n options: SanitizeRichTextMentionContextOptions = {}\n): Record<string, string> | undefined {\n if (!scope) {\n return undefined;\n }\n const maxValueLength =\n options.maxValueLength && options.maxValueLength > 0\n ? options.maxValueLength\n : DEFAULT_MENTION_CONTEXT_MAX_VALUE_LENGTH;\n const nextScope: Record<string, string> = {};\n for (const [key, value] of Object.entries(scope).sort(([left], [right]) =>\n left.localeCompare(right)\n )) {\n const nextKey = key.trim();\n if (\n !nextKey ||\n isReservedMentionScopeKey(nextKey) ||\n isPresentationMentionContextKey(nextKey) ||\n typeof value !== \"string\"\n ) {\n continue;\n }\n const nextValue = value.trim();\n if (!nextValue || isUnsafeMentionContextValue(nextValue, maxValueLength)) {\n continue;\n }\n nextScope[nextKey] = nextValue;\n }\n return Object.keys(nextScope).length ? nextScope : undefined;\n}\n\nexport function sanitizeRichTextMentionForAgentContext(\n mention: {\n providerId?: string | null;\n entityId?: string | null;\n label?: string | null;\n scope?: Readonly<Record<string, unknown>> | null;\n },\n options: SanitizeRichTextMentionContextOptions = {}\n): RichTextMentionAgentContext | undefined {\n const providerId = mention.providerId?.trim() ?? \"\";\n const entityId = mention.entityId?.trim() ?? \"\";\n const label = normalizeMentionLabel(mention.label ?? \"\") || entityId;\n if (!providerId || !entityId || !label) {\n return undefined;\n }\n const scope = sanitizeRichTextMentionScopeForAgentContext(\n mention.scope,\n options\n );\n return {\n providerId,\n entityId,\n label,\n ...(scope ? { scope } : {})\n };\n}\n\nfunction createMentionQueryParams(\n mention: RichTextMentionIdentity\n): URLSearchParams {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(mention.scope ?? {}).sort(\n ([left], [right]) => left.localeCompare(right)\n )) {\n const nextKey = key.trim();\n const nextValue = value.trim();\n if (!nextKey || !nextValue || isReservedMentionScopeKey(nextKey)) {\n continue;\n }\n params.set(nextKey, nextValue);\n }\n return params;\n}\n\nexport function createRichTextMentionHref(\n mention: RichTextMentionIdentity\n): string {\n const providerId = mention.providerId.trim();\n const entityId = mention.entityId.trim();\n const label = normalizeMentionLabel(mention.label);\n if (!providerId || !entityId || !label) {\n return \"\";\n }\n\n const params = createMentionQueryParams(mention);\n const queryString = params.toString();\n const pathname = `${encodeURIComponent(providerId)}/${encodeURIComponent(entityId)}`;\n return queryString\n ? `mention://${pathname}?${queryString}`\n : `mention://${pathname}`;\n}\n\nexport function createRichTextMentionMarkdown(\n mention: RichTextMentionIdentity\n): string {\n const label = normalizeMentionLabel(mention.label);\n const href = createRichTextMentionHref(mention);\n if (!label || !href) {\n return \"\";\n }\n return `[${escapeMarkdownLinkLabel(`@${label}`)}](${escapeMarkdownLinkHref(href)})`;\n}\n\nexport function parseRichTextMentionHref(\n href: string,\n label?: string | null\n): RichTextMentionRef | null {\n const trimmedHref = href.trim();\n if (!isRichTextMentionHref(trimmedHref)) {\n return null;\n }\n\n try {\n const parsed = new URL(trimmedHref);\n const providerId = decodeURIComponent(parsed.hostname).trim();\n const encodedEntityId = parsed.pathname.replace(/^\\/+/, \"\");\n const entityId = decodeURIComponent(encodedEntityId).trim();\n const rawLabel = normalizeMentionLabel(label?.trim() ?? \"\");\n\n if (\n !providerId ||\n !encodedEntityId ||\n encodedEntityId.includes(\"/\") ||\n !entityId\n ) {\n return null;\n }\n\n const nextLabel = rawLabel || entityId;\n\n const scopeEntries: Array<readonly [string, string]> = [];\n for (const [key, value] of parsed.searchParams.entries()) {\n const scopeKey = key.trim();\n const scopeValue = value.trim();\n if (!scopeKey || isReservedMentionScopeKey(scopeKey)) {\n return null;\n }\n if (scopeValue) {\n scopeEntries.push([scopeKey, scopeValue]);\n }\n }\n\n const mention: RichTextMentionRef = {\n trigger: \"@\",\n providerId,\n entityId,\n label: nextLabel\n };\n if (scopeEntries.length > 0) {\n mention.scope = Object.fromEntries(scopeEntries);\n }\n return mention;\n } catch {\n return null;\n }\n}\n\nexport function normalizeRichTextLinkHref(\n pathOrHref: string,\n kind: \"file\" | \"folder\" = \"file\"\n): string {\n return normalizeWorkspacePath(pathOrHref, kind);\n}\n\nexport function createRichTextLinkMarkdown(input: RichTextLinkInput): string {\n const kind = input.kind === \"folder\" ? \"folder\" : \"file\";\n const href = normalizeRichTextLinkHref(input.path, kind);\n const displayName =\n input.name?.trim() ||\n href.split(\"/\").filter(Boolean).at(-1) ||\n href ||\n input.path.trim();\n if (!href || !displayName) {\n return \"\";\n }\n return `[${escapeMarkdownLinkLabel(displayName)}](${escapeMarkdownLinkHref(href)})`;\n}\n\nexport function appendRichTextLinksToContent(\n value: string | null | undefined,\n refs: readonly RichTextLinkInput[]\n): string {\n const content = normalizeContentString(value);\n const existing = new Set(\n extractRichTextLinksFromContent(content).map((ref) => ref.path)\n );\n const rendered = refs\n .map((ref) => {\n const kind = ref.kind === \"folder\" ? \"folder\" : \"file\";\n const path = normalizeRichTextLinkHref(ref.path, kind);\n if (!path || existing.has(path)) {\n return \"\";\n }\n existing.add(path);\n return createRichTextLinkMarkdown({ ...ref, path, kind });\n })\n .filter(Boolean);\n\n if (rendered.length === 0) {\n return content;\n }\n return content ? `${content} ${rendered.join(\" \")}` : rendered.join(\" \");\n}\n\nexport function extractRichTextLinksFromContent(\n value: string | null | undefined\n): RichTextLinkRef[] {\n const content = normalizeContentString(value);\n const refs = new Map<string, RichTextLinkRef>();\n for (const match of findRichTextMarkdownLinks(content)) {\n const name = match.label.trim();\n const href = match.href.trim();\n if (!name || !isWorkspaceReferenceHref(href)) {\n continue;\n }\n const kind = href.endsWith(\"/\") ? \"folder\" : \"file\";\n const path = normalizeRichTextLinkHref(href, kind);\n if (!path || refs.has(path)) {\n continue;\n }\n refs.set(path, {\n name,\n path,\n href: path,\n kind\n });\n }\n return [...refs.values()];\n}\n\nexport function extractRichTextMentionsFromContent(\n value: string | null | undefined\n): RichTextMentionRef[] {\n const content = normalizeContentString(value);\n const refs = new Map<string, RichTextMentionRef>();\n\n for (const match of findRichTextMarkdownLinks(content)) {\n const label = match.label.trim();\n const href = match.href.trim();\n const mention = parseRichTextMentionHref(href, label);\n if (!mention) {\n continue;\n }\n const mentionKey = [\n mention.providerId,\n mention.entityId,\n JSON.stringify(\n Object.fromEntries(\n Object.entries(mention.scope ?? {}).sort(([left], [right]) =>\n left.localeCompare(right)\n )\n )\n )\n ].join(\":\");\n if (refs.has(mentionKey)) {\n continue;\n }\n refs.set(mentionKey, mention);\n }\n\n return [...refs.values()];\n}\n\nexport function removeRichTextMentionFromContent(\n content: string,\n mention: Pick<RichTextMentionAttrs, \"providerId\" | \"entityId\">\n): string {\n const providerId = mention.providerId.trim();\n const entityId = mention.entityId.trim();\n if (!providerId || !entityId) {\n return normalizeContentString(content);\n }\n\n const normalized = normalizeContentString(content);\n const next = replaceRichTextMarkdownLinks(normalized, (match) => {\n const parsedMention = parseRichTextMentionHref(match.href, match.label);\n if (!parsedMention) {\n return match.source;\n }\n return parsedMention.providerId === providerId &&\n parsedMention.entityId === entityId\n ? \"\"\n : match.source;\n });\n\n return next\n .replace(/[ \\t]+\\n/g, \"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\nexport function removeRichTextLinkFromContent(\n content: string,\n path: string\n): string {\n const targetPath = path.trim();\n if (!targetPath) {\n return normalizeContentString(content);\n }\n const normalized = normalizeContentString(content);\n const next = replaceRichTextMarkdownLinks(normalized, (match) => {\n const href = match.href.trim();\n const kind = href.endsWith(\"/\") ? \"folder\" : \"file\";\n const refPath = normalizeRichTextLinkHref(href, kind);\n return refPath === targetPath ? \"\" : match.source;\n });\n return next\n .replace(/[ \\t]+\\n/g, \"\\n\")\n .replace(/\\n[ \\t]+/g, \"\\n\")\n .replace(/[ \\t]{2,}/g, \" \")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\nexport function extractPlainTextFromContent(value?: string | null): string {\n const content = normalizeContentString(value);\n if (!content) {\n return \"\";\n }\n return replaceRichTextMarkdownLinks(\n content.replace(MARKDOWN_IMAGE_PATTERN, \" $1 \"),\n (match) => ` ${match.label} `\n )\n .replace(/^[\\s>*#+-]+/gm, \" \")\n .replace(/`([^`]+)`/g, \" $1 \")\n .replace(/[*_~]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nexport function extractPlainTextWithoutFilesFromContent(\n value?: string | null\n): string {\n const content = normalizeContentString(value);\n if (!content) {\n return \"\";\n }\n return replaceRichTextMarkdownLinks(\n content.replace(MARKDOWN_IMAGE_PATTERN, \" \"),\n () => \" \"\n )\n .replace(/^[\\s>*#+-]+/gm, \" \")\n .replace(/`([^`]+)`/g, \" $1 \")\n .replace(/[*_~]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nexport function parseRichTextContentToDocument(\n value?: string | null\n): RichTextDocument {\n const content = normalizeContentString(value);\n if (!content) {\n return {\n type: \"doc\",\n content: [{ type: \"paragraph\" }]\n };\n }\n\n const paragraphs = content\n .split(/\\n{2,}/)\n .map((paragraph) => createRichTextParagraphNode(paragraph))\n .filter((paragraph) => Array.isArray(paragraph.content));\n\n return {\n type: \"doc\",\n content: paragraphs.length > 0 ? paragraphs : [{ type: \"paragraph\" }]\n };\n}\n\nexport function serializeRichTextDocumentToContent(\n document: RichTextDocument\n): string {\n const paragraphs = (document.content ?? [])\n .map((node) => serializeRichTextBlockNode(node))\n .filter((value) => value.length > 0);\n\n return paragraphs.join(\"\\n\\n\").trim();\n}\n\nfunction createRichTextParagraphNode(paragraph: string): JSONContent {\n return {\n type: \"paragraph\",\n content: createRichTextInlineNodes(paragraph)\n };\n}\n\nfunction createRichTextInlineNodes(text: string): JSONContent[] {\n const content: JSONContent[] = [];\n let cursor = 0;\n\n for (const match of findRichTextMarkdownLinks(text)) {\n const { index, source } = match;\n if (index > cursor) {\n appendPlainTextNodes(content, text.slice(cursor, index));\n }\n\n const label = match.label.trim();\n const href = match.href.trim();\n const mention = parseRichTextMentionHref(href, label);\n if (mention) {\n content.push({\n type: mentionReferenceNodeName,\n attrs: mention\n });\n } else if (label && isWorkspaceReferenceHref(href)) {\n const kind = href.endsWith(\"/\") ? \"folder\" : \"file\";\n content.push({\n type: workspaceReferenceNodeName,\n attrs: {\n kind,\n label,\n path: normalizeRichTextLinkHref(href, kind)\n }\n });\n } else {\n appendPlainTextNodes(content, source);\n }\n\n cursor = match.to;\n }\n\n if (cursor < text.length) {\n appendPlainTextNodes(content, text.slice(cursor));\n }\n\n return content;\n}\n\nfunction replaceRichTextMarkdownLinks(\n value: string,\n replace: (match: RichTextMarkdownLinkMatch) => string\n): string {\n let nextValue = \"\";\n let cursor = 0;\n\n for (const match of findRichTextMarkdownLinks(value)) {\n nextValue += value.slice(cursor, match.index);\n nextValue += replace(match);\n cursor = match.to;\n }\n\n return `${nextValue}${value.slice(cursor)}`;\n}\n\nfunction escapeMarkdownLinkLabel(value: string): string {\n return value.replace(/[\\\\[\\]]/g, \"\\\\$&\");\n}\n\nfunction escapeMarkdownLinkHref(value: string): string {\n return value.replace(/[\\\\()]/g, \"\\\\$&\");\n}\n\nfunction appendPlainTextNodes(content: JSONContent[], text: string): void {\n if (!text) {\n return;\n }\n\n const lines = text.split(\"\\n\");\n lines.forEach((line, index) => {\n if (line.length > 0) {\n content.push({\n type: \"text\",\n text: line\n });\n }\n if (index < lines.length - 1) {\n content.push({ type: \"hardBreak\" });\n }\n });\n}\n\nfunction serializeRichTextBlockNode(node: JSONContent): string {\n if (node.type === \"paragraph\") {\n return serializeRichTextInlineNodes(node.content ?? []);\n }\n return serializeRichTextInlineNodes(node.content ?? []);\n}\n\nfunction serializeRichTextInlineNodes(nodes: readonly JSONContent[]): string {\n return nodes\n .map((node) => {\n if (node.type === \"text\") {\n return typeof node.text === \"string\" ? node.text : \"\";\n }\n if (node.type === \"hardBreak\") {\n return \"\\n\";\n }\n if (node.type === workspaceReferenceNodeName) {\n const attrs = node.attrs ?? {};\n return createRichTextLinkMarkdown({\n kind: attrs.kind === \"folder\" ? \"folder\" : \"file\",\n name: typeof attrs.label === \"string\" ? attrs.label : \"\",\n path: typeof attrs.path === \"string\" ? attrs.path : \"\"\n });\n }\n if (node.type === mentionReferenceNodeName) {\n const attrs = node.attrs ?? {};\n const label = typeof attrs.label === \"string\" ? attrs.label.trim() : \"\";\n const providerId =\n typeof attrs.providerId === \"string\" ? attrs.providerId.trim() : \"\";\n const entityId =\n typeof attrs.entityId === \"string\" ? attrs.entityId.trim() : \"\";\n if (!label || !providerId || !entityId) {\n return \"\";\n }\n const scope =\n attrs.scope && typeof attrs.scope === \"object\"\n ? (attrs.scope as Record<string, string>)\n : undefined;\n return createRichTextMentionMarkdown({\n entityId,\n label,\n providerId,\n scope\n });\n }\n\n if (Array.isArray(node.content)) {\n return serializeRichTextInlineNodes(node.content);\n }\n\n return \"\";\n })\n .join(\"\");\n}\n"],"mappings":"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","names":[]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createRichTextLinkMarkdown,
3
3
  createRichTextMentionMarkdown
4
- } from "./chunk-W2IS5BLZ.js";
4
+ } from "./chunk-HO3WOO7V.js";
5
5
 
6
6
  // src/plugins/mention.ts
7
7
  var richTextMentionTrigger = "@";
@@ -355,4 +355,4 @@ export {
355
355
  createRichTextTriggerRegistry,
356
356
  createRichTextMentionRegistry
357
357
  };
358
- //# sourceMappingURL=chunk-RHEJPXOW.js.map
358
+ //# sourceMappingURL=chunk-NNPICKW6.js.map
@@ -14,8 +14,24 @@ type RichTextLinkInput = {
14
14
  };
15
15
  type RichTextMentionRef = RichTextMentionAttrs;
16
16
  type RichTextDocument = JSONContent;
17
+ interface RichTextMentionAgentContext {
18
+ providerId: string;
19
+ entityId: string;
20
+ label: string;
21
+ scope?: Readonly<Record<string, string>>;
22
+ }
23
+ interface SanitizeRichTextMentionContextOptions {
24
+ maxValueLength?: number;
25
+ }
17
26
  declare function normalizeRichTextContent(value?: string | null): string;
18
27
  declare function isRichTextMentionHref(href: string): boolean;
28
+ declare function sanitizeRichTextMentionScopeForAgentContext(scope?: Readonly<Record<string, unknown>> | null, options?: SanitizeRichTextMentionContextOptions): Record<string, string> | undefined;
29
+ declare function sanitizeRichTextMentionForAgentContext(mention: {
30
+ providerId?: string | null;
31
+ entityId?: string | null;
32
+ label?: string | null;
33
+ scope?: Readonly<Record<string, unknown>> | null;
34
+ }, options?: SanitizeRichTextMentionContextOptions): RichTextMentionAgentContext | undefined;
19
35
  declare function createRichTextMentionHref(mention: RichTextMentionIdentity): string;
20
36
  declare function createRichTextMentionMarkdown(mention: RichTextMentionIdentity): string;
21
37
  declare function parseRichTextMentionHref(href: string, label?: string | null): RichTextMentionRef | null;
@@ -31,4 +47,4 @@ declare function extractPlainTextWithoutFilesFromContent(value?: string | null):
31
47
  declare function parseRichTextContentToDocument(value?: string | null): RichTextDocument;
32
48
  declare function serializeRichTextDocumentToContent(document: RichTextDocument): string;
33
49
 
34
- export { type RichTextDocument, type RichTextLinkInput, type RichTextLinkRef, type RichTextMentionRef, appendRichTextLinksToContent, createRichTextLinkMarkdown, createRichTextMentionHref, createRichTextMentionMarkdown, extractPlainTextFromContent, extractPlainTextWithoutFilesFromContent, extractRichTextLinksFromContent, extractRichTextMentionsFromContent, isRichTextMentionHref, normalizeRichTextContent, normalizeRichTextLinkHref, parseRichTextContentToDocument, parseRichTextMentionHref, removeRichTextLinkFromContent, removeRichTextMentionFromContent, serializeRichTextDocumentToContent };
50
+ export { type RichTextDocument, type RichTextLinkInput, type RichTextLinkRef, type RichTextMentionAgentContext, type RichTextMentionRef, type SanitizeRichTextMentionContextOptions, appendRichTextLinksToContent, createRichTextLinkMarkdown, createRichTextMentionHref, createRichTextMentionMarkdown, extractPlainTextFromContent, extractPlainTextWithoutFilesFromContent, extractRichTextLinksFromContent, extractRichTextMentionsFromContent, isRichTextMentionHref, normalizeRichTextContent, normalizeRichTextLinkHref, parseRichTextContentToDocument, parseRichTextMentionHref, removeRichTextLinkFromContent, removeRichTextMentionFromContent, sanitizeRichTextMentionForAgentContext, sanitizeRichTextMentionScopeForAgentContext, serializeRichTextDocumentToContent };
@@ -15,8 +15,10 @@ import {
15
15
  parseRichTextMentionHref,
16
16
  removeRichTextLinkFromContent,
17
17
  removeRichTextMentionFromContent,
18
+ sanitizeRichTextMentionForAgentContext,
19
+ sanitizeRichTextMentionScopeForAgentContext,
18
20
  serializeRichTextDocumentToContent
19
- } from "../chunk-W2IS5BLZ.js";
21
+ } from "../chunk-HO3WOO7V.js";
20
22
  export {
21
23
  appendRichTextLinksToContent,
22
24
  createRichTextLinkMarkdown,
@@ -33,6 +35,8 @@ export {
33
35
  parseRichTextMentionHref,
34
36
  removeRichTextLinkFromContent,
35
37
  removeRichTextMentionFromContent,
38
+ sanitizeRichTextMentionForAgentContext,
39
+ sanitizeRichTextMentionScopeForAgentContext,
36
40
  serializeRichTextDocumentToContent
37
41
  };
38
42
  //# sourceMappingURL=index.js.map
@@ -7,7 +7,7 @@ import {
7
7
  getRichTextMentionDisplayText,
8
8
  renderRichTextTriggerInsertResult,
9
9
  resolveRichTextMentionView
10
- } from "../chunk-RHEJPXOW.js";
10
+ } from "../chunk-NNPICKW6.js";
11
11
  import {
12
12
  findRichTextMarkdownLinks,
13
13
  isRichTextMentionHref,
@@ -18,7 +18,7 @@ import {
18
18
  parseRichTextMentionHref,
19
19
  serializeRichTextDocumentToContent,
20
20
  workspaceReferenceNodeName
21
- } from "../chunk-W2IS5BLZ.js";
21
+ } from "../chunk-HO3WOO7V.js";
22
22
 
23
23
  // src/editor/RichTextTriggerEditor.tsx
24
24
  import {
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  parseRichTextMentionHref,
19
19
  removeRichTextMentionFromContent,
20
20
  serializeRichTextDocumentToContent
21
- } from "./chunk-W2IS5BLZ.js";
21
+ } from "./chunk-HO3WOO7V.js";
22
22
  export {
23
23
  createDefaultRichTextI18nRuntime,
24
24
  createRichTextI18nRuntime,
@@ -11,8 +11,8 @@ import {
11
11
  isRichTextMentionAttrs,
12
12
  renderRichTextTriggerInsertResult,
13
13
  resolveRichTextMentionView
14
- } from "../chunk-RHEJPXOW.js";
15
- import "../chunk-W2IS5BLZ.js";
14
+ } from "../chunk-NNPICKW6.js";
15
+ import "../chunk-HO3WOO7V.js";
16
16
  export {
17
17
  createRichTextMarkdownLinkInsertResult,
18
18
  createRichTextMentionAttrs,
package/package.json CHANGED
@@ -1,38 +1,45 @@
1
1
  {
2
2
  "name": "@tutti-os/ui-rich-text",
3
- "version": "0.0.25",
3
+ "version": "0.0.26",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
7
7
  "exports": {
8
8
  ".": {
9
9
  "types": "./dist/index.d.ts",
10
- "import": "./dist/index.js"
10
+ "import": "./dist/index.js",
11
+ "default": "./dist/index.js"
11
12
  },
12
13
  "./at-panel": {
13
14
  "types": "./dist/at-panel/index.d.ts",
14
- "import": "./dist/at-panel/index.js"
15
+ "import": "./dist/at-panel/index.js",
16
+ "default": "./dist/at-panel/index.js"
15
17
  },
16
18
  "./at-panel/index.css": "./dist/at-panel/index.css",
17
19
  "./at-panel/model": {
18
20
  "types": "./dist/at-panel/model.d.ts",
19
- "import": "./dist/at-panel/model.js"
21
+ "import": "./dist/at-panel/model.js",
22
+ "default": "./dist/at-panel/model.js"
20
23
  },
21
24
  "./core": {
22
25
  "types": "./dist/core/index.d.ts",
23
- "import": "./dist/core/index.js"
26
+ "import": "./dist/core/index.js",
27
+ "default": "./dist/core/index.js"
24
28
  },
25
29
  "./editor": {
26
30
  "types": "./dist/editor/index.d.ts",
27
- "import": "./dist/editor/index.js"
31
+ "import": "./dist/editor/index.js",
32
+ "default": "./dist/editor/index.js"
28
33
  },
29
34
  "./plugins": {
30
35
  "types": "./dist/plugins/index.d.ts",
31
- "import": "./dist/plugins/index.js"
36
+ "import": "./dist/plugins/index.js",
37
+ "default": "./dist/plugins/index.js"
32
38
  },
33
39
  "./types": {
34
40
  "types": "./dist/types/index.d.ts",
35
- "import": "./dist/types/index.js"
41
+ "import": "./dist/types/index.js",
42
+ "default": "./dist/types/index.js"
36
43
  }
37
44
  },
38
45
  "files": [
@@ -45,8 +52,8 @@
45
52
  "directory": "packages/ui/rich-text"
46
53
  },
47
54
  "dependencies": {
48
- "@tutti-os/ui-i18n-runtime": "0.0.25",
49
- "@tutti-os/ui-system": "0.0.25",
55
+ "@tutti-os/ui-i18n-runtime": "0.0.26",
56
+ "@tutti-os/ui-system": "0.0.26",
50
57
  "@tiptap/core": "^3.23.6",
51
58
  "@tiptap/extension-document": "^3.23.6",
52
59
  "@tiptap/extension-hard-break": "^3.23.6",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/extensions/names.ts","../src/core/richTextMarkdownLinks.ts","../src/core/richTextDocument.ts"],"sourcesContent":["export const workspaceReferenceNodeName = \"workspaceReference\";\nexport const mentionReferenceNodeName = \"mentionReference\";\n","export interface RichTextMarkdownLinkMatch {\n href: string;\n index: number;\n label: string;\n source: string;\n to: number;\n}\n\nexport function* findRichTextMarkdownLinks(\n value: string\n): Generator<RichTextMarkdownLinkMatch> {\n let cursor = 0;\n\n while (cursor < value.length) {\n const labelStart = value.indexOf(\"[\", cursor);\n if (labelStart < 0) {\n return;\n }\n if (labelStart > 0 && value[labelStart - 1] === \"!\") {\n cursor = labelStart + 1;\n continue;\n }\n\n const labelEnd = findMarkdownLabelEnd(value, labelStart + 1);\n if (labelEnd < 0 || value[labelEnd + 1] !== \"(\") {\n cursor = labelStart + 1;\n continue;\n }\n\n const hrefStart = labelEnd + 2;\n const hrefEnd = findMarkdownHrefEnd(value, hrefStart);\n if (hrefEnd < 0) {\n cursor = labelStart + 1;\n continue;\n }\n\n yield {\n href: unescapeMarkdownLinkText(value.slice(hrefStart, hrefEnd)),\n index: labelStart,\n label: unescapeMarkdownLinkText(value.slice(labelStart + 1, labelEnd)),\n source: value.slice(labelStart, hrefEnd + 1),\n to: hrefEnd + 1\n };\n cursor = hrefEnd + 1;\n }\n}\n\nfunction unescapeMarkdownLinkText(value: string): string {\n return value.replace(/\\\\([\\\\[\\]()])/g, \"$1\");\n}\n\nfunction findMarkdownLabelEnd(value: string, cursor: number): number {\n let escaped = false;\n\n for (let index = cursor; index < value.length; index += 1) {\n const char = value[index];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === \"\\\\\") {\n escaped = true;\n continue;\n }\n if (char === \"]\") {\n return index;\n }\n }\n\n return -1;\n}\n\nfunction findMarkdownHrefEnd(value: string, cursor: number): number {\n let escaped = false;\n let depth = 0;\n\n for (let index = cursor; index < value.length; index += 1) {\n const char = value[index];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === \"\\\\\") {\n escaped = true;\n continue;\n }\n if (char === \"(\") {\n depth += 1;\n continue;\n }\n if (char !== \")\") {\n continue;\n }\n if (depth === 0) {\n return index;\n }\n depth -= 1;\n }\n\n return -1;\n}\n","import type { JSONContent } from \"@tiptap/core\";\nimport {\n mentionReferenceNodeName,\n workspaceReferenceNodeName\n} from \"../extensions/names.ts\";\nimport type {\n RichTextMentionAttrs,\n RichTextMentionIdentity\n} from \"../types/mention.ts\";\nimport {\n findRichTextMarkdownLinks,\n type RichTextMarkdownLinkMatch\n} from \"./richTextMarkdownLinks.ts\";\n\nexport type RichTextLinkRef = {\n name: string;\n path: string;\n href: string;\n kind: \"file\" | \"folder\";\n};\n\nexport type RichTextLinkInput = {\n name?: string | null;\n path: string;\n kind?: \"file\" | \"folder\";\n};\n\nexport type RichTextMentionRef = RichTextMentionAttrs;\nexport type RichTextDocument = JSONContent;\n\nconst MARKDOWN_IMAGE_PATTERN = /!\\[([^\\]]*)\\]\\(([^)\\s]+)\\)/g;\nconst EXTERNAL_LINK_PREFIX = /^(?:[a-z]+:)?\\/\\//i;\nconst MENTION_LINK_PREFIX = /^mention:\\/\\//i;\nconst RESERVED_MENTION_SCOPE_KEYS = new Set([\n \"appId\",\n \"id\",\n \"kind\",\n \"link\",\n \"provider\",\n \"v\",\n \"version\"\n]);\n\ntype LegacyJSONContentNode = {\n type?: string;\n text?: string;\n attrs?: Record<string, unknown>;\n content?: LegacyJSONContentNode[];\n};\n\nfunction normalizeLineEndings(value: string): string {\n return value.replace(/\\r\\n?/g, \"\\n\");\n}\n\nfunction normalizeContentString(value?: string | null): string {\n const trimmed = normalizeLineEndings(value ?? \"\").trim();\n if (!trimmed) {\n return \"\";\n }\n const markdown = convertLegacyDocumentString(trimmed);\n return markdown || trimmed;\n}\n\nexport function normalizeRichTextContent(value?: string | null): string {\n return normalizeContentString(value);\n}\n\nfunction convertLegacyDocumentString(value: string): string {\n try {\n const parsed = JSON.parse(value) as LegacyJSONContentNode;\n if (parsed?.type !== \"doc\" || !Array.isArray(parsed.content)) {\n return \"\";\n }\n return renderLegacyNodesToMarkdown(parsed.content).trim();\n } catch {\n return \"\";\n }\n}\n\nfunction renderLegacyNodesToMarkdown(nodes: LegacyJSONContentNode[]): string {\n return nodes\n .map((node) => renderLegacyNodeToMarkdown(node))\n .filter((part) => part.length > 0)\n .join(\"\\n\\n\");\n}\n\nfunction renderLegacyNodeToMarkdown(\n node: LegacyJSONContentNode | null | undefined\n): string {\n if (!node) {\n return \"\";\n }\n if (node.type === \"text\") {\n return node.text ?? \"\";\n }\n if (node.type === \"workspaceFileLink\") {\n const attrs = node.attrs ?? {};\n const kind = attrs.kind === \"folder\" ? \"folder\" : \"file\";\n const hrefValue =\n (typeof attrs.href === \"string\" ? attrs.href : undefined) ||\n (typeof attrs.path === \"string\" ? attrs.path : undefined) ||\n \"\";\n const href = normalizeRichTextLinkHref(hrefValue, kind);\n const label =\n (typeof attrs.name === \"string\" ? attrs.name : undefined)?.trim() ||\n href.split(\"/\").filter(Boolean).at(-1) ||\n href;\n return href && label ? `[${label}](${href})` : label;\n }\n if (Array.isArray(node.content)) {\n const inline = node.content\n .map((child) => renderLegacyNodeToMarkdown(child))\n .filter((part) => part.length > 0)\n .join(\"\")\n .trim();\n if (!inline) {\n return \"\";\n }\n if (node.type === \"paragraph\") {\n return inline;\n }\n return inline;\n }\n return \"\";\n}\n\nfunction normalizeWorkspacePath(\n pathOrHref: string,\n kind: \"file\" | \"folder\"\n): string {\n const trimmed = pathOrHref.trim();\n if (!trimmed) {\n return \"\";\n }\n if (kind === \"folder\" && !trimmed.endsWith(\"/\")) {\n return `${trimmed}/`;\n }\n return trimmed;\n}\n\nfunction isWorkspaceReferenceHref(href: string): boolean {\n const trimmed = href.trim();\n if (\n !trimmed ||\n MENTION_LINK_PREFIX.test(trimmed) ||\n EXTERNAL_LINK_PREFIX.test(trimmed)\n ) {\n return false;\n }\n return true;\n}\n\nexport function isRichTextMentionHref(href: string): boolean {\n return MENTION_LINK_PREFIX.test(href.trim());\n}\n\nfunction normalizeMentionLabel(value: string): string {\n return value.trim().replace(/^@+/, \"\").trim();\n}\n\nfunction isReservedMentionScopeKey(key: string): boolean {\n return RESERVED_MENTION_SCOPE_KEYS.has(key) || key.startsWith(\"meta.\");\n}\n\nfunction createMentionQueryParams(\n mention: RichTextMentionIdentity\n): URLSearchParams {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(mention.scope ?? {}).sort(\n ([left], [right]) => left.localeCompare(right)\n )) {\n const nextKey = key.trim();\n const nextValue = value.trim();\n if (!nextKey || !nextValue || isReservedMentionScopeKey(nextKey)) {\n continue;\n }\n params.set(nextKey, nextValue);\n }\n return params;\n}\n\nexport function createRichTextMentionHref(\n mention: RichTextMentionIdentity\n): string {\n const providerId = mention.providerId.trim();\n const entityId = mention.entityId.trim();\n const label = normalizeMentionLabel(mention.label);\n if (!providerId || !entityId || !label) {\n return \"\";\n }\n\n const params = createMentionQueryParams(mention);\n const queryString = params.toString();\n const pathname = `${encodeURIComponent(providerId)}/${encodeURIComponent(entityId)}`;\n return queryString\n ? `mention://${pathname}?${queryString}`\n : `mention://${pathname}`;\n}\n\nexport function createRichTextMentionMarkdown(\n mention: RichTextMentionIdentity\n): string {\n const label = normalizeMentionLabel(mention.label);\n const href = createRichTextMentionHref(mention);\n if (!label || !href) {\n return \"\";\n }\n return `[${escapeMarkdownLinkLabel(`@${label}`)}](${escapeMarkdownLinkHref(href)})`;\n}\n\nexport function parseRichTextMentionHref(\n href: string,\n label?: string | null\n): RichTextMentionRef | null {\n const trimmedHref = href.trim();\n if (!isRichTextMentionHref(trimmedHref)) {\n return null;\n }\n\n try {\n const parsed = new URL(trimmedHref);\n const providerId = decodeURIComponent(parsed.hostname).trim();\n const encodedEntityId = parsed.pathname.replace(/^\\/+/, \"\");\n const entityId = decodeURIComponent(encodedEntityId).trim();\n const rawLabel = normalizeMentionLabel(label?.trim() ?? \"\");\n\n if (\n !providerId ||\n !encodedEntityId ||\n encodedEntityId.includes(\"/\") ||\n !entityId\n ) {\n return null;\n }\n\n const nextLabel = rawLabel || entityId;\n\n const scopeEntries: Array<readonly [string, string]> = [];\n for (const [key, value] of parsed.searchParams.entries()) {\n const scopeKey = key.trim();\n const scopeValue = value.trim();\n if (!scopeKey || isReservedMentionScopeKey(scopeKey)) {\n return null;\n }\n if (scopeValue) {\n scopeEntries.push([scopeKey, scopeValue]);\n }\n }\n\n const mention: RichTextMentionRef = {\n trigger: \"@\",\n providerId,\n entityId,\n label: nextLabel\n };\n if (scopeEntries.length > 0) {\n mention.scope = Object.fromEntries(scopeEntries);\n }\n return mention;\n } catch {\n return null;\n }\n}\n\nexport function normalizeRichTextLinkHref(\n pathOrHref: string,\n kind: \"file\" | \"folder\" = \"file\"\n): string {\n return normalizeWorkspacePath(pathOrHref, kind);\n}\n\nexport function createRichTextLinkMarkdown(input: RichTextLinkInput): string {\n const kind = input.kind === \"folder\" ? \"folder\" : \"file\";\n const href = normalizeRichTextLinkHref(input.path, kind);\n const displayName =\n input.name?.trim() ||\n href.split(\"/\").filter(Boolean).at(-1) ||\n href ||\n input.path.trim();\n if (!href || !displayName) {\n return \"\";\n }\n return `[${escapeMarkdownLinkLabel(displayName)}](${escapeMarkdownLinkHref(href)})`;\n}\n\nexport function appendRichTextLinksToContent(\n value: string | null | undefined,\n refs: readonly RichTextLinkInput[]\n): string {\n const content = normalizeContentString(value);\n const existing = new Set(\n extractRichTextLinksFromContent(content).map((ref) => ref.path)\n );\n const rendered = refs\n .map((ref) => {\n const kind = ref.kind === \"folder\" ? \"folder\" : \"file\";\n const path = normalizeRichTextLinkHref(ref.path, kind);\n if (!path || existing.has(path)) {\n return \"\";\n }\n existing.add(path);\n return createRichTextLinkMarkdown({ ...ref, path, kind });\n })\n .filter(Boolean);\n\n if (rendered.length === 0) {\n return content;\n }\n return content ? `${content} ${rendered.join(\" \")}` : rendered.join(\" \");\n}\n\nexport function extractRichTextLinksFromContent(\n value: string | null | undefined\n): RichTextLinkRef[] {\n const content = normalizeContentString(value);\n const refs = new Map<string, RichTextLinkRef>();\n for (const match of findRichTextMarkdownLinks(content)) {\n const name = match.label.trim();\n const href = match.href.trim();\n if (!name || !isWorkspaceReferenceHref(href)) {\n continue;\n }\n const kind = href.endsWith(\"/\") ? \"folder\" : \"file\";\n const path = normalizeRichTextLinkHref(href, kind);\n if (!path || refs.has(path)) {\n continue;\n }\n refs.set(path, {\n name,\n path,\n href: path,\n kind\n });\n }\n return [...refs.values()];\n}\n\nexport function extractRichTextMentionsFromContent(\n value: string | null | undefined\n): RichTextMentionRef[] {\n const content = normalizeContentString(value);\n const refs = new Map<string, RichTextMentionRef>();\n\n for (const match of findRichTextMarkdownLinks(content)) {\n const label = match.label.trim();\n const href = match.href.trim();\n const mention = parseRichTextMentionHref(href, label);\n if (!mention) {\n continue;\n }\n const mentionKey = [\n mention.providerId,\n mention.entityId,\n JSON.stringify(\n Object.fromEntries(\n Object.entries(mention.scope ?? {}).sort(([left], [right]) =>\n left.localeCompare(right)\n )\n )\n )\n ].join(\":\");\n if (refs.has(mentionKey)) {\n continue;\n }\n refs.set(mentionKey, mention);\n }\n\n return [...refs.values()];\n}\n\nexport function removeRichTextMentionFromContent(\n content: string,\n mention: Pick<RichTextMentionAttrs, \"providerId\" | \"entityId\">\n): string {\n const providerId = mention.providerId.trim();\n const entityId = mention.entityId.trim();\n if (!providerId || !entityId) {\n return normalizeContentString(content);\n }\n\n const normalized = normalizeContentString(content);\n const next = replaceRichTextMarkdownLinks(normalized, (match) => {\n const parsedMention = parseRichTextMentionHref(match.href, match.label);\n if (!parsedMention) {\n return match.source;\n }\n return parsedMention.providerId === providerId &&\n parsedMention.entityId === entityId\n ? \"\"\n : match.source;\n });\n\n return next\n .replace(/[ \\t]+\\n/g, \"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\nexport function removeRichTextLinkFromContent(\n content: string,\n path: string\n): string {\n const targetPath = path.trim();\n if (!targetPath) {\n return normalizeContentString(content);\n }\n const normalized = normalizeContentString(content);\n const next = replaceRichTextMarkdownLinks(normalized, (match) => {\n const href = match.href.trim();\n const kind = href.endsWith(\"/\") ? \"folder\" : \"file\";\n const refPath = normalizeRichTextLinkHref(href, kind);\n return refPath === targetPath ? \"\" : match.source;\n });\n return next\n .replace(/[ \\t]+\\n/g, \"\\n\")\n .replace(/\\n[ \\t]+/g, \"\\n\")\n .replace(/[ \\t]{2,}/g, \" \")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\nexport function extractPlainTextFromContent(value?: string | null): string {\n const content = normalizeContentString(value);\n if (!content) {\n return \"\";\n }\n return replaceRichTextMarkdownLinks(\n content.replace(MARKDOWN_IMAGE_PATTERN, \" $1 \"),\n (match) => ` ${match.label} `\n )\n .replace(/^[\\s>*#+-]+/gm, \" \")\n .replace(/`([^`]+)`/g, \" $1 \")\n .replace(/[*_~]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nexport function extractPlainTextWithoutFilesFromContent(\n value?: string | null\n): string {\n const content = normalizeContentString(value);\n if (!content) {\n return \"\";\n }\n return replaceRichTextMarkdownLinks(\n content.replace(MARKDOWN_IMAGE_PATTERN, \" \"),\n () => \" \"\n )\n .replace(/^[\\s>*#+-]+/gm, \" \")\n .replace(/`([^`]+)`/g, \" $1 \")\n .replace(/[*_~]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nexport function parseRichTextContentToDocument(\n value?: string | null\n): RichTextDocument {\n const content = normalizeContentString(value);\n if (!content) {\n return {\n type: \"doc\",\n content: [{ type: \"paragraph\" }]\n };\n }\n\n const paragraphs = content\n .split(/\\n{2,}/)\n .map((paragraph) => createRichTextParagraphNode(paragraph))\n .filter((paragraph) => Array.isArray(paragraph.content));\n\n return {\n type: \"doc\",\n content: paragraphs.length > 0 ? paragraphs : [{ type: \"paragraph\" }]\n };\n}\n\nexport function serializeRichTextDocumentToContent(\n document: RichTextDocument\n): string {\n const paragraphs = (document.content ?? [])\n .map((node) => serializeRichTextBlockNode(node))\n .filter((value) => value.length > 0);\n\n return paragraphs.join(\"\\n\\n\").trim();\n}\n\nfunction createRichTextParagraphNode(paragraph: string): JSONContent {\n return {\n type: \"paragraph\",\n content: createRichTextInlineNodes(paragraph)\n };\n}\n\nfunction createRichTextInlineNodes(text: string): JSONContent[] {\n const content: JSONContent[] = [];\n let cursor = 0;\n\n for (const match of findRichTextMarkdownLinks(text)) {\n const { index, source } = match;\n if (index > cursor) {\n appendPlainTextNodes(content, text.slice(cursor, index));\n }\n\n const label = match.label.trim();\n const href = match.href.trim();\n const mention = parseRichTextMentionHref(href, label);\n if (mention) {\n content.push({\n type: mentionReferenceNodeName,\n attrs: mention\n });\n } else if (label && isWorkspaceReferenceHref(href)) {\n const kind = href.endsWith(\"/\") ? \"folder\" : \"file\";\n content.push({\n type: workspaceReferenceNodeName,\n attrs: {\n kind,\n label,\n path: normalizeRichTextLinkHref(href, kind)\n }\n });\n } else {\n appendPlainTextNodes(content, source);\n }\n\n cursor = match.to;\n }\n\n if (cursor < text.length) {\n appendPlainTextNodes(content, text.slice(cursor));\n }\n\n return content;\n}\n\nfunction replaceRichTextMarkdownLinks(\n value: string,\n replace: (match: RichTextMarkdownLinkMatch) => string\n): string {\n let nextValue = \"\";\n let cursor = 0;\n\n for (const match of findRichTextMarkdownLinks(value)) {\n nextValue += value.slice(cursor, match.index);\n nextValue += replace(match);\n cursor = match.to;\n }\n\n return `${nextValue}${value.slice(cursor)}`;\n}\n\nfunction escapeMarkdownLinkLabel(value: string): string {\n return value.replace(/[\\\\[\\]]/g, \"\\\\$&\");\n}\n\nfunction escapeMarkdownLinkHref(value: string): string {\n return value.replace(/[\\\\()]/g, \"\\\\$&\");\n}\n\nfunction appendPlainTextNodes(content: JSONContent[], text: string): void {\n if (!text) {\n return;\n }\n\n const lines = text.split(\"\\n\");\n lines.forEach((line, index) => {\n if (line.length > 0) {\n content.push({\n type: \"text\",\n text: line\n });\n }\n if (index < lines.length - 1) {\n content.push({ type: \"hardBreak\" });\n }\n });\n}\n\nfunction serializeRichTextBlockNode(node: JSONContent): string {\n if (node.type === \"paragraph\") {\n return serializeRichTextInlineNodes(node.content ?? []);\n }\n return serializeRichTextInlineNodes(node.content ?? []);\n}\n\nfunction serializeRichTextInlineNodes(nodes: readonly JSONContent[]): string {\n return nodes\n .map((node) => {\n if (node.type === \"text\") {\n return typeof node.text === \"string\" ? node.text : \"\";\n }\n if (node.type === \"hardBreak\") {\n return \"\\n\";\n }\n if (node.type === workspaceReferenceNodeName) {\n const attrs = node.attrs ?? {};\n return createRichTextLinkMarkdown({\n kind: attrs.kind === \"folder\" ? \"folder\" : \"file\",\n name: typeof attrs.label === \"string\" ? attrs.label : \"\",\n path: typeof attrs.path === \"string\" ? attrs.path : \"\"\n });\n }\n if (node.type === mentionReferenceNodeName) {\n const attrs = node.attrs ?? {};\n const label = typeof attrs.label === \"string\" ? attrs.label.trim() : \"\";\n const providerId =\n typeof attrs.providerId === \"string\" ? attrs.providerId.trim() : \"\";\n const entityId =\n typeof attrs.entityId === \"string\" ? attrs.entityId.trim() : \"\";\n if (!label || !providerId || !entityId) {\n return \"\";\n }\n const scope =\n attrs.scope && typeof attrs.scope === \"object\"\n ? (attrs.scope as Record<string, string>)\n : undefined;\n return createRichTextMentionMarkdown({\n entityId,\n label,\n providerId,\n scope\n });\n }\n\n if (Array.isArray(node.content)) {\n return serializeRichTextInlineNodes(node.content);\n }\n\n return \"\";\n })\n .join(\"\");\n}\n"],"mappings":"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","names":[]}