Remark plugin that transforms inline `@marker:id` mention tokens in markdown text nodes into synthetic `link` mdast nodes using the `mention://` scheme, enabling downstream rendering as interactive chip components. ## Key Components ### `MENTION_REGEX` Compiled regex matching `@:` tokens with boundary detection. Captures an optional leading boundary character (`lead`), the marker (lowercase letters), and the id (alphanumeric plus `_.+/=-`, but not trailing `.` or `-`). ### `remarkMentionChips` A [unified](https://github.com/unifiedjs/unified) `Plugin<[], Root>` that visits every `text` leaf in the mdast tree. For each match it: 1. Emits any preceding text as a `Text` node 2. Replaces the token with a `Link` node (`url: mention://:`, children: raw token as fallback text) 3. Returns `[SKIP, index + parts.length]` to advance past the injected nodes without re-visiting them ## Usage Example ```typescript import { unified } from 'unified' import remarkParse from 'remark-parse' import remarkRehype from 'remark-rehype' import { remarkMentionChips } from './remark-mention-chips' const processor = unified() .use(remarkParse) .use(remarkMentionChips) .use(remarkRehype) // Input markdown: "Check @device:64f0a1 and @kb:5 for details." // Produces a link node: { type: 'link', url: 'mention://device:64f0a1', ... } // The downstream override detects the mention:// scheme and renders a chip. const file = await processor.process('Check @device:64f0a1 and @kb:5 for details.') ``` ## Notes - Handles boundary safety: `user@host:1234` is **not** matched because `@` is preceded by a word character - Parenthesised mentions like `(@device:64f0a1)` work correctly — the `(` is re-emitted as text - Unresolved mentions (no matching `contextItems` entry) fall back to the raw `@marker:id` literal - Companion to `remark-card-links`, which handles assistant-side `[card://type:id]` markers **Source:** [`remark-mention-chips.ts`](https://github.com/flamingo-stack/openframe-oss-lib/blob/main/remark-mention-chips.ts)