diff --git a/apps/x/apps/renderer/package.json b/apps/x/apps/renderer/package.json index 397dae9c..c52f1019 100644 --- a/apps/x/apps/renderer/package.json +++ b/apps/x/apps/renderer/package.json @@ -25,6 +25,11 @@ "@radix-ui/react-tooltip": "^1.2.8", "@radix-ui/react-use-controllable-state": "^1.2.2", "@tailwindcss/vite": "^4.1.18", + "@tiptap/extension-link": "^3.15.3", + "@tiptap/extension-placeholder": "^3.15.3", + "@tiptap/pm": "^3.15.3", + "@tiptap/react": "^3.15.3", + "@tiptap/starter-kit": "^3.15.3", "@x/preload": "workspace:*", "@x/shared": "workspace:*", "ai": "^5.0.117", @@ -39,6 +44,7 @@ "streamdown": "^1.6.10", "tailwind-merge": "^3.4.0", "tailwindcss": "^4.1.18", + "tiptap-markdown": "^0.9.0", "tokenlens": "^1.3.1", "use-stick-to-bottom": "^1.1.1", "zod": "^4.2.1" diff --git a/apps/x/apps/renderer/src/App.tsx b/apps/x/apps/renderer/src/App.tsx index a26de040..40bceae4 100644 --- a/apps/x/apps/renderer/src/App.tsx +++ b/apps/x/apps/renderer/src/App.tsx @@ -1,12 +1,14 @@ import * as React from 'react' -import { useCallback, useEffect, useState } from 'react' +import { useCallback, useEffect, useState, useRef } from 'react' import { workspace } from '@x/shared'; import { RunEvent } from '@x/shared/src/runs.js'; import type { ChatStatus, LanguageModelUsage, ToolUIPart } from 'ai'; import './App.css' import z from 'zod'; import { Button } from './components/ui/button'; -import { MessageSquare } from 'lucide-react'; +import { MessageSquare, CheckIcon, LoaderIcon } from 'lucide-react'; +import { MarkdownEditor } from './components/markdown-editor'; +import { useDebounce } from './hooks/use-debounce'; import { SidebarIcon } from '@/components/sidebar-icon'; import { SidebarContentPanel } from '@/components/sidebar-content'; import { SidebarSectionProvider } from '@/contexts/sidebar-context'; @@ -224,9 +226,16 @@ function App() { // File browser state (for Knowledge section) const [selectedPath, setSelectedPath] = useState(null) const [fileContent, setFileContent] = useState('') + const [editorContent, setEditorContent] = useState('') const [tree, setTree] = useState([]) const [expandedPaths, setExpandedPaths] = useState>(new Set()) + // Auto-save state + const [isSaving, setIsSaving] = useState(false) + const [lastSaved, setLastSaved] = useState(null) + const debouncedContent = useDebounce(editorContent, 500) + const initialContentRef = useRef('') + // Chat state const [message, setMessage] = useState('') const [conversation, setConversation] = useState([]) @@ -268,6 +277,9 @@ function App() { useEffect(() => { if (!selectedPath) { setFileContent('') + setEditorContent('') + initialContentRef.current = '' + setLastSaved(null) return } (async () => { @@ -276,16 +288,48 @@ function App() { if (stat.kind === 'file') { const result = await window.ipc.invoke('workspace:readFile', { path: selectedPath }) setFileContent(result.data) + setEditorContent(result.data) + initialContentRef.current = result.data + setLastSaved(null) } else { setFileContent('') + setEditorContent('') + initialContentRef.current = '' } } catch (err) { console.error('Failed to load file:', err) setFileContent('') + setEditorContent('') + initialContentRef.current = '' } })() }, [selectedPath]) + // Auto-save when content changes + useEffect(() => { + if (!selectedPath || !selectedPath.endsWith('.md')) return + if (debouncedContent === initialContentRef.current) return + if (!debouncedContent) return + + const saveFile = async () => { + setIsSaving(true) + try { + await window.ipc.invoke('workspace:writeFile', { + path: selectedPath, + data: debouncedContent, + opts: { encoding: 'utf8' } + }) + initialContentRef.current = debouncedContent + setLastSaved(new Date()) + } catch (err) { + console.error('Failed to save file:', err) + } finally { + setIsSaving(false) + } + } + saveFile() + }, [debouncedContent, selectedPath]) + // Listen to run events useEffect(() => { const cleanup = window.ipc.on('runs:events', ((event: unknown) => { @@ -685,24 +729,48 @@ function App() { {selectedPath ? selectedPath : 'Chat'} {selectedPath && ( - + <> + {/* Save status indicator */} +
+ {isSaving ? ( + <> + + Saving... + + ) : lastSaved ? ( + <> + + Saved + + ) : null} +
+ + )} {selectedPath ? ( -
-
-                    {fileContent || 'Loading...'}
-                  
-
+ selectedPath.endsWith('.md') ? ( + + ) : ( +
+
+                      {fileContent || 'Loading...'}
+                    
+
+ ) ) : (
diff --git a/apps/x/apps/renderer/src/components/editor-toolbar.tsx b/apps/x/apps/renderer/src/components/editor-toolbar.tsx new file mode 100644 index 00000000..e49acc2e --- /dev/null +++ b/apps/x/apps/renderer/src/components/editor-toolbar.tsx @@ -0,0 +1,181 @@ +import type { Editor } from '@tiptap/react' +import { Button } from '@/components/ui/button' +import { + BoldIcon, + ItalicIcon, + StrikethroughIcon, + CodeIcon, + Heading1Icon, + Heading2Icon, + Heading3Icon, + ListIcon, + ListOrderedIcon, + QuoteIcon, + MinusIcon, + LinkIcon, + CodeSquareIcon, +} from 'lucide-react' + +interface EditorToolbarProps { + editor: Editor | null +} + +export function EditorToolbar({ editor }: EditorToolbarProps) { + if (!editor) return null + + const setLink = () => { + const previousUrl = editor.getAttributes('link').href + const url = window.prompt('URL', previousUrl) + + if (url === null) return + + if (url === '') { + editor.chain().focus().extendMarkRange('link').unsetLink().run() + return + } + + editor.chain().focus().extendMarkRange('link').setLink({ href: url }).run() + } + + return ( +
+ + + + + +
+ + + + + +
+ + + + +
+ + + + + +
+ ) +} diff --git a/apps/x/apps/renderer/src/components/markdown-editor.tsx b/apps/x/apps/renderer/src/components/markdown-editor.tsx new file mode 100644 index 00000000..ec2bf47f --- /dev/null +++ b/apps/x/apps/renderer/src/components/markdown-editor.tsx @@ -0,0 +1,81 @@ +import { useEditor, EditorContent } from '@tiptap/react' +import StarterKit from '@tiptap/starter-kit' +import Link from '@tiptap/extension-link' +import Placeholder from '@tiptap/extension-placeholder' +import { Markdown } from 'tiptap-markdown' +import { useEffect, useCallback, useRef } from 'react' +import { EditorToolbar } from './editor-toolbar' +import '@/styles/editor.css' + +interface MarkdownEditorProps { + content: string + onChange: (markdown: string) => void + placeholder?: string +} + +export function MarkdownEditor({ content, onChange, placeholder = 'Start writing...' }: MarkdownEditorProps) { + const isInternalUpdate = useRef(false) + + const editor = useEditor({ + extensions: [ + StarterKit.configure({ + heading: { + levels: [1, 2, 3], + }, + }), + Link.configure({ + openOnClick: false, + HTMLAttributes: { + rel: 'noopener noreferrer', + target: '_blank', + }, + }), + Placeholder.configure({ + placeholder, + }), + Markdown.configure({ + html: false, + transformCopiedText: true, + transformPastedText: true, + }), + ], + content: '', + onUpdate: ({ editor }) => { + if (isInternalUpdate.current) return + const markdown = editor.storage.markdown.getMarkdown() + onChange(markdown) + }, + editorProps: { + attributes: { + class: 'prose prose-sm max-w-none focus:outline-none', + }, + }, + }) + + // Update editor content when prop changes (e.g., file selection changes) + useEffect(() => { + if (editor && content !== undefined) { + const currentContent = editor.storage.markdown?.getMarkdown() || '' + if (currentContent !== content) { + isInternalUpdate.current = true + editor.commands.setContent(content) + isInternalUpdate.current = false + } + } + }, [editor, content]) + + // Handle keyboard shortcuts + const handleKeyDown = useCallback((event: React.KeyboardEvent) => { + if (event.key === 's' && (event.metaKey || event.ctrlKey)) { + event.preventDefault() + // The parent component handles saving via onChange + } + }, []) + + return ( +
+ + +
+ ) +} diff --git a/apps/x/apps/renderer/src/hooks/use-debounce.ts b/apps/x/apps/renderer/src/hooks/use-debounce.ts new file mode 100644 index 00000000..7a74acc3 --- /dev/null +++ b/apps/x/apps/renderer/src/hooks/use-debounce.ts @@ -0,0 +1,23 @@ +import { useState, useEffect } from 'react' + +/** + * Debounce a value by a specified delay + * @param value The value to debounce + * @param delay The delay in milliseconds + * @returns The debounced value + */ +export function useDebounce(value: T, delay: number): T { + const [debouncedValue, setDebouncedValue] = useState(value) + + useEffect(() => { + const handler = setTimeout(() => { + setDebouncedValue(value) + }, delay) + + return () => { + clearTimeout(handler) + } + }, [value, delay]) + + return debouncedValue +} diff --git a/apps/x/apps/renderer/src/styles/editor.css b/apps/x/apps/renderer/src/styles/editor.css new file mode 100644 index 00000000..3ba91ce9 --- /dev/null +++ b/apps/x/apps/renderer/src/styles/editor.css @@ -0,0 +1,214 @@ +/* Tiptap Editor Styles */ + +.tiptap-editor { + display: flex; + flex-direction: column; + height: 100%; +} + +.tiptap-editor .ProseMirror { + flex: 1; + padding: 1rem; + outline: none; + overflow-y: auto; +} + +.tiptap-editor .ProseMirror:focus { + outline: none; +} + +/* Placeholder */ +.tiptap-editor .ProseMirror p.is-editor-empty:first-child::before { + color: var(--muted-foreground); + content: attr(data-placeholder); + float: left; + height: 0; + pointer-events: none; +} + +/* Typography */ +.tiptap-editor .ProseMirror { + font-size: 1rem; + line-height: 1.75; + color: var(--foreground); +} + +.tiptap-editor .ProseMirror > * + * { + margin-top: 0.75em; +} + +/* Headings */ +.tiptap-editor .ProseMirror h1 { + font-size: 2em; + font-weight: 700; + line-height: 1.2; + margin-top: 1.5em; + margin-bottom: 0.5em; +} + +.tiptap-editor .ProseMirror h2 { + font-size: 1.5em; + font-weight: 600; + line-height: 1.3; + margin-top: 1.25em; + margin-bottom: 0.5em; +} + +.tiptap-editor .ProseMirror h3 { + font-size: 1.25em; + font-weight: 600; + line-height: 1.4; + margin-top: 1em; + margin-bottom: 0.5em; +} + +.tiptap-editor .ProseMirror h1:first-child, +.tiptap-editor .ProseMirror h2:first-child, +.tiptap-editor .ProseMirror h3:first-child { + margin-top: 0; +} + +/* Paragraphs */ +.tiptap-editor .ProseMirror p { + margin: 0; +} + +/* Lists */ +.tiptap-editor .ProseMirror ul, +.tiptap-editor .ProseMirror ol { + padding-left: 1.5em; + margin: 0.5em 0; +} + +.tiptap-editor .ProseMirror ul { + list-style-type: disc; +} + +.tiptap-editor .ProseMirror ol { + list-style-type: decimal; +} + +.tiptap-editor .ProseMirror li { + margin: 0.25em 0; +} + +.tiptap-editor .ProseMirror li p { + margin: 0; +} + +/* Blockquote */ +.tiptap-editor .ProseMirror blockquote { + border-left: 3px solid var(--border); + padding-left: 1em; + margin-left: 0; + margin-right: 0; + color: var(--muted-foreground); + font-style: italic; +} + +/* Code */ +.tiptap-editor .ProseMirror code { + background-color: var(--muted); + border-radius: 0.25em; + padding: 0.15em 0.3em; + font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; + font-size: 0.9em; +} + +/* Code Block */ +.tiptap-editor .ProseMirror pre { + background-color: var(--muted); + border-radius: 0.5em; + padding: 1em; + overflow-x: auto; + margin: 0.75em 0; +} + +.tiptap-editor .ProseMirror pre code { + background: none; + padding: 0; + font-size: 0.875em; + color: inherit; +} + +/* Horizontal Rule */ +.tiptap-editor .ProseMirror hr { + border: none; + border-top: 1px solid var(--border); + margin: 1.5em 0; +} + +/* Links */ +.tiptap-editor .ProseMirror a { + color: var(--primary); + text-decoration: underline; + text-underline-offset: 2px; + cursor: pointer; +} + +.tiptap-editor .ProseMirror a:hover { + opacity: 0.8; +} + +/* Strong and Emphasis */ +.tiptap-editor .ProseMirror strong { + font-weight: 600; +} + +.tiptap-editor .ProseMirror em { + font-style: italic; +} + +.tiptap-editor .ProseMirror s { + text-decoration: line-through; +} + +/* Task Lists */ +.tiptap-editor .ProseMirror ul[data-type="taskList"] { + list-style: none; + padding-left: 0; +} + +.tiptap-editor .ProseMirror ul[data-type="taskList"] li { + display: flex; + align-items: flex-start; + gap: 0.5em; +} + +.tiptap-editor .ProseMirror ul[data-type="taskList"] li > label { + flex-shrink: 0; + margin-top: 0.25em; +} + +/* Selection */ +.tiptap-editor .ProseMirror ::selection { + background-color: var(--ring); + color: var(--background); +} + +/* Toolbar */ +.editor-toolbar { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 0.25rem; + padding: 0.5rem; + border-bottom: 1px solid var(--border); + background-color: var(--background); +} + +.editor-toolbar .separator { + width: 1px; + height: 1.5rem; + background-color: var(--border); + margin: 0 0.25rem; + align-self: center; +} + +/* Content area centering */ +.tiptap-editor .ProseMirror { + margin-left: 20%; + margin-right: 20%; + padding-left: 1rem; + padding-right: 1rem; +} diff --git a/apps/x/pnpm-lock.yaml b/apps/x/pnpm-lock.yaml index 3a612db3..82d1ffc1 100644 --- a/apps/x/pnpm-lock.yaml +++ b/apps/x/pnpm-lock.yaml @@ -124,6 +124,21 @@ importers: '@tailwindcss/vite': specifier: ^4.1.18 version: 4.1.18(vite@7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2)) + '@tiptap/extension-link': + specifier: ^3.15.3 + version: 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3) + '@tiptap/extension-placeholder': + specifier: ^3.15.3 + version: 3.15.3(@tiptap/extensions@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)) + '@tiptap/pm': + specifier: ^3.15.3 + version: 3.15.3 + '@tiptap/react': + specifier: ^3.15.3 + version: 3.15.3(@floating-ui/dom@1.7.4)(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3) + '@tiptap/starter-kit': + specifier: ^3.15.3 + version: 3.15.3 '@x/preload': specifier: workspace:* version: link:../preload @@ -166,6 +181,9 @@ importers: tailwindcss: specifier: ^4.1.18 version: 4.1.18 + tiptap-markdown: + specifier: ^0.9.0 + version: 0.9.0(@tiptap/core@3.15.3(@tiptap/pm@3.15.3)) tokenlens: specifier: ^1.3.1 version: 1.3.1 @@ -1397,6 +1415,9 @@ packages: '@radix-ui/rect@1.1.1': resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==} + '@remirror/core-constants@3.0.0': + resolution: {integrity: sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==} + '@rolldown/pluginutils@1.0.0-beta.53': resolution: {integrity: sha512-vENRlFU4YbrwVqNDZ7fLvy+JR1CRkyr01jhSiDpE1u6py3OMzQfztQU2jxykW3ALNxO4kSlqIDeYyD0Y9RcQeQ==} @@ -1632,6 +1653,160 @@ packages: peerDependencies: vite: ^5.2.0 || ^6 || ^7 + '@tiptap/core@3.15.3': + resolution: {integrity: sha512-bmXydIHfm2rEtGju39FiQNfzkFx9CDvJe+xem1dgEZ2P6Dj7nQX9LnA1ZscW7TuzbBRkL5p3dwuBIi3f62A66A==} + peerDependencies: + '@tiptap/pm': ^3.15.3 + + '@tiptap/extension-blockquote@3.15.3': + resolution: {integrity: sha512-13x5UsQXtttFpoS/n1q173OeurNxppsdWgP3JfsshzyxIghhC141uL3H6SGYQLPU31AizgDs2OEzt6cSUevaZg==} + peerDependencies: + '@tiptap/core': ^3.15.3 + + '@tiptap/extension-bold@3.15.3': + resolution: {integrity: sha512-I8JYbkkUTNUXbHd/wCse2bR0QhQtJD7+0/lgrKOmGfv5ioLxcki079Nzuqqay3PjgYoJLIJQvm3RAGxT+4X91w==} + peerDependencies: + '@tiptap/core': ^3.15.3 + + '@tiptap/extension-bubble-menu@3.15.3': + resolution: {integrity: sha512-e88DG1bTy6hKxrt7iPVQhJnH5/EOrnKpIyp09dfRDgWrrW88fE0Qjys7a/eT8W+sXyXM3z10Ye7zpERWsrLZDg==} + peerDependencies: + '@tiptap/core': ^3.15.3 + '@tiptap/pm': ^3.15.3 + + '@tiptap/extension-bullet-list@3.15.3': + resolution: {integrity: sha512-MGwEkNT7ltst6XaWf0ObNgpKQ4PvuuV3igkBrdYnQS+qaAx9IF4isygVPqUc9DvjYC306jpyKsNqNrENIXcosA==} + peerDependencies: + '@tiptap/extension-list': ^3.15.3 + + '@tiptap/extension-code-block@3.15.3': + resolution: {integrity: sha512-q1UB9icNfdJppTqMIUWfoRKkx5SSdWIpwZoL2NeOI5Ah3E20/dQKVttIgLhsE521chyvxCYCRaHD5tMNGKfhyw==} + peerDependencies: + '@tiptap/core': ^3.15.3 + '@tiptap/pm': ^3.15.3 + + '@tiptap/extension-code@3.15.3': + resolution: {integrity: sha512-x6LFt3Og6MFINYpsMzrJnz7vaT9Yk1t4oXkbJsJRSavdIWBEBcoRudKZ4sSe/AnsYlRJs8FY2uR76mt9e+7xAQ==} + peerDependencies: + '@tiptap/core': ^3.15.3 + + '@tiptap/extension-document@3.15.3': + resolution: {integrity: sha512-AC72nI2gnogBuETCKbZekn+h6t5FGGcZG2abPGKbz/x9rwpb6qV2hcbAQ30t6M7H6cTOh2/Ut8bEV2MtMB15sw==} + peerDependencies: + '@tiptap/core': ^3.15.3 + + '@tiptap/extension-dropcursor@3.15.3': + resolution: {integrity: sha512-jGI5XZpdo8GSYQFj7HY15/oEwC2m2TqZz0/Fln5qIhY32XlZhWrsMuMI6WbUJrTH16es7xO6jmRlDsc6g+vJWg==} + peerDependencies: + '@tiptap/extensions': ^3.15.3 + + '@tiptap/extension-floating-menu@3.15.3': + resolution: {integrity: sha512-+3DVBleKKffadEJEdLYxmYAJOjHjLSqtiSFUE3RABT4V2ka1ODy2NIpyKX0o1SvQ5N1jViYT9Q+yUbNa6zCcDw==} + peerDependencies: + '@floating-ui/dom': ^1.0.0 + '@tiptap/core': ^3.15.3 + '@tiptap/pm': ^3.15.3 + + '@tiptap/extension-gapcursor@3.15.3': + resolution: {integrity: sha512-Kaw0sNzP0bQI/xEAMSfIpja6xhsu9WqqAK/puzOIS1RKWO47Wps/tzqdSJ9gfslPIb5uY5mKCfy8UR8Xgiia8w==} + peerDependencies: + '@tiptap/extensions': ^3.15.3 + + '@tiptap/extension-hard-break@3.15.3': + resolution: {integrity: sha512-8HjxmeRbBiXW+7JKemAJtZtHlmXQ9iji398CPQ0yYde68WbIvUhHXjmbJE5pxFvvQTJ/zJv1aISeEOZN2bKBaw==} + peerDependencies: + '@tiptap/core': ^3.15.3 + + '@tiptap/extension-heading@3.15.3': + resolution: {integrity: sha512-G1GG6iN1YXPS+75arDpo+bYRzhr3dNDw99c7D7na3aDawa9Qp7sZ/bVrzFUUcVEce0cD6h83yY7AooBxEc67hA==} + peerDependencies: + '@tiptap/core': ^3.15.3 + + '@tiptap/extension-horizontal-rule@3.15.3': + resolution: {integrity: sha512-FYkN7L6JsfwwNEntmLklCVKvgL0B0N47OXMacRk6kYKQmVQ4Nvc7q/VJLpD9sk4wh4KT1aiCBfhKEBTu5pv1fg==} + peerDependencies: + '@tiptap/core': ^3.15.3 + '@tiptap/pm': ^3.15.3 + + '@tiptap/extension-italic@3.15.3': + resolution: {integrity: sha512-6XeuPjcWy7OBxpkgOV7bD6PATO5jhIxc8SEK4m8xn8nelGTBIbHGqK37evRv+QkC7E0MUryLtzwnmmiaxcKL0Q==} + peerDependencies: + '@tiptap/core': ^3.15.3 + + '@tiptap/extension-link@3.15.3': + resolution: {integrity: sha512-PdDXyBF9Wco9U1x6e+b7tKBWG+kqBDXDmaYXHkFm/gYuQCQafVJ5mdrDdKgkHDWVnJzMWZXBcZjT9r57qtlLWg==} + peerDependencies: + '@tiptap/core': ^3.15.3 + '@tiptap/pm': ^3.15.3 + + '@tiptap/extension-list-item@3.15.3': + resolution: {integrity: sha512-CCxL5ek1p0lO5e8aqhnPzIySldXRSigBFk2fP9OLgdl5qKFLs2MGc19jFlx5+/kjXnEsdQTFbGY1Sizzt0TVDw==} + peerDependencies: + '@tiptap/extension-list': ^3.15.3 + + '@tiptap/extension-list-keymap@3.15.3': + resolution: {integrity: sha512-UxqnTEEAKrL+wFQeSyC9z0mgyUUVRS2WTcVFoLZCE6/Xus9F53S4bl7VKFadjmqI4GpDk5Oe2IOUc72o129jWg==} + peerDependencies: + '@tiptap/extension-list': ^3.15.3 + + '@tiptap/extension-list@3.15.3': + resolution: {integrity: sha512-n7y/MF9lAM5qlpuH5IR4/uq+kJPEJpe9NrEiH+NmkO/5KJ6cXzpJ6F4U17sMLf2SNCq+TWN9QK8QzoKxIn50VQ==} + peerDependencies: + '@tiptap/core': ^3.15.3 + '@tiptap/pm': ^3.15.3 + + '@tiptap/extension-ordered-list@3.15.3': + resolution: {integrity: sha512-/8uhw528Iy0c9wF6tHCiIn0ToM0Ml6Ll2c/3iPRnKr4IjXwx2Lr994stUFihb+oqGZwV1J8CPcZJ4Ufpdqi4Dw==} + peerDependencies: + '@tiptap/extension-list': ^3.15.3 + + '@tiptap/extension-paragraph@3.15.3': + resolution: {integrity: sha512-lc0Qu/1AgzcEfS67NJMj5tSHHhH6NtA6uUpvppEKGsvJwgE2wKG1onE4isrVXmcGRdxSMiCtyTDemPNMu6/ozQ==} + peerDependencies: + '@tiptap/core': ^3.15.3 + + '@tiptap/extension-placeholder@3.15.3': + resolution: {integrity: sha512-XcHHnojT186hKIoOgcPBesXk89+caNGVUdMtc171Vcr/5s0dpnr4q5LfE+YRC+S85CpCxCRRnh84Ou+XRtOqrw==} + peerDependencies: + '@tiptap/extensions': ^3.15.3 + + '@tiptap/extension-strike@3.15.3': + resolution: {integrity: sha512-Y1P3eGNY7RxQs2BcR6NfLo9VfEOplXXHAqkOM88oowWWOE7dMNeFFZM9H8HNxoQgXJ7H0aWW9B7ZTWM9hWli2Q==} + peerDependencies: + '@tiptap/core': ^3.15.3 + + '@tiptap/extension-text@3.15.3': + resolution: {integrity: sha512-MhkBz8ZvrqOKtKNp+ZWISKkLUlTrDR7tbKZc2OnNcUTttL9dz0HwT+cg91GGz19fuo7ttDcfsPV6eVmflvGToA==} + peerDependencies: + '@tiptap/core': ^3.15.3 + + '@tiptap/extension-underline@3.15.3': + resolution: {integrity: sha512-r/IwcNN0W366jGu4Y0n2MiFq9jGa4aopOwtfWO4d+J0DyeS2m7Go3+KwoUqi0wQTiVU74yfi4DF6eRsMQ9/iHQ==} + peerDependencies: + '@tiptap/core': ^3.15.3 + + '@tiptap/extensions@3.15.3': + resolution: {integrity: sha512-ycx/BgxR4rc9tf3ZyTdI98Z19yKLFfqM3UN+v42ChuIwkzyr9zyp7kG8dB9xN2lNqrD+5y/HyJobz/VJ7T90gA==} + peerDependencies: + '@tiptap/core': ^3.15.3 + '@tiptap/pm': ^3.15.3 + + '@tiptap/pm@3.15.3': + resolution: {integrity: sha512-Zm1BaU1TwFi3CQiisxjgnzzIus+q40bBKWLqXf6WEaus8Z6+vo1MT2pU52dBCMIRaW9XNDq3E5cmGtMc1AlveA==} + + '@tiptap/react@3.15.3': + resolution: {integrity: sha512-XvouB+Hrqw8yFmZLPEh+HWlMeRSjZfHSfWfWuw5d8LSwnxnPeu3Bg/rjHrRrdwb+7FumtzOnNWMorpb/PSOttQ==} + peerDependencies: + '@tiptap/core': ^3.15.3 + '@tiptap/pm': ^3.15.3 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + '@types/react-dom': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@tiptap/starter-kit@3.15.3': + resolution: {integrity: sha512-ia+eQr9Mt1ln2UO+kK4kFTJOrZK4GhvZXFjpCCYuHtco3rhr2fZAIxEEY4cl/vo5VO5WWyPqxhkFeLcoWmNjSw==} + '@tokenlens/core@1.3.0': resolution: {integrity: sha512-d8YNHNC+q10bVpi95fELJwJyPVf1HfvBEI18eFQxRSZTdByXrP+f/ZtlhSzkx0Jl0aEmYVeBA5tPeeYRioLViQ==} @@ -1779,9 +1954,27 @@ packages: '@types/keyv@3.1.4': resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + '@types/linkify-it@3.0.5': + resolution: {integrity: sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==} + + '@types/linkify-it@5.0.0': + resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + + '@types/markdown-it@13.0.9': + resolution: {integrity: sha512-1XPwR0+MgXLWfTn9gCsZ55AHOKW1WN+P9vr0PaQh5aerR9LLQXUbjfEAFhjmEmyoYFWAyuN2Mqkn40MZ4ukjBw==} + + '@types/markdown-it@14.1.2': + resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} + '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + '@types/mdurl@1.0.5': + resolution: {integrity: sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==} + + '@types/mdurl@2.0.0': + resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==} + '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} @@ -1814,6 +2007,9 @@ packages: '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + '@types/use-sync-external-store@0.0.6': + resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} + '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} @@ -2155,6 +2351,9 @@ packages: cose-base@2.2.0: resolution: {integrity: sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==} + crelt@1.0.6: + resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} + cross-spawn@7.0.6: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} @@ -2590,6 +2789,10 @@ packages: fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-equals@5.4.0: + resolution: {integrity: sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw==} + engines: {node: '>=6.0.0'} + fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} @@ -3165,6 +3368,12 @@ packages: resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} engines: {node: '>= 12.0.0'} + linkify-it@5.0.0: + resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + + linkifyjs@4.3.2: + resolution: {integrity: sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -3210,6 +3419,13 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + markdown-it-task-lists@2.1.1: + resolution: {integrity: sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA==} + + markdown-it@14.1.0: + resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} + hasBin: true + markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} @@ -3274,6 +3490,9 @@ packages: mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + mdurl@2.0.0: + resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==} + media-typer@1.1.0: resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} engines: {node: '>= 0.8'} @@ -3573,6 +3792,9 @@ packages: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} + orderedmap@2.1.1: + resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==} + p-cancelable@2.1.1: resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} engines: {node: '>=8'} @@ -3671,6 +3893,64 @@ packages: property-information@7.1.0: resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + prosemirror-changeset@2.3.1: + resolution: {integrity: sha512-j0kORIBm8ayJNl3zQvD1TTPHJX3g042et6y/KQhZhnPrruO8exkTgG8X+NRpj7kIyMMEx74Xb3DyMIBtO0IKkQ==} + + prosemirror-collab@1.3.1: + resolution: {integrity: sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==} + + prosemirror-commands@1.7.1: + resolution: {integrity: sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==} + + prosemirror-dropcursor@1.8.2: + resolution: {integrity: sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==} + + prosemirror-gapcursor@1.4.0: + resolution: {integrity: sha512-z00qvurSdCEWUIulij/isHaqu4uLS8r/Fi61IbjdIPJEonQgggbJsLnstW7Lgdk4zQ68/yr6B6bf7sJXowIgdQ==} + + prosemirror-history@1.5.0: + resolution: {integrity: sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==} + + prosemirror-inputrules@1.5.1: + resolution: {integrity: sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==} + + prosemirror-keymap@1.2.3: + resolution: {integrity: sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==} + + prosemirror-markdown@1.13.2: + resolution: {integrity: sha512-FPD9rHPdA9fqzNmIIDhhnYQ6WgNoSWX9StUZ8LEKapaXU9i6XgykaHKhp6XMyXlOWetmaFgGDS/nu/w9/vUc5g==} + + prosemirror-menu@1.2.5: + resolution: {integrity: sha512-qwXzynnpBIeg1D7BAtjOusR+81xCp53j7iWu/IargiRZqRjGIlQuu1f3jFi+ehrHhWMLoyOQTSRx/IWZJqOYtQ==} + + prosemirror-model@1.25.4: + resolution: {integrity: sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==} + + prosemirror-schema-basic@1.2.4: + resolution: {integrity: sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==} + + prosemirror-schema-list@1.5.1: + resolution: {integrity: sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==} + + prosemirror-state@1.4.4: + resolution: {integrity: sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==} + + prosemirror-tables@1.8.5: + resolution: {integrity: sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==} + + prosemirror-trailing-node@3.0.0: + resolution: {integrity: sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==} + peerDependencies: + prosemirror-model: ^1.22.1 + prosemirror-state: ^1.4.2 + prosemirror-view: ^1.33.8 + + prosemirror-transform@1.10.5: + resolution: {integrity: sha512-RPDQCxIDhIBb1o36xxwsaeAvivO8VLJcgBtzmOwQ64bMtsVFh5SSuJ6dWSxO1UsHTiTXPCgQm3PDJt7p6IOLbw==} + + prosemirror-view@1.41.4: + resolution: {integrity: sha512-WkKgnyjNncri03Gjaz3IFWvCAE94XoiEgvtr0/r2Xw7R8/IjK3sKLSiDoCHWcsXSAinVaKlGRZDvMCsF1kbzjA==} + proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -3681,6 +3961,10 @@ packages: pump@3.0.3: resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -3845,6 +4129,9 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rope-sequence@1.3.4: + resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} + roughjs@4.6.6: resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==} @@ -4016,6 +4303,11 @@ packages: resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} engines: {node: '>=12.0.0'} + tiptap-markdown@0.9.0: + resolution: {integrity: sha512-dKLQ9iiuGNgrlGVjrNauF/UBzWu4LYOx5pkD0jNkmQt/GOwfCJsBuzZTsf1jZ204ANHOm572mZ9PYvGh1S7tpQ==} + peerDependencies: + '@tiptap/core': ^3.0.1 + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -4080,6 +4372,9 @@ packages: engines: {node: '>=14.17'} hasBin: true + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + ufo@1.6.1: resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} @@ -4244,6 +4539,9 @@ packages: vscode-uri@3.0.8: resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==} + w3c-keyname@2.2.8: + resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + wait-on@9.0.3: resolution: {integrity: sha512-13zBnyYvFDW1rBvWiJ6Av3ymAaq8EDQuvxZnPIw3g04UqGi4TyoIJABmfJ6zrvKo9yeFQExNkOk7idQbDJcuKA==} engines: {node: '>=20.0.0'} @@ -5349,6 +5647,8 @@ snapshots: '@radix-ui/rect@1.1.1': {} + '@remirror/core-constants@3.0.0': {} + '@rolldown/pluginutils@1.0.0-beta.53': {} '@rollup/rollup-android-arm-eabi@4.54.0': @@ -5526,6 +5826,187 @@ snapshots: tailwindcss: 4.1.18 vite: 7.3.0(@types/node@24.10.4)(jiti@2.6.1)(lightningcss@1.30.2)(yaml@2.8.2) + '@tiptap/core@3.15.3(@tiptap/pm@3.15.3)': + dependencies: + '@tiptap/pm': 3.15.3 + + '@tiptap/extension-blockquote@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))': + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + + '@tiptap/extension-bold@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))': + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + + '@tiptap/extension-bubble-menu@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)': + dependencies: + '@floating-ui/dom': 1.7.4 + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + '@tiptap/pm': 3.15.3 + optional: true + + '@tiptap/extension-bullet-list@3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))': + dependencies: + '@tiptap/extension-list': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3) + + '@tiptap/extension-code-block@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)': + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + '@tiptap/pm': 3.15.3 + + '@tiptap/extension-code@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))': + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + + '@tiptap/extension-document@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))': + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + + '@tiptap/extension-dropcursor@3.15.3(@tiptap/extensions@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))': + dependencies: + '@tiptap/extensions': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3) + + '@tiptap/extension-floating-menu@3.15.3(@floating-ui/dom@1.7.4)(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)': + dependencies: + '@floating-ui/dom': 1.7.4 + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + '@tiptap/pm': 3.15.3 + optional: true + + '@tiptap/extension-gapcursor@3.15.3(@tiptap/extensions@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))': + dependencies: + '@tiptap/extensions': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3) + + '@tiptap/extension-hard-break@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))': + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + + '@tiptap/extension-heading@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))': + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + + '@tiptap/extension-horizontal-rule@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)': + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + '@tiptap/pm': 3.15.3 + + '@tiptap/extension-italic@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))': + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + + '@tiptap/extension-link@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)': + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + '@tiptap/pm': 3.15.3 + linkifyjs: 4.3.2 + + '@tiptap/extension-list-item@3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))': + dependencies: + '@tiptap/extension-list': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3) + + '@tiptap/extension-list-keymap@3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))': + dependencies: + '@tiptap/extension-list': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3) + + '@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)': + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + '@tiptap/pm': 3.15.3 + + '@tiptap/extension-ordered-list@3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))': + dependencies: + '@tiptap/extension-list': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3) + + '@tiptap/extension-paragraph@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))': + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + + '@tiptap/extension-placeholder@3.15.3(@tiptap/extensions@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3))': + dependencies: + '@tiptap/extensions': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3) + + '@tiptap/extension-strike@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))': + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + + '@tiptap/extension-text@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))': + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + + '@tiptap/extension-underline@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))': + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + + '@tiptap/extensions@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)': + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + '@tiptap/pm': 3.15.3 + + '@tiptap/pm@3.15.3': + dependencies: + prosemirror-changeset: 2.3.1 + prosemirror-collab: 1.3.1 + prosemirror-commands: 1.7.1 + prosemirror-dropcursor: 1.8.2 + prosemirror-gapcursor: 1.4.0 + prosemirror-history: 1.5.0 + prosemirror-inputrules: 1.5.1 + prosemirror-keymap: 1.2.3 + prosemirror-markdown: 1.13.2 + prosemirror-menu: 1.2.5 + prosemirror-model: 1.25.4 + prosemirror-schema-basic: 1.2.4 + prosemirror-schema-list: 1.5.1 + prosemirror-state: 1.4.4 + prosemirror-tables: 1.8.5 + prosemirror-trailing-node: 3.0.0(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.4) + prosemirror-transform: 1.10.5 + prosemirror-view: 1.41.4 + + '@tiptap/react@3.15.3(@floating-ui/dom@1.7.4)(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)': + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + '@tiptap/pm': 3.15.3 + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@types/use-sync-external-store': 0.0.6 + fast-equals: 5.4.0 + react: 19.2.3 + react-dom: 19.2.3(react@19.2.3) + use-sync-external-store: 1.6.0(react@19.2.3) + optionalDependencies: + '@tiptap/extension-bubble-menu': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3) + '@tiptap/extension-floating-menu': 3.15.3(@floating-ui/dom@1.7.4)(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3) + transitivePeerDependencies: + - '@floating-ui/dom' + + '@tiptap/starter-kit@3.15.3': + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + '@tiptap/extension-blockquote': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3)) + '@tiptap/extension-bold': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3)) + '@tiptap/extension-bullet-list': 3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)) + '@tiptap/extension-code': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3)) + '@tiptap/extension-code-block': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3) + '@tiptap/extension-document': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3)) + '@tiptap/extension-dropcursor': 3.15.3(@tiptap/extensions@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)) + '@tiptap/extension-gapcursor': 3.15.3(@tiptap/extensions@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)) + '@tiptap/extension-hard-break': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3)) + '@tiptap/extension-heading': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3)) + '@tiptap/extension-horizontal-rule': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3) + '@tiptap/extension-italic': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3)) + '@tiptap/extension-link': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3) + '@tiptap/extension-list': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3) + '@tiptap/extension-list-item': 3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)) + '@tiptap/extension-list-keymap': 3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)) + '@tiptap/extension-ordered-list': 3.15.3(@tiptap/extension-list@3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3)) + '@tiptap/extension-paragraph': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3)) + '@tiptap/extension-strike': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3)) + '@tiptap/extension-text': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3)) + '@tiptap/extension-underline': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3)) + '@tiptap/extensions': 3.15.3(@tiptap/core@3.15.3(@tiptap/pm@3.15.3))(@tiptap/pm@3.15.3) + '@tiptap/pm': 3.15.3 + '@tokenlens/core@1.3.0': {} '@tokenlens/fetch@1.3.0': @@ -5712,10 +6193,28 @@ snapshots: dependencies: '@types/node': 25.0.3 + '@types/linkify-it@3.0.5': {} + + '@types/linkify-it@5.0.0': {} + + '@types/markdown-it@13.0.9': + dependencies: + '@types/linkify-it': 3.0.5 + '@types/mdurl': 1.0.5 + + '@types/markdown-it@14.1.2': + dependencies: + '@types/linkify-it': 5.0.0 + '@types/mdurl': 2.0.0 + '@types/mdast@4.0.4': dependencies: '@types/unist': 3.0.3 + '@types/mdurl@1.0.5': {} + + '@types/mdurl@2.0.0': {} + '@types/ms@2.1.0': {} '@types/node@22.19.3': @@ -5749,6 +6248,8 @@ snapshots: '@types/unist@3.0.3': {} + '@types/use-sync-external-store@0.0.6': {} + '@types/yauzl@2.10.3': dependencies: '@types/node': 25.0.3 @@ -6133,6 +6634,8 @@ snapshots: dependencies: layout-base: 2.0.1 + crelt@1.0.6: {} + cross-spawn@7.0.6: dependencies: path-key: 3.1.1 @@ -6684,6 +7187,8 @@ snapshots: fast-deep-equal@3.1.3: {} + fast-equals@5.4.0: {} + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -7352,6 +7857,12 @@ snapshots: lightningcss-win32-arm64-msvc: 1.30.2 lightningcss-win32-x64-msvc: 1.30.2 + linkify-it@5.0.0: + dependencies: + uc.micro: 2.1.0 + + linkifyjs@4.3.2: {} + locate-path@6.0.0: dependencies: p-locate: 5.0.0 @@ -7390,6 +7901,17 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + markdown-it-task-lists@2.1.1: {} + + markdown-it@14.1.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.0 + mdurl: 2.0.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + markdown-table@3.0.4: {} marked@16.4.2: {} @@ -7566,6 +8088,8 @@ snapshots: dependencies: '@types/mdast': 4.0.4 + mdurl@2.0.0: {} + media-typer@1.1.0: {} merge-descriptors@2.0.0: {} @@ -7976,6 +8500,8 @@ snapshots: type-check: 0.4.0 word-wrap: 1.2.5 + orderedmap@2.1.1: {} + p-cancelable@2.1.1: {} p-limit@3.1.0: @@ -8065,6 +8591,109 @@ snapshots: property-information@7.1.0: {} + prosemirror-changeset@2.3.1: + dependencies: + prosemirror-transform: 1.10.5 + + prosemirror-collab@1.3.1: + dependencies: + prosemirror-state: 1.4.4 + + prosemirror-commands@1.7.1: + dependencies: + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + + prosemirror-dropcursor@1.8.2: + dependencies: + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + prosemirror-view: 1.41.4 + + prosemirror-gapcursor@1.4.0: + dependencies: + prosemirror-keymap: 1.2.3 + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-view: 1.41.4 + + prosemirror-history@1.5.0: + dependencies: + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + prosemirror-view: 1.41.4 + rope-sequence: 1.3.4 + + prosemirror-inputrules@1.5.1: + dependencies: + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + + prosemirror-keymap@1.2.3: + dependencies: + prosemirror-state: 1.4.4 + w3c-keyname: 2.2.8 + + prosemirror-markdown@1.13.2: + dependencies: + '@types/markdown-it': 14.1.2 + markdown-it: 14.1.0 + prosemirror-model: 1.25.4 + + prosemirror-menu@1.2.5: + dependencies: + crelt: 1.0.6 + prosemirror-commands: 1.7.1 + prosemirror-history: 1.5.0 + prosemirror-state: 1.4.4 + + prosemirror-model@1.25.4: + dependencies: + orderedmap: 2.1.1 + + prosemirror-schema-basic@1.2.4: + dependencies: + prosemirror-model: 1.25.4 + + prosemirror-schema-list@1.5.1: + dependencies: + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + + prosemirror-state@1.4.4: + dependencies: + prosemirror-model: 1.25.4 + prosemirror-transform: 1.10.5 + prosemirror-view: 1.41.4 + + prosemirror-tables@1.8.5: + dependencies: + prosemirror-keymap: 1.2.3 + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + prosemirror-view: 1.41.4 + + prosemirror-trailing-node@3.0.0(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.4): + dependencies: + '@remirror/core-constants': 3.0.0 + escape-string-regexp: 4.0.0 + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-view: 1.41.4 + + prosemirror-transform@1.10.5: + dependencies: + prosemirror-model: 1.25.4 + + prosemirror-view@1.41.4: + dependencies: + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 + proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 @@ -8077,6 +8706,8 @@ snapshots: end-of-stream: 1.4.5 once: 1.4.0 + punycode.js@2.3.1: {} + punycode@2.3.1: {} qs@6.14.1: @@ -8287,6 +8918,8 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.54.0 fsevents: 2.3.3 + rope-sequence@1.3.4: {} + roughjs@4.6.6: dependencies: hachure-fill: 0.5.2 @@ -8514,6 +9147,14 @@ snapshots: fdir: 6.5.0(picomatch@4.0.3) picomatch: 4.0.3 + tiptap-markdown@0.9.0(@tiptap/core@3.15.3(@tiptap/pm@3.15.3)): + dependencies: + '@tiptap/core': 3.15.3(@tiptap/pm@3.15.3) + '@types/markdown-it': 13.0.9 + markdown-it: 14.1.0 + markdown-it-task-lists: 2.1.1 + prosemirror-markdown: 1.13.2 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -8571,6 +9212,8 @@ snapshots: typescript@5.9.3: {} + uc.micro@2.1.0: {} + ufo@1.6.1: {} undici-types@6.21.0: {} @@ -8712,6 +9355,8 @@ snapshots: vscode-uri@3.0.8: {} + w3c-keyname@2.2.8: {} + wait-on@9.0.3: dependencies: axios: 1.13.2