@djangocfg/ui-tools 2.1.380 → 2.1.382
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 +132 -899
- package/dist/ChatRoot-6IZFM5HM.mjs +5 -0
- package/dist/{ChatRoot-EJC5Y2YM.cjs.map → ChatRoot-6IZFM5HM.mjs.map} +1 -1
- package/dist/ChatRoot-LW4XNIKP.cjs +14 -0
- package/dist/{ChatRoot-QOSKJPM6.mjs.map → ChatRoot-LW4XNIKP.cjs.map} +1 -1
- package/dist/DictationField-2ZLQWLYV.mjs +4 -0
- package/dist/DictationField-2ZLQWLYV.mjs.map +1 -0
- package/dist/DictationField-IPPJ54CU.cjs +13 -0
- package/dist/DictationField-IPPJ54CU.cjs.map +1 -0
- package/dist/{DocsLayout-2YKPXZYO.mjs → DocsLayout-2P3ONDWJ.mjs} +3 -3
- package/dist/{DocsLayout-2YKPXZYO.mjs.map → DocsLayout-2P3ONDWJ.mjs.map} +1 -1
- package/dist/{DocsLayout-Q4KS3QWW.cjs → DocsLayout-2YZNS5VK.cjs} +8 -8
- package/dist/{DocsLayout-Q4KS3QWW.cjs.map → DocsLayout-2YZNS5VK.cjs.map} +1 -1
- package/dist/chunk-4LXG3NBV.mjs +833 -0
- package/dist/chunk-4LXG3NBV.mjs.map +1 -0
- package/dist/{chunk-XACCHZH2.cjs → chunk-FIRK5CEH.cjs} +42 -4
- package/dist/chunk-FIRK5CEH.cjs.map +1 -0
- package/dist/{chunk-NWUT327A.mjs → chunk-HIK6BPL7.mjs} +38 -5
- package/dist/chunk-HIK6BPL7.mjs.map +1 -0
- package/dist/chunk-KMSBGNVC.cjs +835 -0
- package/dist/chunk-KMSBGNVC.cjs.map +1 -0
- package/dist/chunk-OZAU3QWD.cjs +2493 -0
- package/dist/chunk-OZAU3QWD.cjs.map +1 -0
- package/dist/chunk-UWVP6LCW.mjs +2447 -0
- package/dist/chunk-UWVP6LCW.mjs.map +1 -0
- package/dist/index.cjs +1532 -100
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1148 -107
- package/dist/index.d.ts +1148 -107
- package/dist/index.mjs +1421 -51
- package/dist/index.mjs.map +1 -1
- package/package.json +16 -8
- package/src/audio-assets.d.ts +8 -0
- package/src/components/markdown/MarkdownMessage/CollapseToggle.tsx +3 -1
- package/src/components/markdown/MarkdownMessage/components.tsx +2 -5
- package/src/stories/index.ts +32 -2
- package/src/tools/Chat/README.md +347 -530
- package/src/tools/Chat/components/Attachments.tsx +6 -1
- package/src/tools/Chat/components/ChatRoot.tsx +30 -2
- package/src/tools/Chat/components/Composer.tsx +20 -3
- package/src/tools/Chat/components/ErrorBanner.tsx +7 -3
- package/src/tools/Chat/components/MessageActions.tsx +3 -1
- package/src/tools/Chat/components/MessageBubble.tsx +6 -5
- package/src/tools/Chat/components/MessageList.tsx +87 -1
- package/src/tools/Chat/components/ToolCalls.tsx +21 -3
- package/src/tools/Chat/context/ChatProvider.tsx +21 -3
- package/src/tools/Chat/core/audio/audioBus.ts +10 -163
- package/src/tools/Chat/core/audio/defaults.ts +43 -0
- package/src/tools/Chat/core/audio/index.ts +1 -0
- package/src/tools/Chat/core/audio/preferences.ts +5 -59
- package/src/tools/Chat/core/audio/sounds/error.mp3 +0 -0
- package/src/tools/Chat/core/audio/sounds/mention.mp3 +0 -0
- package/src/tools/Chat/core/audio/sounds/notification.mp3 +0 -0
- package/src/tools/Chat/core/audio/sounds/received.mp3 +0 -0
- package/src/tools/Chat/core/audio/sounds/sent.mp3 +0 -0
- package/src/tools/Chat/core/audio/sounds/start.mp3 +0 -0
- package/src/tools/Chat/core/audio/types.ts +28 -0
- package/src/tools/Chat/core/reducer.ts +33 -0
- package/src/tools/Chat/core/transport/index.ts +13 -0
- package/src/tools/Chat/core/transport/mappers/index.ts +6 -0
- package/src/tools/Chat/core/transport/mappers/pydantic-ai.ts +142 -0
- package/src/tools/Chat/core/transport/pydantic-ai-transport.ts +208 -0
- package/src/tools/Chat/core/transport/sse.ts +18 -5
- package/src/tools/Chat/hooks/index.ts +25 -0
- package/src/tools/Chat/hooks/useAutoFocusOnStreamEnd.ts +5 -3
- package/src/tools/Chat/hooks/useChat.ts +28 -0
- package/src/tools/Chat/hooks/useChatAudio.ts +59 -180
- package/src/tools/Chat/hooks/useChatDockPrefs.ts +74 -0
- package/src/tools/Chat/hooks/useChatReset.ts +70 -0
- package/src/tools/Chat/hooks/useChatUnread.ts +87 -0
- package/src/tools/Chat/hooks/useFocusOnEmptyClick.ts +111 -0
- package/src/tools/Chat/hooks/useVisitorFingerprint.ts +48 -0
- package/src/tools/Chat/index.ts +69 -1
- package/src/tools/Chat/launcher/ChatDock.tsx +263 -0
- package/src/tools/Chat/launcher/ChatFAB.tsx +349 -0
- package/src/tools/Chat/launcher/ChatGreeting.tsx +200 -0
- package/src/tools/Chat/launcher/ChatHeader.tsx +76 -0
- package/src/tools/Chat/launcher/ChatHeaderActionButton.tsx +87 -0
- package/src/tools/Chat/launcher/ChatHeaderAudioToggle.tsx +47 -0
- package/src/tools/Chat/launcher/ChatHeaderLanguageButton.tsx +179 -0
- package/src/tools/Chat/launcher/ChatHeaderModeToggle.tsx +57 -0
- package/src/tools/Chat/launcher/ChatHeaderResetButton.tsx +93 -0
- package/src/tools/Chat/launcher/ChatLauncher.tsx +321 -0
- package/src/tools/Chat/launcher/ChatUnreadPreview.tsx +197 -0
- package/src/tools/Chat/launcher/index.ts +46 -0
- package/src/tools/Chat/launcher/useChatPresence.ts +44 -0
- package/src/tools/Chat/stories/01-basic.story.tsx +64 -0
- package/src/tools/Chat/stories/02-bubbles.story.tsx +21 -0
- package/src/tools/Chat/stories/03-tool-calls.story.tsx +59 -0
- package/src/tools/Chat/stories/04-personas.story.tsx +78 -0
- package/src/tools/Chat/stories/05-launcher.story.tsx +321 -0
- package/src/tools/Chat/stories/06-header.story.tsx +147 -0
- package/src/tools/Chat/stories/07-audio-actions.story.tsx +112 -0
- package/src/tools/Chat/stories/shared/Frame.tsx +21 -0
- package/src/tools/Chat/stories/shared/index.ts +5 -0
- package/src/tools/Chat/stories/shared/messages.ts +39 -0
- package/src/tools/Chat/stories/shared/personas.ts +13 -0
- package/src/tools/Chat/stories/shared/seeds.ts +92 -0
- package/src/tools/Chat/stories/shared/transports.ts +36 -0
- package/src/tools/Chat/styles/bubbleTokens.ts +71 -0
- package/src/tools/Chat/styles/index.ts +16 -0
- package/src/tools/Chat/styles/useChatStyles.ts +101 -0
- package/src/tools/Chat/types/attachment.ts +25 -0
- package/src/tools/Chat/types/config.ts +48 -0
- package/src/tools/Chat/types/events.ts +35 -0
- package/src/tools/Chat/types/index.ts +34 -0
- package/src/tools/Chat/types/labels.ts +38 -0
- package/src/tools/Chat/types/message.ts +32 -0
- package/src/tools/Chat/types/persona.ts +31 -0
- package/src/tools/Chat/types/session.ts +43 -0
- package/src/tools/Chat/types/tool-call.ts +17 -0
- package/src/tools/Chat/types/transport.ts +28 -0
- package/src/tools/Chat/types.ts +5 -240
- package/src/tools/MarkdownEditor/MarkdownEditor.tsx +50 -14
- package/src/tools/MarkdownEditor/index.ts +1 -1
- package/src/tools/SpeechRecognition/README.md +336 -0
- package/src/tools/SpeechRecognition/__tests__/ids.test.ts +15 -0
- package/src/tools/SpeechRecognition/__tests__/language.test.ts +59 -0
- package/src/tools/SpeechRecognition/__tests__/reducer.test.ts +71 -0
- package/src/tools/SpeechRecognition/__tests__/transcript.test.ts +52 -0
- package/src/tools/SpeechRecognition/components/DevicePicker.tsx +49 -0
- package/src/tools/SpeechRecognition/components/DictationButton.tsx +93 -0
- package/src/tools/SpeechRecognition/components/EngineBadge.tsx +30 -0
- package/src/tools/SpeechRecognition/components/ErrorBanner.tsx +52 -0
- package/src/tools/SpeechRecognition/components/LanguagePicker.tsx +63 -0
- package/src/tools/SpeechRecognition/components/MicMeter.tsx +63 -0
- package/src/tools/SpeechRecognition/components/PushToTalkHint.tsx +51 -0
- package/src/tools/SpeechRecognition/components/TranscriptView.tsx +55 -0
- package/src/tools/SpeechRecognition/components/index.ts +16 -0
- package/src/tools/SpeechRecognition/context/SpeechRecognitionProvider.tsx +47 -0
- package/src/tools/SpeechRecognition/context/index.ts +6 -0
- package/src/tools/SpeechRecognition/core/audio/defaults.ts +24 -0
- package/src/tools/SpeechRecognition/core/engine/external.ts +222 -0
- package/src/tools/SpeechRecognition/core/engine/http.ts +147 -0
- package/src/tools/SpeechRecognition/core/engine/index.ts +52 -0
- package/src/tools/SpeechRecognition/core/engine/mediarecorder.ts +105 -0
- package/src/tools/SpeechRecognition/core/engine/websocket.ts +211 -0
- package/src/tools/SpeechRecognition/core/engine/webspeech.ts +188 -0
- package/src/tools/SpeechRecognition/core/ids.ts +11 -0
- package/src/tools/SpeechRecognition/core/index.ts +14 -0
- package/src/tools/SpeechRecognition/core/language.ts +78 -0
- package/src/tools/SpeechRecognition/core/languages-catalog.ts +229 -0
- package/src/tools/SpeechRecognition/core/logger.ts +3 -0
- package/src/tools/SpeechRecognition/core/reducer.ts +105 -0
- package/src/tools/SpeechRecognition/core/transcript.ts +36 -0
- package/src/tools/SpeechRecognition/hooks/index.ts +14 -0
- package/src/tools/SpeechRecognition/hooks/useDictation.ts +59 -0
- package/src/tools/SpeechRecognition/hooks/useEnginePrefs.ts +15 -0
- package/src/tools/SpeechRecognition/hooks/useMicDevices.ts +57 -0
- package/src/tools/SpeechRecognition/hooks/useMicLevel.ts +52 -0
- package/src/tools/SpeechRecognition/hooks/usePushToTalk.ts +85 -0
- package/src/tools/SpeechRecognition/hooks/useResolvedLanguage.ts +28 -0
- package/src/tools/SpeechRecognition/hooks/useSpeechLanguageInfo.ts +108 -0
- package/src/tools/SpeechRecognition/hooks/useSpeechRecognition.ts +188 -0
- package/src/tools/SpeechRecognition/hooks/useVoiceSupport.ts +78 -0
- package/src/tools/SpeechRecognition/index.ts +82 -0
- package/src/tools/SpeechRecognition/lazy.tsx +19 -0
- package/src/tools/SpeechRecognition/store/index.ts +2 -0
- package/src/tools/SpeechRecognition/store/prefsStore.ts +54 -0
- package/src/tools/SpeechRecognition/stories/01-basic.story.tsx +32 -0
- package/src/tools/SpeechRecognition/stories/02-dictation-field.story.tsx +32 -0
- package/src/tools/SpeechRecognition/stories/03-push-to-talk.story.tsx +27 -0
- package/src/tools/SpeechRecognition/stories/04-mic-meter.story.tsx +35 -0
- package/src/tools/SpeechRecognition/stories/05-custom-engine-http.story.tsx +40 -0
- package/src/tools/SpeechRecognition/stories/06-custom-engine-ws.story.tsx +48 -0
- package/src/tools/SpeechRecognition/stories/07-language-device.story.tsx +57 -0
- package/src/tools/SpeechRecognition/stories/08-errors-permissions.story.tsx +25 -0
- package/src/tools/SpeechRecognition/stories/09-chat-voice.story.tsx +90 -0
- package/src/tools/SpeechRecognition/stories/shared.tsx +123 -0
- package/src/tools/SpeechRecognition/types.ts +133 -0
- package/src/tools/SpeechRecognition/widgets/DictationField.tsx +105 -0
- package/src/tools/SpeechRecognition/widgets/VoiceComposerSlot.tsx +305 -0
- package/src/tools/SpeechRecognition/widgets/VoiceMessageRecorder.tsx +88 -0
- package/src/tools/SpeechRecognition/widgets/index.ts +6 -0
- package/dist/ChatRoot-EJC5Y2YM.cjs +0 -14
- package/dist/ChatRoot-QOSKJPM6.mjs +0 -5
- package/dist/chunk-NWUT327A.mjs.map +0 -1
- package/dist/chunk-QLMKCSR6.mjs +0 -2420
- package/dist/chunk-QLMKCSR6.mjs.map +0 -1
- package/dist/chunk-SI5RD2GD.cjs +0 -2460
- package/dist/chunk-SI5RD2GD.cjs.map +0 -1
- package/dist/chunk-XACCHZH2.cjs.map +0 -1
- package/src/tools/Chat/Chat.story.tsx +0 -1457
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tools/SpeechRecognition/components/DictationButton.tsx","../src/tools/SpeechRecognition/components/ErrorBanner.tsx","../src/tools/SpeechRecognition/components/MicMeter.tsx","../src/tools/SpeechRecognition/components/PushToTalkHint.tsx","../src/tools/SpeechRecognition/core/transcript.ts","../src/tools/SpeechRecognition/core/ids.ts","../src/tools/SpeechRecognition/core/logger.ts","../src/tools/SpeechRecognition/core/reducer.ts","../src/tools/SpeechRecognition/core/engine/index.ts","../src/tools/SpeechRecognition/core/engine/webspeech.ts","../src/tools/SpeechRecognition/store/prefsStore.ts","../src/tools/SpeechRecognition/hooks/useMicLevel.ts","../src/tools/SpeechRecognition/core/language.ts","../src/tools/SpeechRecognition/hooks/useResolvedLanguage.ts","../src/tools/SpeechRecognition/hooks/useSpeechRecognition.ts","../src/tools/SpeechRecognition/hooks/useDictation.ts","../src/tools/SpeechRecognition/hooks/usePushToTalk.ts","../src/tools/SpeechRecognition/widgets/DictationField.tsx"],"names":["jsxs","cn","jsx","useState","useRef","useEffect"],"mappings":"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","file":"chunk-4LXG3NBV.mjs","sourcesContent":["'use client';\n\nimport type * as React from 'react';\n\nimport { Loader2, Mic, MicOff } from 'lucide-react';\nimport type { CSSProperties, ReactNode } from 'react';\n\nimport { cn } from '@djangocfg/ui-core/lib';\n\nimport type { RecognitionStatus } from '../types';\n\nexport interface DictationButtonProps {\n status: RecognitionStatus;\n onClick: () => void;\n isSupported?: boolean;\n size?: 'sm' | 'md' | 'lg';\n className?: string;\n style?: CSSProperties;\n ariaLabel?: string;\n /** Override icon for the idle state. */\n idleIcon?: ReactNode;\n /** Override icon for the listening state. */\n listeningIcon?: ReactNode;\n /** Disable without unmounting. */\n disabled?: boolean;\n}\n\nconst SIZE_CLS: Record<NonNullable<DictationButtonProps['size']>, string> = {\n sm: 'h-8 w-8 [&_svg]:h-4 [&_svg]:w-4',\n md: 'h-10 w-10 [&_svg]:h-5 [&_svg]:w-5',\n lg: 'h-12 w-12 [&_svg]:h-6 [&_svg]:w-6',\n};\n\n/**\n * Round microphone button. Cycles icon by status; shows a soft pulse\n * ring when listening. ARIA-correct so screen readers announce\n * \"recording\" vs \"start dictation\".\n */\nexport function DictationButton({\n status,\n onClick,\n isSupported = true,\n size = 'md',\n className,\n style,\n ariaLabel,\n idleIcon,\n listeningIcon,\n disabled,\n}: DictationButtonProps): React.ReactElement {\n const listening = status === 'listening' || status === 'starting';\n const stopping = status === 'stopping';\n const off = !isSupported;\n\n return (\n <button\n type=\"button\"\n onClick={onClick}\n disabled={disabled || off}\n aria-pressed={listening}\n aria-label={\n ariaLabel ?? (listening ? 'Stop dictation' : off ? 'Dictation not supported' : 'Start dictation')\n }\n className={cn(\n 'relative inline-flex items-center justify-center rounded-full transition-colors',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n SIZE_CLS[size],\n listening\n ? 'bg-destructive text-destructive-foreground hover:bg-destructive/90'\n : 'bg-primary text-primary-foreground hover:bg-primary/90',\n className,\n )}\n style={style}\n >\n {listening && (\n <span\n aria-hidden\n className=\"absolute inset-0 rounded-full bg-destructive/40 animate-ping\"\n />\n )}\n {stopping ? (\n <Loader2 className=\"animate-spin\" />\n ) : off ? (\n listeningIcon ?? <MicOff />\n ) : listening ? (\n listeningIcon ?? <Mic />\n ) : (\n idleIcon ?? <Mic />\n )}\n </button>\n );\n}\n","'use client';\n\nimport type * as React from 'react';\n\nimport { AlertTriangle } from 'lucide-react';\n\nimport { cn } from '@djangocfg/ui-core/lib';\n\nimport type { RecognitionError } from '../types';\n\nconst FRIENDLY: Record<RecognitionError['code'], string> = {\n unsupported: 'Speech recognition isn\\'t available in this browser.',\n 'permission-denied': 'Microphone access was denied. Allow it in your browser settings to dictate.',\n 'no-microphone': 'No microphone found.',\n network: 'Network error talking to the speech service.',\n aborted: 'Recognition was interrupted.',\n 'no-speech': 'No speech was detected. Try again.',\n language: 'The requested language isn\\'t supported by the engine.',\n engine: 'The speech engine reported an error.',\n unknown: 'Something went wrong with the microphone.',\n};\n\nexport interface ErrorBannerProps {\n error: RecognitionError | null;\n className?: string;\n onDismiss?: () => void;\n}\n\nexport function ErrorBanner({ error, className, onDismiss }: ErrorBannerProps): React.ReactElement | null {\n if (!error) return null;\n return (\n <div\n role=\"alert\"\n className={cn(\n 'flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/10 px-3 py-2 text-xs text-destructive',\n className,\n )}\n >\n <AlertTriangle className=\"mt-0.5 h-3.5 w-3.5 shrink-0\" />\n <div className=\"flex-1\">{FRIENDLY[error.code] ?? error.message}</div>\n {onDismiss && (\n <button\n type=\"button\"\n onClick={onDismiss}\n className=\"text-destructive hover:underline\"\n >\n Dismiss\n </button>\n )}\n </div>\n );\n}\n","'use client';\n\nimport type * as React from 'react';\n\nimport { cn } from '@djangocfg/ui-core/lib';\n\nexport interface MicMeterProps {\n /** RMS level 0..1 (use the value returned by `useMicLevel`). */\n level: number;\n /** Number of bars rendered. @default 12 */\n bars?: number;\n /** Bar gap in px. @default 2 */\n gap?: number;\n /** Bar width in px. @default 3 */\n barWidth?: number;\n /** Container height in px. @default 24 */\n height?: number;\n className?: string;\n}\n\n/**\n * Discrete-bar VU meter — small, dependency-free, no canvas. Each bar\n * lights up when the current `level` exceeds its threshold. Centre bars\n * are tallest so the meter reads like a classic mic level indicator.\n */\nexport function MicMeter({\n level,\n bars = 12,\n gap = 2,\n barWidth = 3,\n height = 24,\n className,\n}: MicMeterProps): React.ReactElement {\n const clamped = Math.min(1, Math.max(0, level));\n return (\n <div\n role=\"meter\"\n aria-valuemin={0}\n aria-valuemax={1}\n aria-valuenow={clamped}\n className={cn('inline-flex items-center', className)}\n style={{ gap, height }}\n >\n {Array.from({ length: bars }).map((_, i) => {\n const ratio = (i + 1) / bars;\n const active = clamped >= ratio - 0.5 / bars;\n // taller in the middle, shorter at edges\n const heightRatio = 1 - Math.abs(i - (bars - 1) / 2) / ((bars - 1) / 2 || 1);\n const barH = Math.max(2, height * (0.35 + heightRatio * 0.65));\n return (\n <span\n key={i}\n className={cn(\n 'rounded-sm transition-colors',\n active ? 'bg-primary' : 'bg-border',\n )}\n style={{ width: barWidth, height: barH }}\n />\n );\n })}\n </div>\n );\n}\n","'use client';\n\nimport type * as React from 'react';\n\nimport { cn } from '@djangocfg/ui-core/lib';\n\nexport interface PushToTalkHintProps {\n /** Same chord string passed to `usePushToTalk`. */\n chord: string;\n className?: string;\n}\n\n/**\n * Renders \"Hold ⌥ to talk\" with the chord pretty-printed. Tiny helper\n * meant to live next to a `DictationButton`.\n */\nexport function PushToTalkHint({ chord, className }: PushToTalkHintProps): React.ReactElement {\n const formatted = chord\n .split('+')\n .map((p) => p.trim().toLowerCase())\n .map((p) => {\n switch (p) {\n case 'mod':\n case 'meta':\n return '⌘';\n case 'alt':\n return '⌥';\n case 'shift':\n return '⇧';\n case 'ctrl':\n return '⌃';\n default:\n return p.length === 1 ? p.toUpperCase() : p;\n }\n })\n .join('');\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1 text-[11px] text-muted-foreground',\n className,\n )}\n >\n Hold\n <kbd className=\"rounded border border-border bg-muted px-1 py-0.5 font-mono text-[10px] text-foreground\">\n {formatted}\n </kbd>\n to talk\n </span>\n );\n}\n","import type { Segment, Transcript } from '../types';\n\nexport const EMPTY_TRANSCRIPT: Transcript = {\n interim: '',\n final: '',\n segments: [],\n};\n\nexport function joinFinal(segments: Segment[]): string {\n let out = '';\n for (const seg of segments) {\n if (!seg.isFinal) continue;\n const text = seg.text.trim();\n if (!text) continue;\n out = out ? `${out} ${text}` : text;\n }\n return out;\n}\n\nexport function buildTranscript(segments: Segment[]): Transcript {\n const last = segments[segments.length - 1];\n const interim = last && !last.isFinal ? last.text : '';\n return {\n interim,\n final: joinFinal(segments),\n segments,\n };\n}\n\n/**\n * Polite text normalisation between concatenated finals — strips double\n * spaces / leading punctuation that some engines emit when the user pauses.\n */\nexport function normaliseFinal(text: string): string {\n return text.replace(/\\s+/g, ' ').replace(/\\s+([,.!?])/g, '$1').trim();\n}\n","let counter = 0;\n\n/**\n * Cheap monotonic id — collisions are fine across sessions, we just need\n * uniqueness within one component lifecycle. Avoids pulling in nanoid for\n * a tool that already keeps the lazy chunk small.\n */\nexport function newSegmentId(): string {\n counter = (counter + 1) % Number.MAX_SAFE_INTEGER;\n return `seg_${Date.now().toString(36)}_${counter.toString(36)}`;\n}\n","import { consola } from 'consola';\n\nexport const sttLogger = consola.withTag('ui-tools:speech');\n","import { newSegmentId } from './ids';\nimport type {\n RecognitionError,\n RecognitionStatus,\n Segment,\n} from '../types';\n\nexport interface RecognitionState {\n status: RecognitionStatus;\n segments: Segment[];\n error: RecognitionError | null;\n startedAt: number | null;\n}\n\nexport const INITIAL_STATE: RecognitionState = {\n status: 'idle',\n segments: [],\n error: null,\n startedAt: null,\n};\n\nexport type RecognitionAction =\n | { type: 'START' }\n | { type: 'STARTED' }\n | { type: 'STOP' }\n | { type: 'STOPPED' }\n | { type: 'ABORT' }\n | {\n type: 'PARTIAL';\n text: string;\n segmentId: string;\n confidence?: number;\n }\n | {\n type: 'FINAL';\n text: string;\n segmentId: string;\n confidence?: number;\n }\n | { type: 'ERROR'; error: RecognitionError }\n | { type: 'RESET' };\n\nfunction nowSinceStart(state: RecognitionState): number {\n return state.startedAt ? Date.now() - state.startedAt : 0;\n}\n\nfunction upsertSegment(\n segments: Segment[],\n patch: Segment,\n): Segment[] {\n const idx = segments.findIndex((s) => s.id === patch.id);\n if (idx === -1) return [...segments, patch];\n const next = segments.slice();\n next[idx] = { ...next[idx], ...patch };\n return next;\n}\n\nexport function reducer(\n state: RecognitionState,\n action: RecognitionAction,\n): RecognitionState {\n switch (action.type) {\n case 'START':\n return {\n ...state,\n status: 'starting',\n error: null,\n startedAt: Date.now(),\n };\n case 'STARTED':\n return { ...state, status: 'listening' };\n case 'STOP':\n return { ...state, status: 'stopping' };\n case 'STOPPED':\n case 'ABORT':\n return { ...state, status: 'idle' };\n case 'PARTIAL': {\n const seg: Segment = {\n id: action.segmentId,\n text: action.text,\n isFinal: false,\n confidence: action.confidence,\n startedAt: nowSinceStart(state),\n };\n return { ...state, segments: upsertSegment(state.segments, seg) };\n }\n case 'FINAL': {\n const seg: Segment = {\n id: action.segmentId || newSegmentId(),\n text: action.text,\n isFinal: true,\n confidence: action.confidence,\n startedAt: nowSinceStart(state),\n endedAt: nowSinceStart(state),\n };\n return { ...state, segments: upsertSegment(state.segments, seg) };\n }\n case 'ERROR':\n return { ...state, status: 'error', error: action.error };\n case 'RESET':\n return { ...INITIAL_STATE };\n default:\n return state;\n }\n}\n","/**\n * Tiny event-bus helper shared by every engine. Lets engine authors avoid\n * re-implementing add/remove listener bookkeeping while keeping the\n * public `RecognitionEngine.on(...)` contract identical across engines.\n */\n\nimport type { EngineEventMap, Unsub } from '../../types';\n\ntype Listeners = {\n [K in keyof EngineEventMap]: Set<EngineEventMap[K]>;\n};\n\nexport function createEngineBus(): {\n on: <K extends keyof EngineEventMap>(event: K, cb: EngineEventMap[K]) => Unsub;\n emit: <K extends keyof EngineEventMap>(\n event: K,\n ...args: Parameters<EngineEventMap[K]>\n ) => void;\n clear: () => void;\n} {\n const listeners: Listeners = {\n partial: new Set(),\n final: new Set(),\n error: new Set(),\n state: new Set(),\n };\n\n return {\n on(event, cb) {\n const set = listeners[event] as Set<typeof cb>;\n set.add(cb);\n return () => {\n set.delete(cb);\n };\n },\n emit(event, ...args) {\n const set = listeners[event];\n for (const cb of set) {\n try {\n (cb as (...a: unknown[]) => void)(...(args as unknown[]));\n } catch {\n // listener errors are isolated — never break the engine loop\n }\n }\n },\n clear() {\n for (const key of Object.keys(listeners) as Array<keyof Listeners>) {\n listeners[key].clear();\n }\n },\n };\n}\n","/**\n * Default engine — wraps the browser's `SpeechRecognition` API.\n *\n * Lives behind the same `RecognitionEngine` contract every other engine\n * implements. When the browser doesn't expose `SpeechRecognition`\n * (Firefox, some mobile WebViews) `isSupported` is `false` and `start()`\n * throws an `unsupported` error.\n */\n\nimport { newSegmentId } from '../ids';\nimport { sttLogger } from '../logger';\nimport { createEngineBus } from './index';\nimport type {\n EngineStartOptions,\n RecognitionEngine,\n RecognitionError,\n RecognitionErrorCode,\n Unsub,\n} from '../../types';\n\n// Minimal subset of the Web Speech API we actually rely on. Browsers\n// expose either `SpeechRecognition` (Edge / Safari new) or the older\n// `webkitSpeechRecognition` (Chrome). Both share the same shape.\ninterface BrowserSpeechRecognition extends EventTarget {\n lang: string;\n interimResults: boolean;\n continuous: boolean;\n maxAlternatives: number;\n start(): void;\n stop(): void;\n abort(): void;\n onresult: ((e: BrowserSpeechRecognitionEvent) => void) | null;\n onerror: ((e: BrowserSpeechRecognitionError) => void) | null;\n onstart: (() => void) | null;\n onend: (() => void) | null;\n}\n\ninterface BrowserSpeechRecognitionResult {\n isFinal: boolean;\n 0: { transcript: string; confidence: number };\n}\n\ninterface BrowserSpeechRecognitionEvent extends Event {\n resultIndex: number;\n results: ArrayLike<BrowserSpeechRecognitionResult>;\n}\n\ninterface BrowserSpeechRecognitionError extends Event {\n error: string;\n message?: string;\n}\n\ntype Ctor = new () => BrowserSpeechRecognition;\n\nfunction resolveCtor(): Ctor | null {\n if (typeof window === 'undefined') return null;\n const w = window as unknown as {\n SpeechRecognition?: Ctor;\n webkitSpeechRecognition?: Ctor;\n };\n return w.SpeechRecognition ?? w.webkitSpeechRecognition ?? null;\n}\n\nconst ERROR_MAP: Record<string, RecognitionErrorCode> = {\n 'no-speech': 'no-speech',\n aborted: 'aborted',\n 'audio-capture': 'no-microphone',\n network: 'network',\n 'not-allowed': 'permission-denied',\n 'service-not-allowed': 'permission-denied',\n 'bad-grammar': 'engine',\n 'language-not-supported': 'language',\n};\n\nexport interface WebSpeechEngineOptions {\n /** Whether the underlying recognition should be continuous. Default true. */\n continuous?: boolean;\n /** Max alternatives the engine should request. Default 1. */\n maxAlternatives?: number;\n}\n\nexport function createWebSpeechEngine(\n opts: WebSpeechEngineOptions = {},\n): RecognitionEngine {\n const Ctor = resolveCtor();\n const bus = createEngineBus();\n let instance: BrowserSpeechRecognition | null = null;\n let currentSegmentId: string | null = null;\n\n function teardown(): void {\n if (!instance) return;\n instance.onresult = null;\n instance.onerror = null;\n instance.onstart = null;\n instance.onend = null;\n instance = null;\n currentSegmentId = null;\n }\n\n return {\n id: 'webspeech',\n isSupported: Ctor !== null,\n on(event, cb): Unsub {\n return bus.on(event, cb);\n },\n async start(start: EngineStartOptions): Promise<void> {\n if (!Ctor) {\n const err: RecognitionError = {\n code: 'unsupported',\n message: 'Web Speech API is not available in this browser.',\n };\n bus.emit('error', err);\n throw err;\n }\n if (instance) {\n sttLogger.debug('[webspeech] start() called while running — ignoring');\n return;\n }\n\n bus.emit('state', 'connecting');\n\n const rec = new Ctor();\n rec.lang = start.language;\n rec.interimResults = start.interim;\n rec.continuous = opts.continuous ?? true;\n rec.maxAlternatives = opts.maxAlternatives ?? 1;\n\n rec.onstart = () => {\n bus.emit('state', 'listening');\n };\n rec.onend = () => {\n bus.emit('state', 'closed');\n teardown();\n };\n rec.onerror = (e) => {\n const code = ERROR_MAP[e.error] ?? 'engine';\n const err: RecognitionError = {\n code,\n message: e.message || `Web Speech error: ${e.error}`,\n };\n bus.emit('error', err);\n };\n rec.onresult = (e) => {\n for (let i = e.resultIndex; i < e.results.length; i += 1) {\n const res = e.results[i];\n const alt = res[0];\n const text = alt.transcript;\n if (!currentSegmentId) currentSegmentId = newSegmentId();\n if (res.isFinal) {\n bus.emit('final', text, currentSegmentId, alt.confidence);\n currentSegmentId = null;\n } else {\n bus.emit('partial', text, currentSegmentId);\n }\n }\n };\n\n if (start.signal) {\n start.signal.addEventListener('abort', () => {\n rec.abort();\n });\n }\n\n instance = rec;\n try {\n rec.start();\n } catch (cause) {\n const err: RecognitionError = {\n code: 'engine',\n message: 'Failed to start Web Speech recognition.',\n cause,\n };\n bus.emit('error', err);\n teardown();\n throw err;\n }\n },\n async stop(): Promise<void> {\n if (!instance) return;\n bus.emit('state', 'closing');\n instance.stop();\n },\n abort(): void {\n if (!instance) return;\n instance.abort();\n },\n };\n}\n","'use client';\n\nimport { create } from 'zustand';\nimport { persist, createJSONStorage } from 'zustand/middleware';\n\nexport interface SpeechPrefs {\n /**\n * BCP-47 tag the user explicitly picked (via `<LanguagePicker>` or\n * programmatically). `null` means \"no override\" — `useResolvedLanguage`\n * then falls through to the app i18n locale / `navigator.language`.\n * Storing the picker default as `null` is what lets a host's i18n\n * locale take effect when the user never touched the picker.\n */\n language: string | null;\n deviceId: string | null;\n engineId: string | null;\n earcons: boolean;\n}\n\nconst DEFAULTS: SpeechPrefs = {\n language: null,\n deviceId: null,\n engineId: null,\n earcons: false,\n};\n\ninterface PrefsStore extends SpeechPrefs {\n setLanguage: (v: string | null) => void;\n setDeviceId: (v: string | null) => void;\n setEngineId: (v: string | null) => void;\n setEarcons: (v: boolean) => void;\n reset: () => void;\n}\n\nexport const useSpeechPrefs = create<PrefsStore>()(\n persist(\n (set) => ({\n ...DEFAULTS,\n setLanguage: (language) => set({ language }),\n setDeviceId: (deviceId) => set({ deviceId }),\n setEngineId: (engineId) => set({ engineId }),\n setEarcons: (earcons) => set({ earcons }),\n reset: () => set({ ...DEFAULTS }),\n }),\n {\n name: 'djangocfg-stt:prefs',\n storage: createJSONStorage(() =>\n typeof window === 'undefined'\n ? (undefined as unknown as Storage)\n : window.localStorage,\n ),\n },\n ),\n);\n","'use client';\n\nimport { useEffect, useRef, useState } from 'react';\n\n/**\n * RMS level meter driven by an `AnalyserNode`. Attach a `MediaStream`\n * (the one returned from `startMicCapture`) and read `level` (0..1) for\n * VU meters / mic-pulse animations. Returns 0 when no stream is bound.\n */\nexport function useMicLevel(stream: MediaStream | null): number {\n const [level, setLevel] = useState(0);\n const raf = useRef<number | null>(null);\n\n useEffect(() => {\n if (!stream) {\n setLevel(0);\n return undefined;\n }\n const AC =\n (window as unknown as { AudioContext?: typeof AudioContext }).AudioContext ??\n (window as unknown as { webkitAudioContext?: typeof AudioContext }).webkitAudioContext;\n if (!AC) return undefined;\n const ctx = new AC();\n const source = ctx.createMediaStreamSource(stream);\n const analyser = ctx.createAnalyser();\n analyser.fftSize = 1024;\n analyser.smoothingTimeConstant = 0.7;\n source.connect(analyser);\n const buf = new Float32Array(analyser.fftSize);\n\n const tick = (): void => {\n analyser.getFloatTimeDomainData(buf);\n let sum = 0;\n for (let i = 0; i < buf.length; i += 1) sum += buf[i] * buf[i];\n const rms = Math.sqrt(sum / buf.length);\n // soft compression so loud peaks don't dominate the meter\n setLevel(Math.min(1, rms * 2.5));\n raf.current = requestAnimationFrame(tick);\n };\n tick();\n\n return () => {\n if (raf.current != null) cancelAnimationFrame(raf.current);\n raf.current = null;\n source.disconnect();\n analyser.disconnect();\n void ctx.close();\n };\n }, [stream]);\n\n return level;\n}\n","/**\n * Maps 2-letter ISO 639-1 codes (`en`, `ru`, `ko` — what\n * `@djangocfg/i18n` exposes via `useLocale()`) to BCP-47 tags\n * (`en-US`, `ru-RU`, `ko-KR`) that the Web Speech API and most cloud\n * STT services expect.\n *\n * We keep a small built-in table for the locales we ship translations\n * for; everything else falls through to `<code>-<UPPER(code)>`, which\n * works for the majority of regions. The mapping is also re-exported\n * so consumers can extend it.\n */\n\nconst ISO_TO_BCP47: Record<string, string> = {\n en: 'en-US',\n ru: 'ru-RU',\n ko: 'ko-KR',\n ja: 'ja-JP',\n zh: 'zh-CN',\n de: 'de-DE',\n fr: 'fr-FR',\n it: 'it-IT',\n es: 'es-ES',\n nl: 'nl-NL',\n ar: 'ar-SA',\n tr: 'tr-TR',\n pl: 'pl-PL',\n sv: 'sv-SE',\n no: 'nb-NO',\n da: 'da-DK',\n pt: 'pt-BR',\n};\n\nexport const DEFAULT_ISO_TO_BCP47 = ISO_TO_BCP47;\n\n/**\n * Normalise any of:\n * - BCP-47 (\"en-US\", \"ru-RU\") — passed through.\n * - ISO 639-1 (\"en\", \"ru\") — mapped via the table above, or\n * falls back to `<code>-<UPPER(code)>`.\n * - `null`/`undefined`/empty — returns `undefined`.\n */\nexport function toBCP47(\n code: string | null | undefined,\n table: Record<string, string> = ISO_TO_BCP47,\n): string | undefined {\n if (!code) return undefined;\n const trimmed = code.trim();\n if (!trimmed) return undefined;\n if (trimmed.includes('-')) return trimmed; // already BCP-47\n const lower = trimmed.toLowerCase();\n return table[lower] ?? `${lower}-${lower.toUpperCase()}`;\n}\n\n/**\n * Resolve the language tag for a speech session in priority order:\n * 1. `explicit` prop (always wins) — host-supplied override.\n * 2. `prefs` — value stored in `useSpeechPrefs` (user picked it\n * via `<LanguagePicker>` or programmatically).\n * 3. `i18n` — current i18n locale (2-letter ISO).\n * 4. `navigator.language` — browser default.\n * 5. `'en-US'` — last-resort safety net.\n *\n * All inputs may be ISO-2 or BCP-47; the function normalises before\n * returning.\n */\nexport function resolveSpeechLanguage(opts: {\n explicit?: string;\n prefs?: string | null;\n i18n?: string | null;\n}): string {\n return (\n toBCP47(opts.explicit) ??\n toBCP47(opts.prefs) ??\n toBCP47(opts.i18n) ??\n toBCP47(typeof navigator !== 'undefined' ? navigator.language : null) ??\n 'en-US'\n );\n}\n","'use client';\n\nimport { useLocaleOptional } from '@djangocfg/i18n';\n\nimport { resolveSpeechLanguage } from '../core/language';\nimport { useSpeechPrefs } from '../store/prefsStore';\n\n/**\n * Resolves the BCP-47 language tag a speech session should use.\n *\n * Priority: explicit prop → user-picked `useSpeechPrefs.language` →\n * app i18n locale (when an `<I18nProvider>` is mounted) →\n * `navigator.language` → `en-US`.\n *\n * Uses `useLocaleOptional` (not `useLocale`) so that an unmounted\n * provider doesn't silently inject `'en'`. Without that, the i18n\n * default would shadow the user's real browser language — a Russian\n * speaker would always get `en-US` recognition.\n */\nexport function useResolvedLanguage(explicit?: string): string {\n const prefs = useSpeechPrefs();\n const locale = useLocaleOptional();\n return resolveSpeechLanguage({\n explicit,\n prefs: prefs.language,\n i18n: locale,\n });\n}\n","'use client';\n\nimport { useCallback, useEffect, useMemo, useReducer, useRef, useState } from 'react';\n\nimport {\n EMPTY_TRANSCRIPT,\n INITIAL_STATE,\n buildTranscript,\n reducer,\n sttLogger,\n} from '../core';\nimport { createWebSpeechEngine } from '../core/engine/webspeech';\nimport { useSpeechPrefs } from '../store/prefsStore';\nimport type {\n RecognitionEngine,\n Segment,\n UseSpeechRecognitionConfig,\n UseSpeechRecognitionReturn,\n} from '../types';\nimport { useMicLevel } from './useMicLevel';\nimport { useResolvedLanguage } from './useResolvedLanguage';\n\n/**\n * Main entry point. With no config it uses the browser Web Speech API\n * and the persisted language from `useSpeechPrefs`. Pass a custom\n * `engine` to route through Deepgram / Whisper / custom WebSocket.\n */\nexport function useSpeechRecognition(\n config: UseSpeechRecognitionConfig = {},\n): UseSpeechRecognitionReturn {\n const prefs = useSpeechPrefs();\n const language = useResolvedLanguage(config.language);\n const engine = useMemo<RecognitionEngine>(\n () => config.engine ?? createWebSpeechEngine(),\n [config.engine],\n );\n\n const [state, dispatch] = useReducer(reducer, INITIAL_STATE);\n const [stream, setStream] = useState<MediaStream | null>(null);\n const level = useMicLevel(stream);\n\n // Latest-callback refs so engine subscriptions never tear down on\n // every render — same trick the Chat reducer uses.\n const cbRef = useRef(config);\n cbRef.current = config;\n\n // Engine subscription lifecycle.\n useEffect(() => {\n const offs = [\n engine.on('partial', (text, segmentId) => {\n dispatch({ type: 'PARTIAL', text, segmentId });\n const seg: Segment = {\n id: segmentId,\n text,\n isFinal: false,\n startedAt: Date.now(),\n };\n cbRef.current.onPartial?.(text, seg);\n }),\n engine.on('final', (text, segmentId, confidence) => {\n dispatch({ type: 'FINAL', text, segmentId, confidence });\n const seg: Segment = {\n id: segmentId,\n text,\n isFinal: true,\n confidence,\n startedAt: Date.now(),\n endedAt: Date.now(),\n };\n cbRef.current.onFinal?.(text, seg);\n }),\n engine.on('error', (err) => {\n dispatch({ type: 'ERROR', error: err });\n cbRef.current.onError?.(err);\n }),\n engine.on('state', (s) => {\n if (s === 'listening') {\n dispatch({ type: 'STARTED' });\n cbRef.current.onStart?.();\n setStream(engine.getStream?.() ?? null);\n } else if (s === 'closed') {\n dispatch({ type: 'STOPPED' });\n cbRef.current.onStop?.();\n setStream(null);\n }\n }),\n ];\n return () => {\n offs.forEach((off) => off());\n };\n }, [engine]);\n\n // AutoStop driven by silence + maxMs caps.\n const silenceTimer = useRef<number | null>(null);\n const maxTimer = useRef<number | null>(null);\n useEffect(() => {\n if (state.status !== 'listening') return undefined;\n const { silenceMs, maxMs, silenceThreshold = 0.02 } = config.autoStop ?? {};\n if (maxMs) {\n maxTimer.current = window.setTimeout(() => {\n sttLogger.debug('[autoStop] max duration hit');\n void engine.stop();\n }, maxMs);\n }\n if (silenceMs) {\n const checkInterval = window.setInterval(() => {\n if (level < silenceThreshold) {\n if (silenceTimer.current == null) {\n silenceTimer.current = window.setTimeout(() => {\n sttLogger.debug('[autoStop] silence detected');\n void engine.stop();\n }, silenceMs);\n }\n } else if (silenceTimer.current != null) {\n clearTimeout(silenceTimer.current);\n silenceTimer.current = null;\n }\n }, 200);\n return () => {\n clearInterval(checkInterval);\n if (silenceTimer.current != null) clearTimeout(silenceTimer.current);\n silenceTimer.current = null;\n if (maxTimer.current != null) clearTimeout(maxTimer.current);\n maxTimer.current = null;\n };\n }\n return () => {\n if (maxTimer.current != null) clearTimeout(maxTimer.current);\n maxTimer.current = null;\n };\n }, [state.status, config.autoStop, level, engine]);\n\n const start = useCallback(async () => {\n if (state.status === 'listening' || state.status === 'starting') return;\n dispatch({ type: 'START' });\n try {\n await engine.start({\n language,\n interim: config.interim ?? true,\n deviceId: config.deviceId ?? prefs.deviceId ?? undefined,\n });\n } catch (cause) {\n // engine already emitted 'error'; reducer caught it via subscription\n sttLogger.debug('[start] engine threw', cause);\n }\n }, [engine, language, config.interim, config.deviceId, prefs.deviceId, state.status]);\n\n const stop = useCallback(async () => {\n if (state.status === 'idle' || state.status === 'stopping') return;\n dispatch({ type: 'STOP' });\n await engine.stop();\n }, [engine, state.status]);\n\n const abort = useCallback(() => {\n engine.abort();\n dispatch({ type: 'ABORT' });\n }, [engine]);\n\n const toggle = useCallback(async () => {\n if (state.status === 'listening' || state.status === 'starting') {\n await stop();\n } else {\n await start();\n }\n }, [state.status, start, stop]);\n\n const reset = useCallback(() => {\n dispatch({ type: 'RESET' });\n }, []);\n\n const transcript = useMemo(\n () => (state.segments.length === 0 ? EMPTY_TRANSCRIPT : buildTranscript(state.segments)),\n [state.segments],\n );\n\n return {\n status: state.status,\n isSupported: engine.isSupported,\n transcript,\n error: state.error,\n level,\n start,\n stop,\n abort,\n toggle,\n reset,\n };\n}\n","'use client';\n\nimport { useEffect, useRef } from 'react';\n\nimport { normaliseFinal } from '../core/transcript';\nimport type { UseSpeechRecognitionConfig, UseSpeechRecognitionReturn } from '../types';\nimport { useSpeechRecognition } from './useSpeechRecognition';\n\nexport interface UseDictationConfig\n extends Omit<UseSpeechRecognitionConfig, 'onFinal'> {\n /** Controlled value the dictation is appending to. */\n value: string;\n /** Called with the next value after each final segment lands. */\n onChange: (next: string) => void;\n /** Joiner between the previous value and the new segment. Default ' '. */\n separator?: string;\n}\n\nexport interface UseDictationReturn extends UseSpeechRecognitionReturn {\n /** Convenience — same as `toggle`, named for dictation UIs. */\n toggleDictation: () => Promise<void>;\n}\n\n/**\n * Convenience adapter that pipes final transcript segments straight into\n * a controlled string (`<textarea>` / `<input>` / TipTap). Interim text\n * is left alone — bind `transcript.interim` separately if you want to\n * show a live ghost.\n */\nexport function useDictation(config: UseDictationConfig): UseDictationReturn {\n const { value, onChange, separator = ' ', ...rest } = config;\n\n // Stash latest value in a ref so the onFinal closure always sees the\n // freshest text without forcing the underlying hook to resubscribe.\n const valueRef = useRef(value);\n valueRef.current = value;\n const onChangeRef = useRef(onChange);\n onChangeRef.current = onChange;\n\n const rec = useSpeechRecognition({\n ...rest,\n onFinal: (text) => {\n const clean = normaliseFinal(text);\n if (!clean) return;\n const prev = valueRef.current;\n const next = prev ? `${prev}${separator}${clean}` : clean;\n onChangeRef.current(next);\n },\n });\n\n useEffect(() => {\n valueRef.current = value;\n }, [value]);\n\n return {\n ...rec,\n toggleDictation: rec.toggle,\n };\n}\n","'use client';\n\nimport { useEffect } from 'react';\n\nimport type { UseSpeechRecognitionReturn } from '../types';\n\nexport interface UsePushToTalkOptions {\n /** Key to hold. Combine modifiers with `+`, e.g. `'alt'`, `'mod+alt'`. */\n key: string;\n /** Disable the binding without unmounting. */\n enabled?: boolean;\n}\n\nconst MOD_KEYS = new Set(['shift', 'ctrl', 'alt', 'meta', 'mod']);\n\nfunction parseChord(chord: string): { mods: Set<string>; main: string | null } {\n const parts = chord\n .toLowerCase()\n .split('+')\n .map((s) => s.trim());\n const mods = new Set<string>();\n let main: string | null = null;\n for (const part of parts) {\n if (MOD_KEYS.has(part)) {\n mods.add(part === 'mod' ? 'meta' : part);\n } else {\n main = part;\n }\n }\n return { mods, main };\n}\n\nfunction matches(e: KeyboardEvent, mods: Set<string>, main: string | null): boolean {\n if (mods.has('shift') !== e.shiftKey) return false;\n if (mods.has('ctrl') !== e.ctrlKey) return false;\n if (mods.has('alt') !== e.altKey) return false;\n // 'mod' → meta on mac / ctrl elsewhere; we already normalised to 'meta'.\n if (mods.has('meta') !== (e.metaKey || (!e.metaKey && false))) return false;\n if (main && e.key.toLowerCase() !== main) return false;\n return true;\n}\n\n/**\n * Hold-to-talk wiring. Press → `start()`, release → `stop()`. Ignores\n * repeats and skips keydown inside `<input>` / `<textarea>` unless a\n * modifier is in the chord.\n */\nexport function usePushToTalk(\n recognition: Pick<UseSpeechRecognitionReturn, 'start' | 'stop' | 'status'>,\n opts: UsePushToTalkOptions,\n): void {\n const { key, enabled = true } = opts;\n\n useEffect(() => {\n if (!enabled || typeof window === 'undefined') return undefined;\n const { mods, main } = parseChord(key);\n\n const onDown = (e: KeyboardEvent): void => {\n if (e.repeat) return;\n if (!main && mods.size === 0) return;\n const target = e.target as HTMLElement | null;\n const inField =\n target?.tagName === 'INPUT' ||\n target?.tagName === 'TEXTAREA' ||\n target?.isContentEditable;\n if (inField && mods.size === 0) return;\n if (!matches(e, mods, main)) return;\n if (recognition.status === 'listening' || recognition.status === 'starting') return;\n e.preventDefault();\n void recognition.start();\n };\n const onUp = (e: KeyboardEvent): void => {\n if (!matches(e, mods, main) && main && e.key.toLowerCase() !== main) return;\n if (recognition.status !== 'listening' && recognition.status !== 'starting') return;\n void recognition.stop();\n };\n\n window.addEventListener('keydown', onDown);\n window.addEventListener('keyup', onUp);\n return () => {\n window.removeEventListener('keydown', onDown);\n window.removeEventListener('keyup', onUp);\n };\n }, [enabled, key, recognition]);\n}\n","'use client';\n\nimport type * as React from 'react';\n\nimport { cn } from '@djangocfg/ui-core/lib';\n\nimport { DictationButton } from '../components/DictationButton';\nimport { ErrorBanner } from '../components/ErrorBanner';\nimport { MicMeter } from '../components/MicMeter';\nimport { PushToTalkHint } from '../components/PushToTalkHint';\nimport { useDictation } from '../hooks/useDictation';\nimport { usePushToTalk } from '../hooks/usePushToTalk';\nimport type { RecognitionEngine } from '../types';\n\nexport interface DictationFieldProps {\n value: string;\n onChange: (next: string) => void;\n /** Custom engine. Defaults to Web Speech via `useSpeechRecognition`. */\n engine?: RecognitionEngine;\n /** Override the language stored in `useSpeechPrefs`. */\n language?: string;\n /** Push-to-talk chord (e.g. `'alt'`, `'mod+alt'`). Disabled when omitted. */\n pushToTalk?: { key: string; enabled?: boolean };\n placeholder?: string;\n rows?: number;\n disabled?: boolean;\n /** Show the interim transcript as a ghost overlay below the textarea. */\n showInterim?: boolean;\n /** Show a small RMS meter inside the toolbar. */\n showMeter?: boolean;\n className?: string;\n textareaClassName?: string;\n}\n\n/**\n * Opinionated textarea + dictation button assembly. Final segments are\n * appended to the controlled `value` automatically. Press-and-hold\n * shortcut is optional; the mic button itself works as a toggle.\n */\nexport function DictationField({\n value,\n onChange,\n engine,\n language,\n pushToTalk,\n placeholder = 'Type or press the mic to dictate…',\n rows = 3,\n disabled,\n showInterim = true,\n showMeter = true,\n className,\n textareaClassName,\n}: DictationFieldProps): React.ReactElement {\n const rec = useDictation({\n value,\n onChange,\n engine,\n language,\n });\n\n usePushToTalk(rec, {\n key: pushToTalk?.key ?? 'alt',\n enabled: !!pushToTalk && pushToTalk.enabled !== false,\n });\n\n return (\n <div className={cn('flex flex-col gap-2', className)}>\n <div className=\"relative\">\n <textarea\n value={value}\n onChange={(e) => onChange(e.target.value)}\n placeholder={placeholder}\n rows={rows}\n disabled={disabled}\n className={cn(\n 'w-full resize-y rounded-md border border-input bg-background px-3 py-2 text-sm',\n 'placeholder:text-muted-foreground',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n textareaClassName,\n )}\n />\n {showInterim && rec.transcript.interim && (\n <div className=\"pointer-events-none mt-1 text-xs italic text-muted-foreground\">\n … {rec.transcript.interim}\n </div>\n )}\n </div>\n\n <div className=\"flex items-center gap-2\">\n <DictationButton\n status={rec.status}\n isSupported={rec.isSupported}\n onClick={() => void rec.toggleDictation()}\n size=\"sm\"\n disabled={disabled}\n />\n {showMeter && <MicMeter level={rec.level} bars={10} height={20} />}\n {pushToTalk && <PushToTalkHint chord={pushToTalk.key} className=\"ml-auto\" />}\n </div>\n\n <ErrorBanner error={rec.error} />\n </div>\n );\n}\n"]}
|
|
@@ -210,6 +210,39 @@ var Mermaid = /* @__PURE__ */ chunkOLISEQHS_cjs.__name((props) => {
|
|
|
210
210
|
return /* @__PURE__ */ jsxRuntime.jsx(React8.Suspense, { fallback: /* @__PURE__ */ jsxRuntime.jsx(LoadingFallback, {}), children: /* @__PURE__ */ jsxRuntime.jsx(MermaidClient, { ...props }) });
|
|
211
211
|
}, "Mermaid");
|
|
212
212
|
var Mermaid_default = Mermaid;
|
|
213
|
+
|
|
214
|
+
// src/tools/Chat/styles/bubbleTokens.ts
|
|
215
|
+
var BUBBLE_SURFACE = {
|
|
216
|
+
/** User-authored bubble — solid brand color. */
|
|
217
|
+
user: "bg-primary text-primary-foreground rounded-tr-md",
|
|
218
|
+
/** Assistant bubble in normal state — neutral muted surface. */
|
|
219
|
+
assistant: "bg-muted text-foreground rounded-tl-md",
|
|
220
|
+
/** Assistant bubble when the turn failed — destructive tint. */
|
|
221
|
+
error: "bg-destructive/10 text-destructive rounded-tl-md border border-destructive/30"
|
|
222
|
+
};
|
|
223
|
+
var ANCHOR = {
|
|
224
|
+
user: "text-primary-foreground underline decoration-primary-foreground/60 underline-offset-2 hover:decoration-primary-foreground transition-colors break-all",
|
|
225
|
+
assistant: "text-primary underline hover:text-primary/80 transition-colors break-all"
|
|
226
|
+
};
|
|
227
|
+
var TOGGLE = {
|
|
228
|
+
user: "text-primary-foreground/80 hover:text-primary-foreground",
|
|
229
|
+
assistant: "text-primary hover:text-primary/80"
|
|
230
|
+
};
|
|
231
|
+
var DESTRUCTIVE_SURFACE = {
|
|
232
|
+
/** Banner / card variant: border + tint + text. */
|
|
233
|
+
banner: "border border-destructive/40 bg-destructive/10 text-destructive",
|
|
234
|
+
/** Subtle hover for destructive buttons inside the banner / menu. */
|
|
235
|
+
hover: "hover:bg-destructive/15",
|
|
236
|
+
/** Strong-hover variant (e.g. trash overlay on attachments). */
|
|
237
|
+
hoverStrong: "hover:bg-destructive hover:text-destructive-foreground",
|
|
238
|
+
/** Inline destructive text utility. */
|
|
239
|
+
text: "text-destructive",
|
|
240
|
+
/** Hover style for menu items that delete data. */
|
|
241
|
+
menuItem: "text-destructive focus:text-destructive hover:bg-destructive/15 hover:text-destructive"
|
|
242
|
+
};
|
|
243
|
+
var TOOL_CALL = {
|
|
244
|
+
errorText: "text-destructive"
|
|
245
|
+
};
|
|
213
246
|
var PrettyCodeClient = React8.lazy(() => import('./PrettyCode.client-KOHDVPPN.cjs'));
|
|
214
247
|
var LoadingFallback2 = /* @__PURE__ */ chunkOLISEQHS_cjs.__name(() => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative rounded-sm border border-border overflow-hidden bg-muted dark:bg-zinc-900", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
215
248
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "animate-pulse h-4 w-4 rounded-full bg-muted-foreground/20" }),
|
|
@@ -328,7 +361,7 @@ function createMarkdownComponents(isUser = false, isCompact = false) {
|
|
|
328
361
|
{
|
|
329
362
|
...rest,
|
|
330
363
|
href,
|
|
331
|
-
className: `${textSize} ${isUser ?
|
|
364
|
+
className: `${textSize} ${isUser ? ANCHOR.user : ANCHOR.assistant}`,
|
|
332
365
|
children
|
|
333
366
|
}
|
|
334
367
|
), "a"),
|
|
@@ -424,7 +457,7 @@ function CollapseToggleRaw({
|
|
|
424
457
|
className: `
|
|
425
458
|
${textSize} font-medium cursor-pointer
|
|
426
459
|
transition-colors duration-200
|
|
427
|
-
${isUser ?
|
|
460
|
+
${isUser ? TOGGLE.user : TOGGLE.assistant}
|
|
428
461
|
inline-flex items-center gap-1
|
|
429
462
|
mt-1
|
|
430
463
|
`,
|
|
@@ -718,10 +751,15 @@ function ChatMessageRowRaw({
|
|
|
718
751
|
chunkOLISEQHS_cjs.__name(ChatMessageRowRaw, "ChatMessageRowRaw");
|
|
719
752
|
React8.memo(ChatMessageRowRaw);
|
|
720
753
|
|
|
754
|
+
exports.ANCHOR = ANCHOR;
|
|
755
|
+
exports.BUBBLE_SURFACE = BUBBLE_SURFACE;
|
|
756
|
+
exports.DESTRUCTIVE_SURFACE = DESTRUCTIVE_SURFACE;
|
|
721
757
|
exports.MarkdownMessage = MarkdownMessage;
|
|
722
758
|
exports.Mermaid_default = Mermaid_default;
|
|
723
759
|
exports.PrettyCode_default = PrettyCode_default;
|
|
760
|
+
exports.TOGGLE = TOGGLE;
|
|
761
|
+
exports.TOOL_CALL = TOOL_CALL;
|
|
724
762
|
exports.extractTextFromChildren = extractTextFromChildren;
|
|
725
763
|
exports.useCollapsibleContent = useCollapsibleContent;
|
|
726
|
-
//# sourceMappingURL=chunk-
|
|
727
|
-
//# sourceMappingURL=chunk-
|
|
764
|
+
//# sourceMappingURL=chunk-FIRK5CEH.cjs.map
|
|
765
|
+
//# sourceMappingURL=chunk-FIRK5CEH.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/markdown/useCollapsibleContent.ts","../src/components/markdown/MarkdownMessage/plainText.ts","../src/tools/Mermaid/index.tsx","../src/tools/Chat/styles/bubbleTokens.ts","../src/tools/PrettyCode/index.tsx","../src/components/markdown/MarkdownMessage/sanitize.ts","../src/components/markdown/MarkdownMessage/CodeBlock.tsx","../src/components/markdown/MarkdownMessage/components.tsx","../src/components/markdown/MarkdownMessage/CollapseToggle.tsx","../src/components/markdown/MarkdownMessage/linkRules.ts","../src/components/markdown/MarkdownMessage/MarkdownMessage.tsx","../src/components/markdown/MarkdownMessage/ActionRow.tsx","../src/components/markdown/MarkdownMessage/ChatMessageRow.tsx"],"names":["__name","useState","useMemo","useCallback","React","lazy","jsx","Suspense","LoadingFallback","jsxs","defaultSchema","useResolvedTheme","memo","CopyButton","Fragment","Chevron","ReactMarkdown","remarkGfm","remarkBreaks","remarkSmartypants","remarkEmoji","rehypeRaw","rehypeSanitize","rehypeExternalLinks","useMediaQuery","useRef","useEffect"],"mappings":"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","file":"chunk-FIRK5CEH.cjs","sourcesContent":["'use client';\n\nimport { useCallback, useMemo, useState } from 'react';\n\nexport interface UseCollapsibleContentOptions {\n /**\n * Maximum character length before collapsing\n * If both maxLength and maxLines are set, the stricter limit applies\n */\n maxLength?: number;\n /**\n * Maximum number of lines before collapsing\n * If both maxLength and maxLines are set, the stricter limit applies\n */\n maxLines?: number;\n /**\n * Start in expanded state (default: false - starts collapsed)\n */\n defaultExpanded?: boolean;\n}\n\nexport interface UseCollapsibleContentResult {\n /** Whether content is currently collapsed */\n isCollapsed: boolean;\n /** Toggle between collapsed/expanded state */\n toggleCollapsed: () => void;\n /** Set collapsed state directly */\n setCollapsed: (collapsed: boolean) => void;\n /** Content to display (truncated if collapsed, full if expanded) */\n displayContent: string;\n /** Whether the content exceeds limits and should be collapsible */\n shouldCollapse: boolean;\n /** Original content length */\n originalLength: number;\n /** Original line count */\n originalLineCount: number;\n}\n\n/**\n * Smart truncation that doesn't break words or markdown syntax\n */\nfunction smartTruncate(content: string, maxLength: number): string {\n if (content.length <= maxLength) {\n return content;\n }\n\n // Find a good break point (space, newline) near maxLength\n let breakPoint = maxLength;\n\n // Look backwards for a space or newline\n while (breakPoint > maxLength - 50 && breakPoint > 0) {\n const char = content[breakPoint];\n if (char === ' ' || char === '\\n' || char === '\\t') {\n break;\n }\n breakPoint--;\n }\n\n // If we couldn't find a good break point, just use maxLength\n if (breakPoint <= maxLength - 50) {\n breakPoint = maxLength;\n }\n\n let truncated = content.slice(0, breakPoint).trimEnd();\n\n // Fix unclosed markdown syntax\n truncated = fixUnclosedMarkdown(truncated);\n\n return truncated;\n}\n\n/**\n * Truncate by line count\n */\nfunction truncateByLines(content: string, maxLines: number): string {\n const lines = content.split('\\n');\n\n if (lines.length <= maxLines) {\n return content;\n }\n\n let truncated = lines.slice(0, maxLines).join('\\n').trimEnd();\n\n // Fix unclosed markdown syntax\n truncated = fixUnclosedMarkdown(truncated);\n\n return truncated;\n}\n\n/**\n * Fix unclosed markdown syntax to prevent rendering issues\n */\nfunction fixUnclosedMarkdown(content: string): string {\n let result = content;\n\n // Count occurrences of markdown markers\n const countOccurrences = (str: string, marker: string): number => {\n const escaped = marker.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const matches = str.match(new RegExp(escaped, 'g'));\n return matches ? matches.length : 0;\n };\n\n // Fix unclosed bold (**) - must have even count\n const boldCount = countOccurrences(result, '**');\n if (boldCount % 2 !== 0) {\n result += '**';\n }\n\n // Fix unclosed italic (*) - but not **\n // Remove ** first for counting, then count single *\n const withoutBold = result.replace(/\\*\\*/g, '');\n const italicCount = countOccurrences(withoutBold, '*');\n if (italicCount % 2 !== 0) {\n result += '*';\n }\n\n // Fix unclosed inline code (`)\n const codeCount = countOccurrences(result, '`');\n // Ignore triple backticks for code blocks\n const tripleCount = countOccurrences(result, '```');\n const singleCodeCount = codeCount - (tripleCount * 3);\n if (singleCodeCount % 2 !== 0) {\n result += '`';\n }\n\n // Fix unclosed code blocks (```)\n if (tripleCount % 2 !== 0) {\n result += '\\n```';\n }\n\n // Fix unclosed strikethrough (~~)\n const strikeCount = countOccurrences(result, '~~');\n if (strikeCount % 2 !== 0) {\n result += '~~';\n }\n\n // Fix unclosed underline bold (__)\n const underlineBoldCount = countOccurrences(result, '__');\n if (underlineBoldCount % 2 !== 0) {\n result += '__';\n }\n\n // Fix unclosed underline italic (_) - but not __\n const withoutUnderlineBold = result.replace(/__/g, '');\n const underlineItalicCount = countOccurrences(withoutUnderlineBold, '_');\n if (underlineItalicCount % 2 !== 0) {\n result += '_';\n }\n\n return result;\n}\n\n/**\n * Hook for managing collapsible content with \"Read more...\" functionality\n *\n * @example\n * ```tsx\n * const { isCollapsed, toggleCollapsed, displayContent, shouldCollapse } = useCollapsibleContent(\n * longText,\n * { maxLength: 300, maxLines: 5 }\n * );\n *\n * return (\n * <div>\n * <Markdown content={displayContent} />\n * {shouldCollapse && (\n * <button onClick={toggleCollapsed}>\n * {isCollapsed ? 'Read more...' : 'Show less'}\n * </button>\n * )}\n * </div>\n * );\n * ```\n */\nexport function useCollapsibleContent(\n content: string,\n options: UseCollapsibleContentOptions = {}\n): UseCollapsibleContentResult {\n const { maxLength, maxLines, defaultExpanded = false } = options;\n\n const [isCollapsed, setIsCollapsed] = useState(!defaultExpanded);\n\n const originalLength = content.length;\n const originalLineCount = content.split('\\n').length;\n\n const { shouldCollapse, truncatedContent } = useMemo(() => {\n // If no limits set, don't collapse\n if (maxLength === undefined && maxLines === undefined) {\n return { shouldCollapse: false, truncatedContent: content };\n }\n\n let needsCollapse = false;\n let result = content;\n\n // Check line limit first (usually more restrictive for chat)\n if (maxLines !== undefined && originalLineCount > maxLines) {\n needsCollapse = true;\n result = truncateByLines(result, maxLines);\n }\n\n // Then check character limit\n if (maxLength !== undefined && result.length > maxLength) {\n needsCollapse = true;\n result = smartTruncate(result, maxLength);\n }\n\n return { shouldCollapse: needsCollapse, truncatedContent: result };\n }, [content, maxLength, maxLines, originalLineCount]);\n\n const displayContent = useMemo(() => {\n if (!shouldCollapse || !isCollapsed) {\n return content;\n }\n return truncatedContent;\n }, [content, truncatedContent, shouldCollapse, isCollapsed]);\n\n const toggleCollapsed = useCallback(() => {\n setIsCollapsed((prev) => !prev);\n }, []);\n\n const setCollapsed = useCallback((collapsed: boolean) => {\n setIsCollapsed(collapsed);\n }, []);\n\n return {\n isCollapsed,\n toggleCollapsed,\n setCollapsed,\n displayContent,\n shouldCollapse,\n originalLength,\n originalLineCount,\n };\n}\n\nexport default useCollapsibleContent;\n","import React from 'react';\n\n/** Recursively concatenate the text content of a React.ReactNode tree.\n * Used by the markdown renderers (e.g. `<pre>` extracting code) and\n * by consumers that need a plain-string label out of link children. */\nexport function extractTextFromChildren(children: React.ReactNode): string {\n if (typeof children === 'string') return children;\n if (typeof children === 'number') return String(children);\n if (React.isValidElement(children)) {\n const props = children.props as { children?: React.ReactNode };\n return extractTextFromChildren(props.children);\n }\n if (Array.isArray(children)) {\n return children.map(extractTextFromChildren).join('');\n }\n return '';\n}\n\n/**\n * Auto-detect whether `text` should bypass ReactMarkdown and render as\n * a flat `<div whitespace-pre-wrap>`. Used as the *fallback* when the\n * caller doesn't pass `plainText` explicitly to `MarkdownMessage`.\n *\n * The signal we trust: short, single-paragraph, no markdown markers.\n * Anything longer / multi-paragraph / structurally suggestive falls\n * through to the markdown pipeline — false negatives there are cheap\n * (markdown renders prose correctly), false positives in the prose\n * branch surface as escaped `*` / `#` / etc. so we err markdown-ward.\n *\n * Thresholds were picked from chat-bubble UX research (see ChatGPT,\n * Claude.ai, WhatsApp): roughly \"would a person have written this in\n * one keystroke without thinking about formatting?\". If you find them\n * too tight or too loose, tune here — every consumer goes through\n * `MarkdownMessage` so the change is universal.\n */\nexport function looksLikePlainProse(text: string): boolean {\n const trimmed = text.trim();\n // Empty / whitespace-only — render as plain (cheap path, nothing to parse).\n if (trimmed.length === 0) return true;\n // Long enough that it's likely a structured assistant reply.\n if (trimmed.length > 500) return false;\n // Paragraph break → almost certainly markdown territory.\n if (/\\n\\s*\\n/.test(trimmed)) return false;\n // Many single-line breaks → probably a list or stanza.\n const newlineCount = (trimmed.match(/\\n/g) || []).length;\n if (newlineCount > 4) return false;\n // Any markdown marker → defer to ReactMarkdown.\n if (hasMarkdownSyntax(trimmed)) return false;\n return true;\n}\n\n/** Affordance test: does this string look like markdown? Used to skip\n * the (heavier) ReactMarkdown pipeline when the content is pure\n * prose. NOT a validator — false negatives are fine; false positives\n * cost a render but render correctly. */\nexport function hasMarkdownSyntax(text: string): boolean {\n // Newlines after trim → render as markdown so paragraphs work.\n if (text.trim().includes('\\n')) return true;\n\n // Inline HTML tags (`<br>`, `<b>`, `<code>`, …) — common in OpenAPI\n // descriptions. Without this branch the fast path would escape them\n // and the user sees literal angle brackets.\n if (/<\\/?[a-zA-Z][a-zA-Z0-9-]*(\\s[^>]*)?\\/?>/.test(text)) return true;\n\n const patterns = [\n /^#{1,6}\\s/m, // Headers\n /\\*\\*[^*]+\\*\\*/, // Bold\n /\\*[^*]+\\*/, // Italic\n /__[^_]+__/, // Bold (underscore)\n /_[^_]+_/, // Italic (underscore)\n /\\[.+\\]\\(.+\\)/, // Links\n /!\\[.*\\]\\(.+\\)/, // Images\n /```[\\s\\S]*```/, // Code blocks\n /`[^`]+`/, // Inline code\n /^\\s*[-*+]\\s/m, // Unordered lists\n /^\\s*\\d+\\.\\s/m, // Ordered lists\n /^\\s*>/m, // Blockquotes\n /\\|.+\\|/, // Tables\n /^---+$/m, // Horizontal rules\n /~~[^~]+~~/, // Strikethrough\n ];\n return patterns.some((p) => p.test(text));\n}\n","/**\n * Mermaid Component - Dynamic Import Wrapper\n *\n * Lazy loads the heavy Mermaid library (~800KB) only when needed.\n * This significantly reduces the initial bundle size.\n */\n\n'use client';\n\nimport React, { lazy, Suspense } from 'react';\n\n// Lazy load the client component\nconst MermaidClient = lazy(() => import('./Mermaid.client'));\n\n// Loading fallback component\nconst LoadingFallback = () => (\n <div className=\"flex justify-center items-center min-h-[100px]\">\n <div className=\"animate-spin rounded-full h-6 w-6 border-b-2 border-primary\" />\n </div>\n);\n\nexport interface MermaidProps {\n chart: string;\n className?: string;\n isCompact?: boolean;\n /** Enable click-to-fullscreen functionality (default: true) */\n fullscreen?: boolean;\n /**\n * Enable the FloatingToolbar's \"click to scroll\" lock overlay.\n * Defaults to `false` — Mermaid diagrams don't scroll internally,\n * so the lock overlay just steals page wheel events. See the\n * Mermaid.client implementation for the full rationale.\n */\n scrollIsolation?: boolean;\n}\n\nconst Mermaid: React.FC<MermaidProps> = (props) => {\n return (\n <Suspense fallback={<LoadingFallback />}>\n <MermaidClient {...props} />\n </Suspense>\n );\n};\n\nexport default Mermaid;\n\n// Re-export builders for declarative diagram construction\nexport {\n // Core\n DiagramStore,\n sanitizeLabel,\n toNodeId,\n // Theme hooks\n useThemePalette,\n useStylePresets,\n useBoxColors,\n // FlowDiagram\n FlowDiagram,\n STYLE_PRESETS,\n // SequenceDiagram\n SequenceDiagram,\n // JourneyDiagram\n JourneyDiagram,\n} from './builders';\n\nexport type {\n // Core types\n DiagramStoreOptions,\n FlowDirection,\n NodeShape,\n ParticipantType,\n TaskScore,\n // Theme types\n ThemePalette,\n StyleColors,\n StylePresets,\n BoxColors,\n // FlowDiagram types\n FlowDiagramOptions,\n FlowDiagramBuilder,\n NodeBuilder,\n EdgeBuilder,\n StyleBuilder,\n // SequenceDiagram types\n ParticipantsObject,\n SequenceDiagramOptions,\n SequenceDiagramBuilder,\n // JourneyDiagram types\n JourneyDiagramOptions,\n JourneyDiagramBuilder,\n SectionBuilder,\n} from './builders';\n","/**\n * Chat color tokens — single source of truth.\n *\n * Every role-conditional class for chat surfaces lives here.\n * Components consume via `useChatBubbleStyles` / `useChatRoleStyles`,\n * never via raw Tailwind literals.\n *\n * Why centralize:\n * 1. One file to edit when the design system changes (e.g. light-theme\n * contrast tweaks, palette swap).\n * 2. Eliminates the \"first-token-on-bg-primary-was-text-white\" class\n * of bugs where each call site picks its own foreground.\n * 3. Lets us snapshot-test color decisions later.\n */\n\n/** Bubble surface classes (background + text), keyed by message state. */\nexport const BUBBLE_SURFACE = {\n /** User-authored bubble — solid brand color. */\n user: 'bg-primary text-primary-foreground rounded-tr-md',\n /** Assistant bubble in normal state — neutral muted surface. */\n assistant: 'bg-muted text-foreground rounded-tl-md',\n /** Assistant bubble when the turn failed — destructive tint. */\n error: 'bg-destructive/10 text-destructive rounded-tl-md border border-destructive/30',\n} as const;\n\n/**\n * Anchor (link) classes for markdown content rendered inside a bubble.\n *\n * On `bg-primary` the link MUST stay legible against the cyan/brand fill —\n * `text-primary-foreground` matches the bubble's foreground token, so\n * contrast tracks the design system automatically.\n *\n * On the neutral assistant bubble we keep the brand-primary color so links\n * still pop without competing with the body text.\n */\nexport const ANCHOR = {\n user:\n 'text-primary-foreground underline decoration-primary-foreground/60 underline-offset-2 ' +\n 'hover:decoration-primary-foreground transition-colors break-all',\n assistant: 'text-primary underline hover:text-primary/80 transition-colors break-all',\n} as const;\n\n/** Inline secondary action (e.g. \"Show more / less\"). Same logic as anchors. */\nexport const TOGGLE = {\n user: 'text-primary-foreground/80 hover:text-primary-foreground',\n assistant: 'text-primary hover:text-primary/80',\n} as const;\n\n/** Destructive surface — used by ErrorBanner and the delete action. */\nexport const DESTRUCTIVE_SURFACE = {\n /** Banner / card variant: border + tint + text. */\n banner:\n 'border border-destructive/40 bg-destructive/10 text-destructive',\n /** Subtle hover for destructive buttons inside the banner / menu. */\n hover: 'hover:bg-destructive/15',\n /** Strong-hover variant (e.g. trash overlay on attachments). */\n hoverStrong:\n 'hover:bg-destructive hover:text-destructive-foreground',\n /** Inline destructive text utility. */\n text: 'text-destructive',\n /** Hover style for menu items that delete data. */\n menuItem:\n 'text-destructive focus:text-destructive hover:bg-destructive/15 hover:text-destructive',\n} as const;\n\n/** Tool-call result text. */\nexport const TOOL_CALL = {\n errorText: 'text-destructive',\n} as const;\n\nexport type ChatBubbleSurface = keyof typeof BUBBLE_SURFACE;\n","/**\n * PrettyCode Component - Dynamic Import Wrapper\n *\n * Lazy loads the heavy Prism library (~500KB) only when needed.\n * This significantly reduces the initial bundle size.\n */\n\n'use client';\n\nimport React, { lazy, Suspense } from 'react';\nimport type { Language } from 'prism-react-renderer';\n\n// Lazy load the client component\nconst PrettyCodeClient = lazy(() => import('./PrettyCode.client'));\n\n// Loading fallback component\nconst LoadingFallback = () => (\n <div className=\"relative rounded-sm border border-border overflow-hidden bg-muted dark:bg-zinc-900\">\n <div className=\"p-4\">\n <div className=\"flex items-center gap-2\">\n <div className=\"animate-pulse h-4 w-4 rounded-full bg-muted-foreground/20\"></div>\n <span className=\"text-xs text-muted-foreground\">Loading code...</span>\n </div>\n </div>\n </div>\n);\n\nexport interface PrettyCodeProps {\n data: string | object;\n language: Language;\n className?: string;\n mode?: 'dark' | 'light';\n inline?: boolean;\n customBg?: string;\n isCompact?: boolean;\n /** Block scroll capture until user clicks (default: true) */\n scrollIsolation?: boolean;\n /**\n * Line count above which the block starts scrolling instead of growing.\n * ``undefined`` (default) = no cap, block grows to fit. Set e.g. ``50``\n * to inline short snippets and cap long ones.\n */\n maxLines?: number;\n /**\n * Visual variant:\n * - ``\"card\"`` (default) — full chrome: border, background, hover\n * toolbar (Copy + language tag), optional internal scroll. Suits\n * a standalone code block in documentation prose where the block\n * is its own surface.\n * - ``\"plain\"`` — chrome-less: no border, no background, no toolbar,\n * no internal scroll. Grows to fit its content. Use when\n * embedding inside another scroll container (e.g. the Response\n * panel) — avoids double-scroll surfaces and lets the parent\n * manage copy/language affordances.\n */\n variant?: 'card' | 'plain';\n}\n\nconst PrettyCode: React.FC<PrettyCodeProps> = (props) => {\n return (\n <Suspense fallback={<LoadingFallback />}>\n <PrettyCodeClient {...props} />\n </Suspense>\n );\n};\n\nexport default PrettyCode;\nexport type { Language };\n","import { defaultSchema } from 'rehype-sanitize';\n\n/** Sanitize schema. Typed loosely (`Record<string, unknown>`) so this\n * package's published types don't try to re-export\n * `hast-util-sanitize`'s internal Schema type — that breaks consumers\n * whose TS doesn't have the transitive dependency in scope. */\nexport type SanitizeSchema = Record<string, unknown>;\n\n// Allow-list HTML that OpenAPI descriptions commonly use — we want\n// `<b>`/`<code>`/`<br>` to render, not to appear as literal text.\n// Built on top of rehype-sanitize's default schema so we keep the\n// XSS protection (no `<script>`, no `on*` handlers, no `javascript:`\n// URLs); we just extend the tag allow-list with safe presentational\n// elements that are in wide use in API docs.\nexport const HTML_SCHEMA_BASE: SanitizeSchema = {\n ...defaultSchema,\n tagNames: [\n ...(defaultSchema.tagNames ?? []),\n 'br',\n 'b',\n 'i',\n 'u',\n 's',\n 'sub',\n 'sup',\n 'small',\n 'mark',\n 'kbd',\n 'code',\n 'pre',\n 'details',\n 'summary',\n ],\n};\n\n/** Build a sanitize schema with extra href-URL protocols allowed on\n * `<a>`. Default whitelists `http(s)/mailto/xmpp/irc(s)` — pass extras\n * here (e.g. `'cmdop'`, `'obsidian'`) to opt them in. */\nexport function buildSchema(extraProtocols: readonly string[] | undefined): SanitizeSchema {\n if (!extraProtocols || extraProtocols.length === 0) return HTML_SCHEMA_BASE;\n const baseProtocols =\n (HTML_SCHEMA_BASE as { protocols?: Record<string, string[]> }).protocols\n ?? (defaultSchema as { protocols?: Record<string, string[]> }).protocols\n ?? {};\n const baseHref = baseProtocols.href ?? ['http', 'https', 'mailto', 'xmpp', 'irc', 'ircs'];\n return {\n ...HTML_SCHEMA_BASE,\n protocols: {\n ...baseProtocols,\n href: [...baseHref, ...extraProtocols],\n },\n };\n}\n\n/** Build a `urlTransform` for ReactMarkdown that lets opted-in schemes\n * pass through verbatim. react-markdown's default strips `href` for\n * unrecognised schemes BEFORE sanitize runs — even with our extended\n * sanitize schema, custom schemes would arrive with `href=\"\"`. */\nexport function buildUrlTransform(extraProtocols: readonly string[] | undefined) {\n if (!extraProtocols || extraProtocols.length === 0) return undefined;\n const lower = extraProtocols.map((p) => p.toLowerCase() + ':');\n return (url: string): string => {\n const u = url.trim().toLowerCase();\n for (const p of lower) {\n if (u.startsWith(p)) return url;\n }\n // Fallback: replicate react-markdown's defaults for safe schemes\n // and relative paths. Anything else → empty string so the\n // anchor's href is dropped (XSS guard).\n if (\n /^(https?:|mailto:|tel:|xmpp:|irc:|ircs:|#|\\/|\\.\\/|\\.\\.\\/|\\?)/i.test(u)\n || /^[a-z0-9._~!$&'()*+,;=:@%-]+$/i.test(u)\n ) {\n return url;\n }\n return '';\n };\n}\n","import React, { memo } from 'react';\nimport { CopyButton } from '@djangocfg/ui-core/components';\nimport { useResolvedTheme } from '@djangocfg/ui-core/hooks';\nimport PrettyCode from '../../../tools/PrettyCode';\n\ninterface CodeBlockProps {\n code: string;\n language: string;\n isUser: boolean;\n isCompact?: boolean;\n}\n\n/**\n * Markdown code block. Renders <PrettyCode> directly — its own\n * FloatingToolbar already carries the language tag and Copy action.\n *\n * Earlier versions stacked an extra <CopyButton> here too, which\n * surfaced as two copy buttons on every code fence. The fallback\n * branch below still ships its own button because the plain <pre>\n * has no toolbar of its own.\n *\n * Memoised: re-renders only when `code`, `language`, `isUser` or\n * `isCompact` change. `code` is the main trigger — long code blocks\n * should not re-render when parent chat scrolls.\n */\nfunction CodeBlockRaw({ code, language }: CodeBlockProps) {\n const theme = useResolvedTheme();\n\n // Chat fences are always rendered in PrettyCode's compact mode:\n // 12px font, tighter padding, line-height 1.4. A fenced block in\n // a chat bubble shouldn't outweigh two paragraphs of body text —\n // the standalone PrettyCode story keeps the larger default for\n // docs/diff viewers.\n return (\n <div className=\"my-2\">\n <PrettyCode\n data={code}\n language={language}\n className=\"text-xs\"\n customBg=\"bg-code\"\n mode={theme}\n isCompact\n // Disable click-to-scroll-isolation in chat markdown: code\n // fences here are part of an assistant reply, not a docs\n // viewer. Forcing the user to click into a small block to\n // scroll past it interrupts the reading flow. The standalone\n // PrettyCode use cases (docs, diff viewers, long code panes)\n // keep the default `true`.\n scrollIsolation={false}\n />\n </div>\n );\n}\n\nexport const CodeBlock = memo(CodeBlockRaw);\n\n/** Simple `<pre>` fallback used when CodeBlock throws (lazy module\n * failure, missing PrettyCode peer, etc).\n *\n * Memoised: re-renders only when `code`, `language`, `isUser` or\n * `isCompact` change.\n */\nfunction CodeBlockFallbackRaw({ code, isUser }: CodeBlockProps) {\n // See CodeBlock above for the spirit of this layout — palette\n // pre-computed before render.\n const copyHoverClass = isUser\n ? 'hover:bg-white/20 text-white'\n : 'hover:bg-muted-foreground/20 text-muted-foreground hover:text-foreground';\n const copyButtonClass =\n `absolute top-2 right-2 z-10 opacity-0 group-hover:opacity-100 transition-opacity ` +\n `h-8 w-8 ${copyHoverClass}`;\n\n return (\n <div className=\"relative group my-3\">\n <CopyButton\n value={code}\n variant=\"ghost\"\n className={copyButtonClass}\n title=\"Copy code\"\n />\n <pre className=\"p-3 rounded text-xs font-mono overflow-x-auto bg-code text-code-foreground border border-code-border\">\n <code>{code}</code>\n </pre>\n </div>\n );\n}\n\nexport const CodeBlockFallback = memo(CodeBlockFallbackRaw);\n","import React from 'react';\nimport type { Components } from 'react-markdown';\nimport Mermaid from '../../../tools/Mermaid';\nimport { ANCHOR } from '../../../tools/Chat/styles/bubbleTokens';\nimport { CodeBlock, CodeBlockFallback } from './CodeBlock';\nimport { extractTextFromChildren } from './plainText';\n\n/**\n * Build the chat-tuned markdown component map.\n *\n * Base text size: text-sm (14px) for normal, text-xs (12px) for compact.\n * Heading sizes are scaled down a notch from the prose defaults so\n * inline-in-chat headings don't dominate.\n */\nexport function createMarkdownComponents(\n isUser: boolean = false,\n isCompact: boolean = false,\n): Components {\n const textSize = isCompact ? 'text-xs' : 'text-sm';\n const headingBase = isCompact ? 'text-sm' : 'text-base';\n const headingSm = isCompact ? 'text-xs' : 'text-sm';\n\n return {\n h1: ({ children }) => (\n <h1 className={`${headingBase} font-semibold mb-2 mt-3 first:mt-0`}>{children}</h1>\n ),\n h2: ({ children }) => (\n <h2 className={`${headingSm} font-semibold mb-2 mt-3 first:mt-0`}>{children}</h2>\n ),\n h3: ({ children }) => (\n <h3 className={`${headingSm} font-semibold mb-1 mt-2 first:mt-0`}>{children}</h3>\n ),\n h4: ({ children }) => (\n <h4 className={`${headingSm} font-semibold mb-1 mt-2 first:mt-0`}>{children}</h4>\n ),\n h5: ({ children }) => (\n <h5 className={`${headingSm} font-medium mb-1 mt-2 first:mt-0`}>{children}</h5>\n ),\n h6: ({ children }) => (\n <h6 className={`${headingSm} font-medium mb-1 mt-2 first:mt-0`}>{children}</h6>\n ),\n\n p: ({ children }) => (\n <p className={`${textSize} mb-4 last:mb-0 leading-relaxed break-words`}>{children}</p>\n ),\n\n ul: ({ children }) => (\n <ul className={`list-disc list-inside mb-2 space-y-1 ${textSize}`}>{children}</ul>\n ),\n ol: ({ children }) => (\n <ol className={`list-decimal list-inside mb-2 space-y-1 ${textSize}`}>{children}</ol>\n ),\n li: ({ children }) => <li className=\"break-words\">{children}</li>,\n\n // `target` / `rel` for external links are NOT set here — the\n // rehype-external-links plugin tags them on the rehype side, so\n // every `<a>` that sanitize let through gets the same security\n // treatment regardless of which renderer (default vs linkRules\n // override) emitted it. Doing it twice here would just duplicate\n // attributes; doing it only here would miss the linkRules path.\n a: ({ href, children, ...rest }) => (\n <a\n {...rest}\n href={href}\n className={`${textSize} ${isUser ? ANCHOR.user : ANCHOR.assistant}`}\n >\n {children}\n </a>\n ),\n\n pre: ({ children }) => {\n let codeContent = '';\n let language = 'plaintext';\n\n if (React.isValidElement(children)) {\n const child = children;\n if (\n child.type === 'code'\n || (typeof child.type === 'function' && child.type.name === 'code')\n ) {\n const codeProps = child.props as {\n className?: string;\n children?: React.ReactNode;\n };\n const rawClassName = codeProps.className;\n language = rawClassName?.replace(/language-/, '').trim() || 'plaintext';\n codeContent = extractTextFromChildren(codeProps.children).trim();\n } else {\n codeContent = extractTextFromChildren(children).trim();\n }\n } else {\n codeContent = extractTextFromChildren(children).trim();\n }\n\n if (!codeContent) {\n return (\n <div className=\"my-3 p-3 bg-muted rounded text-sm text-muted-foreground\">\n No content available\n </div>\n );\n }\n\n if (language === 'mermaid') {\n // Inline render fits the bubble width; the Mermaid component\n // owns its own click-to-fullscreen modal which sizes against\n // the viewport, so we don't cap it here. A previous version\n // hardcoded `max-w-[600px]` and that constraint leaked into\n // the fullscreen modal too — diagram rendered at 600px in the\n // middle of an empty viewport.\n return (\n <div className=\"my-3 w-full\">\n <Mermaid chart={codeContent} isCompact={isCompact} />\n </div>\n );\n }\n\n try {\n return <CodeBlock code={codeContent} language={language} isUser={isUser} isCompact={isCompact} />;\n } catch (error) {\n // eslint-disable-next-line no-console\n console.warn('CodeBlock failed, using fallback:', error);\n return <CodeBlockFallback code={codeContent} language={language} isUser={isUser} isCompact={isCompact} />;\n }\n },\n\n code: ({ children, className }) => {\n // Inside <pre>: let pre handle styling.\n if (className?.includes('language-')) {\n return <code className={className}>{children}</code>;\n }\n // Inline `<code>` uses the design system's `--code-inline`\n // token. One semantic chip surface across both themes; on a\n // user bubble we still palette-switch with `text-primary-\n // foreground` because the inline chip blends INTO the bubble\n // — there's no panel boundary like a fence has. We trade a\n // perfect \"code surface\" tone here for legible body inheritance,\n // matching ChatGPT's behaviour in coloured user bubbles.\n const inlineCodeClass = isUser\n ? 'bg-primary-foreground/15 text-primary-foreground'\n : 'bg-code-inline text-code-inline-foreground';\n return (\n <code className={`px-1 py-0.5 rounded font-mono text-[0.875em] ${inlineCodeClass} break-all`}>\n {extractTextFromChildren(children)}\n </code>\n );\n },\n\n // Modern chat convention drops italic on blockquotes — italic +\n // tight bubble = hard to read. Border-left at 2px (4px reads\n // heavy in a 320–480px bubble). On the saturated user bubble we\n // use a primary-foreground tint; on the assistant bubble we use\n // the muted-foreground role for de-emphasis.\n blockquote: ({ children }) => {\n const cls = isUser\n ? 'border-primary-foreground/40 text-primary-foreground/80'\n : 'border-border text-muted-foreground';\n return (\n <blockquote className={`${textSize} border-l-2 pl-3 my-3 break-words ${cls}`}>\n {children}\n </blockquote>\n );\n },\n\n // Tables: outer wrapper handles overflow, inner `<table>`\n // inherits the chat-density text size. Borders / header use\n // semantic tokens — `border-code-border` for the assistant\n // (matches the code-fence panel for visual cohesion when both\n // appear in the same reply); primary-foreground/N for the user\n // bubble so lines read against the saturated `bg-primary`.\n table: ({ children }) => (\n <div className=\"overflow-x-auto my-3\">\n <table className={`min-w-full ${textSize} border-collapse`}>{children}</table>\n </div>\n ),\n thead: ({ children }) => (\n <thead className={isUser ? 'bg-primary-foreground/10' : 'bg-muted/40'}>\n {children}\n </thead>\n ),\n tbody: ({ children }) => <tbody>{children}</tbody>,\n tr: ({ children }) => (\n <tr className={isUser ? 'border-b border-primary-foreground/15' : 'border-b border-border'}>\n {children}\n </tr>\n ),\n th: ({ children }) => {\n const borderCls = isUser ? 'border-primary-foreground/25' : 'border-border';\n return (\n <th className={`px-2 py-1.5 text-left font-semibold border-b ${borderCls} break-words`}>\n {children}\n </th>\n );\n },\n td: ({ children }) => <td className=\"px-2 py-1.5 break-words\">{children}</td>,\n\n // Soft separator. ChatGPT / Slack / Linear strip the visible\n // line, Claude.ai keeps a hairline. We follow Claude — present\n // but quiet. Palette switches by role so the hairline reads on\n // both surfaces.\n hr: () => (\n <hr\n className={`my-4 border-0 h-px ${\n isUser ? 'bg-primary-foreground/20' : 'bg-border'\n }`}\n />\n ),\n\n strong: ({ children }) => <strong className=\"font-semibold\">{children}</strong>,\n em: ({ children }) => <em className=\"italic\">{children}</em>,\n };\n}\n","import React, { memo } from 'react';\n\nimport { TOGGLE } from '../../../tools/Chat/styles/bubbleTokens';\n\ninterface CollapseToggleProps {\n isCollapsed: boolean;\n onClick: () => void;\n readMoreLabel: string;\n showLessLabel: string;\n isUser: boolean;\n isCompact: boolean;\n}\n\n/** \"Read more...\" / \"Show less\" button.\n *\n * Memoised: re-renders only when `isCollapsed`, `onClick`, `readMoreLabel`,\n * `showLessLabel`, `isUser` or `isCompact` change. `onClick` is compared\n * by reference — callers should stabilise it with useCallback.\n */\nfunction CollapseToggleRaw({\n isCollapsed,\n onClick,\n readMoreLabel,\n showLessLabel,\n isUser,\n isCompact,\n}: CollapseToggleProps) {\n const textSize = isCompact ? 'text-xs' : 'text-sm';\n return (\n <button\n type=\"button\"\n onClick={onClick}\n className={`\n ${textSize} font-medium cursor-pointer\n transition-colors duration-200\n ${isUser ? TOGGLE.user : TOGGLE.assistant}\n inline-flex items-center gap-1\n mt-1\n `}\n >\n {isCollapsed ? (\n <>\n {readMoreLabel}\n <Chevron direction=\"down\" />\n </>\n ) : (\n <>\n {showLessLabel}\n <Chevron direction=\"up\" />\n </>\n )}\n </button>\n );\n};\n\nconst Chevron = memo(function Chevron({ direction }: { direction: 'up' | 'down' }) {\n return (\n <svg className=\"w-3 h-3\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n strokeWidth={2}\n d={direction === 'down' ? 'M19 9l-7 7-7-7' : 'M5 15l7-7 7 7'}\n />\n </svg>\n );\n});\n\nexport const CollapseToggle = memo(CollapseToggleRaw);\n","import React from 'react';\nimport type { ComponentProps, ComponentType } from 'react';\nimport type { Components } from 'react-markdown';\nimport type { LinkRule } from './types';\n\n// react-markdown's `Components['a']` is `keyof IntrinsicElements | ComponentType<…>`,\n// so it isn't necessarily a function we can directly call. This is the\n// component-shaped variant — what callers practically pass when they\n// override `a`.\ntype AComponent = ComponentType<ComponentProps<'a'>>;\n\n/** Run every rule's `preprocess` hook in order. Errors in a single\n * rule are logged and skipped — the other rules still run. */\nexport function applyPreprocess(\n source: string,\n rules: readonly LinkRule[] | undefined,\n): string {\n if (!rules || rules.length === 0) return source;\n let s = source;\n for (const rule of rules) {\n if (!rule.preprocess) continue;\n try {\n s = rule.preprocess(s);\n } catch (err) {\n // eslint-disable-next-line no-console\n console.warn(\n `[MarkdownMessage] linkRule \"${rule.name ?? '(anonymous)'}\" preprocess threw; skipping`,\n err,\n );\n }\n }\n return s;\n}\n\n/** Union of `extraHrefProtocols` and any `protocols` declared by rules. */\nexport function collectProtocols(\n extraHrefProtocols: readonly string[] | undefined,\n rules: readonly LinkRule[] | undefined,\n): readonly string[] | undefined {\n const set = new Set<string>();\n if (extraHrefProtocols) for (const p of extraHrefProtocols) set.add(p);\n if (rules) {\n for (const r of rules) {\n if (r.protocols) for (const p of r.protocols) set.add(p);\n }\n }\n return set.size === 0 ? undefined : Array.from(set);\n}\n\n/** Build a custom `a` renderer that dispatches to the first matching\n * rule, falling through to `callerA` (or the built-in chat anchor)\n * for anything no rule claims. */\nexport function buildLinkRulesComponent(\n rules: readonly LinkRule[],\n isUser: boolean,\n callerA: NonNullable<Components['a']> | undefined,\n): NonNullable<Components['a']> {\n const Renderer: AComponent = (props) => {\n const { href, children } = props;\n if (typeof href === 'string') {\n for (const rule of rules) {\n if (rule.match(href)) {\n return React.createElement(\n React.Fragment,\n null,\n rule.render({ href, children, isUser }),\n );\n }\n }\n }\n // Defer to the caller's `a` override if any. We only call it when\n // it's a function/component — string-form intrinsic overrides\n // (`'a' | 'span' | …`) aren't a thing react-markdown supports for\n // tag overrides, but the type still admits the union, so guard.\n if (callerA && typeof callerA === 'function') {\n const Caller = callerA as AComponent;\n return React.createElement(Caller, props);\n }\n // Fall through to the built-in anchor by rendering a plain `<a>`.\n return React.createElement('a', props, children);\n };\n return Renderer as NonNullable<Components['a']>;\n}\n","'use client';\n\nimport React, { memo } from 'react';\nimport ReactMarkdown from 'react-markdown';\nimport rehypeExternalLinks from 'rehype-external-links';\nimport rehypeRaw from 'rehype-raw';\nimport rehypeSanitize from 'rehype-sanitize';\nimport remarkBreaks from 'remark-breaks';\nimport remarkEmoji from 'remark-emoji';\nimport remarkGfm from 'remark-gfm';\nimport remarkSmartypants from 'remark-smartypants';\nimport type { Components } from 'react-markdown';\n\nimport { useCollapsibleContent } from '../useCollapsibleContent';\nimport type { MarkdownMessageProps } from './types';\nimport { buildSchema, buildUrlTransform } from './sanitize';\nimport { looksLikePlainProse } from './plainText';\nimport { createMarkdownComponents } from './components';\nimport { CollapseToggle } from './CollapseToggle';\nimport { applyPreprocess, buildLinkRulesComponent, collectProtocols } from './linkRules';\n\n/**\n * MarkdownMessage — chat-tuned markdown renderer.\n *\n * Features:\n * - GitHub Flavored Markdown (GFM) via remark-gfm\n * - Syntax-highlighted code blocks with Copy button\n * - Mermaid diagram rendering (` ```mermaid ` fence)\n * - Tables, lists, blockquotes scaled for chat density\n * - User vs assistant styling modes (`isUser`)\n * - Plain-text fast path: skips ReactMarkdown when content has no\n * markdown syntax (cheaper render, preserves newlines via CSS)\n * - Optional collapsible \"Read more...\" for long messages\n *\n * Custom URL schemes (chat mentions, deep-links, custom file viewers)\n * are best handled with the declarative `linkRules` prop — see the\n * type definition in `./types.ts` and the storybook for examples.\n *\n * @example\n * ```tsx\n * <MarkdownMessage content=\"# Hello\\n\\nThis is **bold** text.\" />\n *\n * // User message styling\n * <MarkdownMessage content=\"Some content\" isUser />\n *\n * // Custom URL scheme via linkRules\n * <MarkdownMessage\n * content=\"Talk to [Vps-audi](cmdop://machine/abc-123)\"\n * linkRules={[machineMentionRule]}\n * />\n * ```\n *\n * Memoised: re-renders only when props change. `content` is the main\n * trigger — all other props (className, isUser, isCompact, etc.) are\n * compared by value/reference. `onCollapseChange` is compared by\n * reference — callers should stabilise it with useCallback.\n */\nfunction MarkdownMessageRaw({\n content,\n className = '',\n isUser = false,\n isCompact = false,\n plainText,\n customComponents,\n extraHrefProtocols,\n linkRules,\n collapsible = false,\n maxLength,\n maxLines,\n readMoreLabel = 'Read more...',\n showLessLabel = 'Show less',\n defaultExpanded = false,\n onCollapseChange,\n}: MarkdownMessageProps) {\n // Pre-process content through any rules that requested it. Done\n // before trim so a rule can rewrite multi-line shapes too.\n const preprocessed = React.useMemo(\n () => applyPreprocess(content, linkRules),\n [content, linkRules],\n );\n\n // Union of `extraHrefProtocols` and any `protocols` declared by rules.\n const effectiveProtocols = React.useMemo(\n () => collectProtocols(extraHrefProtocols, linkRules),\n [extraHrefProtocols, linkRules],\n );\n\n // Effective custom components: merge linkRules' synthesized `a`\n // renderer with any caller-provided `customComponents`. linkRules\n // wins when both target the same href (rule is the more specific\n // declarative claim by design).\n const effectiveCustomComponents = React.useMemo<Partial<Components> | undefined>(() => {\n if (!linkRules || linkRules.length === 0) return customComponents;\n const callerA = customComponents?.a;\n const aRenderer = buildLinkRulesComponent(linkRules, isUser, callerA);\n return { ...(customComponents ?? {}), a: aRenderer };\n }, [customComponents, linkRules, isUser]);\n\n const trimmedContent = preprocessed.trim();\n\n // Collapsible content logic — defaults kick in only when enabled.\n const collapsibleOptions = React.useMemo(() => {\n if (!collapsible) return {};\n return {\n maxLength: maxLength ?? 1000,\n maxLines: maxLines ?? 10,\n defaultExpanded,\n };\n }, [collapsible, maxLength, maxLines, defaultExpanded]);\n\n const { isCollapsed, toggleCollapsed, displayContent, shouldCollapse } =\n useCollapsibleContent(trimmedContent, collapsible ? collapsibleOptions : {});\n\n React.useEffect(() => {\n if (collapsible && shouldCollapse && onCollapseChange) {\n onCollapseChange(isCollapsed);\n }\n }, [isCollapsed, collapsible, shouldCollapse, onCollapseChange]);\n\n const components = React.useMemo(() => {\n const base = createMarkdownComponents(isUser, isCompact);\n return effectiveCustomComponents ? { ...base, ...effectiveCustomComponents } : base;\n }, [isUser, isCompact, effectiveCustomComponents]);\n\n const schema = React.useMemo(() => buildSchema(effectiveProtocols), [effectiveProtocols]);\n const urlTransform = React.useMemo(\n () => buildUrlTransform(effectiveProtocols),\n [effectiveProtocols],\n );\n\n const textSizeClass = isCompact ? 'text-xs' : 'text-sm';\n const proseClass = isCompact ? 'prose-xs' : 'prose-sm';\n\n // Resolve plain-vs-markdown branch:\n // 1. Caller-passed `plainText` wins outright (explicit beats clever).\n // 2. Caller-supplied non-`a` customComponents force the markdown\n // pipeline — those overrides only matter on real markdown nodes.\n // 3. Otherwise auto-detect via `looksLikePlainProse` (short,\n // single-paragraph, no markdown markers). This is the chat-bubble\n // WhatsApp/Telegram heuristic — \"would the human have written\n // this in one keystroke?\".\n const customComponentsBeyondLinks = React.useMemo(() => {\n if (!customComponents) return false;\n return Object.keys(customComponents).some((k) => k !== 'a');\n }, [customComponents]);\n const isPlainText = plainText !== undefined\n ? plainText\n : !customComponentsBeyondLinks && looksLikePlainProse(displayContent);\n\n if (isPlainText) {\n // <div> + whitespace-pre-wrap: respects newlines AND collapses\n // double spaces, which is what users mean when they hit Enter\n // twice. <span> would break flow inside a flex bubble.\n //\n // leading-snug (1.375), not leading-relaxed (1.625) — `pre-wrap`\n // makes every `\\n` a hard line break, so the relaxed leading\n // turns multi-line user messages into airy ladders. snug matches\n // WhatsApp/Telegram bubble density.\n return (\n <div\n className={`${textSizeClass} font-normal antialiased leading-snug break-words whitespace-pre-wrap ${className}`}\n >\n {displayContent}\n {collapsible && shouldCollapse && (\n <>\n {isCollapsed && '... '}\n <CollapseToggle\n isCollapsed={isCollapsed}\n onClick={toggleCollapsed}\n readMoreLabel={readMoreLabel}\n showLessLabel={showLessLabel}\n isUser={isUser}\n isCompact={isCompact}\n />\n </>\n )}\n </div>\n );\n }\n\n return (\n <div className={className}>\n <div\n className={`\n prose ${proseClass} max-w-none break-words overflow-hidden ${textSizeClass} font-normal antialiased\n ${isUser ? 'prose-invert' : 'dark:prose-invert'}\n [&>*]:leading-relaxed\n [&>*:first-child]:mt-0 [&>*:last-child]:mb-0\n [&_p]:my-2\n [&_ul]:my-2 [&_ol]:my-2 [&_ul]:pl-5 [&_ol]:pl-5\n [&_li]:my-1 [&_li>p]:my-0\n [&_h1]:mt-4 [&_h1]:mb-2 [&_h1]:text-base [&_h1]:font-semibold\n [&_h2]:mt-3.5 [&_h2]:mb-1.5 [&_h2]:text-[15px] [&_h2]:font-semibold\n [&_h3]:mt-3 [&_h3]:mb-1 [&_h3]:text-sm [&_h3]:font-medium\n [&_h4]:mt-3 [&_h4]:mb-1 [&_h4]:text-sm [&_h4]:font-medium\n `}\n style={{\n // Inherit colors from parent — fixes issues with external\n // CSS variables overriding prose tokens.\n '--tw-prose-body': 'inherit',\n '--tw-prose-headings': 'inherit',\n '--tw-prose-bold': 'inherit',\n '--tw-prose-links': 'inherit',\n color: 'inherit',\n } as React.CSSProperties}\n >\n <ReactMarkdown\n // Remark plugin order is load-bearing:\n // 1. `remark-gfm` — tables, strikethrough, autolinks, task lists.\n // 2. `remark-breaks` — chat convention: single `\\n` → `<br>`\n // (ChatGPT / Slack / Discord / Linear). CommonMark's\n // default would collapse those into one paragraph and\n // LLM punchlines / poems / dialogue would render as a\n // run-on line. Goes BEFORE smartypants so quotes that\n // land at line breaks still get the curly treatment.\n // 3. `remark-smartypants` — typographic substitutions:\n // \"...\" → …, -- → —, \"x\" → \"x\". Cheap \"humanized\"\n // polish à la Medium / Substack.\n // 4. `remark-emoji` — `:smile:` → 😄 (GitHub / Linear\n // shortcode style). Leaves Unicode emoji untouched.\n remarkPlugins={[remarkGfm, remarkBreaks, remarkSmartypants, remarkEmoji]}\n // rehype-raw parses inline HTML in the source; rehype-sanitize\n // (with our extended schema) runs after to keep XSS guards\n // (no scripts, no on* handlers, no javascript: urls).\n // rehype-external-links runs LAST so it tags every <a> that\n // sanitize let through — externals get target=_blank +\n // rel=noopener noreferrer in one pass, instead of every\n // custom `a` renderer reimplementing the rule.\n rehypePlugins={[\n rehypeRaw,\n [rehypeSanitize, schema],\n [rehypeExternalLinks, { target: '_blank', rel: ['noopener', 'noreferrer'] }],\n ]}\n components={components}\n // urlTransform runs in remark-rehype before sanitize. Without\n // overriding it, react-markdown's default strips `href` for\n // unknown schemes — making our extended sanitize whitelist\n // moot. Only set when the caller opted into extra protocols.\n urlTransform={urlTransform}\n >\n {displayContent}\n </ReactMarkdown>\n </div>\n {collapsible && shouldCollapse && (\n <CollapseToggle\n isCollapsed={isCollapsed}\n onClick={toggleCollapsed}\n readMoreLabel={readMoreLabel}\n showLessLabel={showLessLabel}\n isUser={isUser}\n isCompact={isCompact}\n />\n )}\n </div>\n );\n};\n\nexport const MarkdownMessage = memo(MarkdownMessageRaw);\n\nexport default MarkdownMessage;\n","'use client';\n\nimport React, { memo } from 'react';\nimport { CopyButton } from '@djangocfg/ui-core/components';\n\ninterface ActionRowProps {\n /** Raw text to copy — pass the same source string used for render. */\n value: string;\n /** Bubble side. Just controls flex alignment; nothing is mirrored. */\n isUser: boolean;\n /**\n * Whether the row is currently shown. Owner-controlled (typically\n * `<ChatMessageRow>` toggles this on hover with a small close delay).\n * The component is intentionally dumb about visibility — owners\n * have full control over reveal logic (hover, focus, always-on,\n * touch behaviour, etc.).\n */\n visible: boolean;\n}\n\n// Action row that lives directly under a chat bubble.\n// Visibility is fully owner-controlled via `visible`.\n//\n// We render at `opacity-0` (not `display:none`) so the fade in/out\n// stays smooth across re-renders. While invisible we drop pointer\n// events so a hidden row can't intercept clicks meant for the page\n// underneath.\n//\n// Memoised: re-renders only when `value`, `isUser` or `visible` change.\n// All props are primitives, so default shallow comparison is sufficient.\nfunction ActionRowRaw({ value, isUser, visible }: ActionRowProps) {\n return (\n <div\n className={`flex ${isUser ? 'justify-end' : 'justify-start'}\n transition-opacity duration-150\n ${visible ? 'opacity-100 pointer-events-auto' : 'opacity-0 pointer-events-none'}`}\n >\n <CopyButton\n value={value}\n size=\"icon\"\n variant=\"ghost\"\n iconClassName=\"h-3.5 w-3.5\"\n className=\"h-7 w-7 text-muted-foreground hover:text-foreground\"\n // Hidden rows must not be reachable via Tab — otherwise\n // keyboard users land on an invisible button.\n tabIndex={visible ? 0 : -1}\n aria-hidden={!visible}\n />\n </div>\n );\n}\n\nexport const ActionRow = memo(ActionRowRaw);\n","'use client';\n\nimport React, { memo, useCallback, useEffect, useRef, useState } from 'react';\nimport { useMediaQuery } from '@djangocfg/ui-core/hooks';\n\ninterface ChatMessageRowProps {\n /** Side of the conversation — drives flex alignment and `isUser`\n * passed to `actions`. */\n isUser: boolean;\n /** The bubble (your own JSX). Anything goes — `<MarkdownMessage>`,\n * custom card, multi-element composition. */\n children: React.ReactNode;\n /** Render-prop for the action row. Receives `visible` so the row\n * knows when to fade in/out. Render `null` to opt out. */\n actions?: (visible: boolean, isUser: boolean) => React.ReactNode;\n /** Close delay in ms after the cursor leaves the row. Long enough\n * to bridge cursor travel from bubble → action button without\n * flicker. Default 250ms (Radix Tooltip-ish). */\n closeDelayMs?: number;\n /** Optional class on the column container. */\n className?: string;\n}\n\n// Owner of the bubble + action row layout.\n//\n// Why a state-based hover instead of `group-hover` CSS:\n// - CSS-only hover bridges break when the cursor crosses gaps\n// between the bubble and the (initially-invisible) row — the\n// row's `pointer-events-none` lets the cursor \"fall through\",\n// `group-hover` flips off, the row vanishes mid-travel.\n// - State + a small close timeout gives Radix-Tooltip-style\n// stability: enter shows immediately, leave waits N ms.\n// - On touch (`@media (hover:none)`) hover doesn't exist; we\n// always pass `visible={true}` so the affordance is reachable.\n//\n// The action row is rendered **absolutely** under the bubble so\n// hidden rows don't allocate vertical space — no dead-air gap\n// between consecutive messages.\n//\n// Memoised: re-renders only when `isUser`, `children`, `actions`,\n// `closeDelayMs` or `className` change. `actions` render-prop is\n// compared by reference — callers should stabilise it with useCallback.\nfunction ChatMessageRowRaw({\n isUser,\n children,\n actions,\n closeDelayMs = 250,\n className = '',\n}: ChatMessageRowProps) {\n const isTouch = useMediaQuery('(hover: none), (pointer: coarse)');\n const [hovered, setHovered] = useState(false);\n const closeTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n const cancelClose = useCallback(() => {\n if (closeTimer.current) {\n clearTimeout(closeTimer.current);\n closeTimer.current = null;\n }\n }, []);\n\n const open = useCallback(() => {\n cancelClose();\n setHovered(true);\n }, [cancelClose]);\n\n const scheduleClose = useCallback(() => {\n cancelClose();\n closeTimer.current = setTimeout(() => setHovered(false), closeDelayMs);\n }, [cancelClose, closeDelayMs]);\n\n useEffect(() => () => cancelClose(), [cancelClose]);\n\n // Touch: always-visible. Hover: state-driven.\n const visible = isTouch || hovered;\n\n // On touch, `static` positioning so the row claims real layout\n // space (otherwise an absolute always-visible row would still\n // overlap the next message). On hover devices, `absolute` so the\n // hidden row doesn't leave dead air between bubbles.\n const rowPositionClass = isTouch ? 'static mt-1' : 'absolute top-full';\n const rowSideClass = isUser ? 'right-0' : 'left-0';\n\n return (\n <div\n className={`relative flex flex-col ${isUser ? 'items-end' : 'items-start'} ${className}`}\n onPointerEnter={isTouch ? undefined : open}\n onPointerLeave={isTouch ? undefined : scheduleClose}\n onFocusCapture={open}\n onBlurCapture={(e) => {\n if (!e.currentTarget.contains(e.relatedTarget as Node | null)) scheduleClose();\n }}\n >\n {children}\n {actions && (\n <div className={`${rowPositionClass} ${rowSideClass}`}>\n {actions(visible, isUser)}\n </div>\n )}\n </div>\n );\n}\n\nexport const ChatMessageRow = memo(ChatMessageRowRaw);\n"]}
|
|
@@ -196,6 +196,39 @@ var Mermaid = /* @__PURE__ */ __name((props) => {
|
|
|
196
196
|
return /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(LoadingFallback, {}), children: /* @__PURE__ */ jsx(MermaidClient, { ...props }) });
|
|
197
197
|
}, "Mermaid");
|
|
198
198
|
var Mermaid_default = Mermaid;
|
|
199
|
+
|
|
200
|
+
// src/tools/Chat/styles/bubbleTokens.ts
|
|
201
|
+
var BUBBLE_SURFACE = {
|
|
202
|
+
/** User-authored bubble — solid brand color. */
|
|
203
|
+
user: "bg-primary text-primary-foreground rounded-tr-md",
|
|
204
|
+
/** Assistant bubble in normal state — neutral muted surface. */
|
|
205
|
+
assistant: "bg-muted text-foreground rounded-tl-md",
|
|
206
|
+
/** Assistant bubble when the turn failed — destructive tint. */
|
|
207
|
+
error: "bg-destructive/10 text-destructive rounded-tl-md border border-destructive/30"
|
|
208
|
+
};
|
|
209
|
+
var ANCHOR = {
|
|
210
|
+
user: "text-primary-foreground underline decoration-primary-foreground/60 underline-offset-2 hover:decoration-primary-foreground transition-colors break-all",
|
|
211
|
+
assistant: "text-primary underline hover:text-primary/80 transition-colors break-all"
|
|
212
|
+
};
|
|
213
|
+
var TOGGLE = {
|
|
214
|
+
user: "text-primary-foreground/80 hover:text-primary-foreground",
|
|
215
|
+
assistant: "text-primary hover:text-primary/80"
|
|
216
|
+
};
|
|
217
|
+
var DESTRUCTIVE_SURFACE = {
|
|
218
|
+
/** Banner / card variant: border + tint + text. */
|
|
219
|
+
banner: "border border-destructive/40 bg-destructive/10 text-destructive",
|
|
220
|
+
/** Subtle hover for destructive buttons inside the banner / menu. */
|
|
221
|
+
hover: "hover:bg-destructive/15",
|
|
222
|
+
/** Strong-hover variant (e.g. trash overlay on attachments). */
|
|
223
|
+
hoverStrong: "hover:bg-destructive hover:text-destructive-foreground",
|
|
224
|
+
/** Inline destructive text utility. */
|
|
225
|
+
text: "text-destructive",
|
|
226
|
+
/** Hover style for menu items that delete data. */
|
|
227
|
+
menuItem: "text-destructive focus:text-destructive hover:bg-destructive/15 hover:text-destructive"
|
|
228
|
+
};
|
|
229
|
+
var TOOL_CALL = {
|
|
230
|
+
errorText: "text-destructive"
|
|
231
|
+
};
|
|
199
232
|
var PrettyCodeClient = lazy(() => import('./PrettyCode.client-ZGYGKE7G.mjs'));
|
|
200
233
|
var LoadingFallback2 = /* @__PURE__ */ __name(() => /* @__PURE__ */ jsx("div", { className: "relative rounded-sm border border-border overflow-hidden bg-muted dark:bg-zinc-900", children: /* @__PURE__ */ jsx("div", { className: "p-4", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
201
234
|
/* @__PURE__ */ jsx("div", { className: "animate-pulse h-4 w-4 rounded-full bg-muted-foreground/20" }),
|
|
@@ -314,7 +347,7 @@ function createMarkdownComponents(isUser = false, isCompact = false) {
|
|
|
314
347
|
{
|
|
315
348
|
...rest,
|
|
316
349
|
href,
|
|
317
|
-
className: `${textSize} ${isUser ?
|
|
350
|
+
className: `${textSize} ${isUser ? ANCHOR.user : ANCHOR.assistant}`,
|
|
318
351
|
children
|
|
319
352
|
}
|
|
320
353
|
), "a"),
|
|
@@ -410,7 +443,7 @@ function CollapseToggleRaw({
|
|
|
410
443
|
className: `
|
|
411
444
|
${textSize} font-medium cursor-pointer
|
|
412
445
|
transition-colors duration-200
|
|
413
|
-
${isUser ?
|
|
446
|
+
${isUser ? TOGGLE.user : TOGGLE.assistant}
|
|
414
447
|
inline-flex items-center gap-1
|
|
415
448
|
mt-1
|
|
416
449
|
`,
|
|
@@ -704,6 +737,6 @@ function ChatMessageRowRaw({
|
|
|
704
737
|
__name(ChatMessageRowRaw, "ChatMessageRowRaw");
|
|
705
738
|
memo(ChatMessageRowRaw);
|
|
706
739
|
|
|
707
|
-
export { MarkdownMessage, Mermaid_default, PrettyCode_default, extractTextFromChildren, useCollapsibleContent };
|
|
708
|
-
//# sourceMappingURL=chunk-
|
|
709
|
-
//# sourceMappingURL=chunk-
|
|
740
|
+
export { ANCHOR, BUBBLE_SURFACE, DESTRUCTIVE_SURFACE, MarkdownMessage, Mermaid_default, PrettyCode_default, TOGGLE, TOOL_CALL, extractTextFromChildren, useCollapsibleContent };
|
|
741
|
+
//# sourceMappingURL=chunk-HIK6BPL7.mjs.map
|
|
742
|
+
//# sourceMappingURL=chunk-HIK6BPL7.mjs.map
|