@tessera-editor/core 0.1.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/nodes/hint.ts","../src/nodes/collapsible.ts","../src/nodes/image.ts","../src/nodes/table.ts","../src/nodes/embed.ts","../src/nodes/toc.ts","../src/marks/ai.ts","../src/marks/comment.ts","../src/marks/placeholder.ts","../src/extensions/input-rules.ts","../src/extensions/shortcuts.ts","../src/extensions/find-replace.ts","../src/extensions/slash.ts","../src/i18n.ts","../src/extensions/emoji.ts","../src/extensions/history.ts","../src/services.ts","../src/extensions/context-menu.ts","../src/extensions/gallery.ts","../src/extensions/metrics.ts","../src/markdown.ts","../src/extensions/word-paste.ts","../src/wordpaste.ts","../src/blockmenu.ts","../src/preset.ts","../src/diff.ts","../src/writeback.ts"],"sourcesContent":["import { Node, mergeAttributes, wrappingInputRule } from '@tiptap/core'\n\nexport type HintVariant = 'info' | 'success' | 'warning' | 'danger' | 'neutral'\n\nexport interface HintOptions {\n HTMLAttributes: Record<string, unknown>\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n hint: {\n /** Wrap the current block into a hint container (input rule: `!! ` + space). */\n setHint: (variant?: HintVariant) => ReturnType\n toggleHint: () => ReturnType\n }\n }\n}\n\n/**\n * Slite-style Hint block: a callout container that holds any block content.\n * Trigger: type `!!` followed by a space at the start of a line.\n */\nexport const Hint = Node.create<HintOptions>({\n name: 'hint',\n group: 'block',\n content: 'block+',\n defining: true,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n addAttributes() {\n return {\n variant: {\n default: 'info' as HintVariant,\n parseHTML: element => (element.getAttribute('data-variant') as HintVariant) || 'info',\n renderHTML: attributes => ({ 'data-variant': String(attributes.variant) }),\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'div[data-type=\"hint\"]' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['div', mergeAttributes({ 'data-type': 'hint' }, this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n setHint: (variant: HintVariant = 'info') => ({ commands }) => commands.wrapIn(this.name, { variant }),\n toggleHint: () => ({ commands }) => commands.toggleWrap(this.name),\n }\n },\n\n addInputRules() {\n return [\n wrappingInputRule({\n find: /^(!{2}) $/,\n type: this.type,\n keepMarks: true,\n keepAttributes: true,\n }),\n ]\n },\n})\n","import { Node, mergeAttributes, InputRule } from '@tiptap/core'\nimport { TextSelection } from '@tiptap/pm/state'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\nexport interface CollapsibleOptions {\n HTMLAttributes: Record<string, unknown>\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n collapsible: {\n /** Replace the current empty paragraph with a collapsible block (input rule: `>>` + space). */\n insertCollapsible: () => ReturnType\n }\n }\n}\n\nfunction collapsibleJSON(): Record<string, unknown> {\n return {\n type: 'collapsible',\n attrs: { open: true },\n content: [\n { type: 'collapsibleSummary' },\n {\n type: 'collapsibleContent',\n content: [{ type: 'paragraph' }],\n },\n ],\n }\n}\n\n/**\n * Slite-style Collapsible block: always-visible summary line + collapsible content,\n * nested blocks allowed. Trigger: type `>>` followed by a space on an empty line.\n */\nexport const Collapsible = Node.create<CollapsibleOptions>({\n name: 'collapsible',\n group: 'block',\n content: 'collapsibleSummary collapsibleContent',\n defining: true,\n isolating: true,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n addAttributes() {\n return {\n open: {\n default: true,\n parseHTML: element => element.getAttribute('data-open') !== 'false',\n renderHTML: attributes => ({ 'data-open': String(attributes.open) }),\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'div[data-type=\"collapsible\"]' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['div', mergeAttributes({ 'data-type': 'collapsible' }, this.options.HTMLAttributes, HTMLAttributes), 0]\n },\n\n addCommands() {\n return {\n insertCollapsible: () => ({ state, chain }) => {\n const { $from } = state.selection\n if ($from.parent.type.name !== 'paragraph') {\n return false\n }\n const from = $from.before()\n const to = $from.after()\n return chain()\n .insertContentAt({ from, to }, collapsibleJSON())\n .command(({ tr, dispatch }) => {\n if (dispatch) {\n tr.setSelection(TextSelection.near(tr.doc.resolve(from + 2)))\n }\n return true\n })\n .run()\n },\n }\n },\n\n addInputRules() {\n return [\n new InputRule({\n find: /^(>{2}) $/,\n handler: ({ state, range, chain }) => {\n const $from = state.doc.resolve(range.from)\n if ($from.parent.type.name !== 'paragraph') {\n return\n }\n const from = $from.before()\n const to = $from.after()\n chain()\n .insertContentAt({ from, to }, collapsibleJSON())\n .command(({ tr, dispatch }) => {\n if (dispatch) {\n tr.setSelection(TextSelection.near(tr.doc.resolve(from + 2)))\n }\n return true\n })\n .run()\n },\n }),\n ]\n },\n\n addProseMirrorPlugins() {\n const nodeName = this.name\n return [\n new Plugin({\n key: new PluginKey('tesseraCollapsibleToggle'),\n props: {\n // Click on the summary toggles open/closed; collapsed state survives reload\n // because it is a node attribute, not CSS state.\n handleClickOn: (view, _pos, node, nodePos, event) => {\n if (node.type.name !== nodeName) {\n return false\n }\n const target = event.target as HTMLElement | null\n if (!target?.closest('[data-type=\"collapsible-summary\"]')) {\n return false\n }\n view.dispatch(\n view.state.tr.setNodeMarkup(nodePos, undefined, {\n ...node.attrs,\n open: !node.attrs.open,\n }),\n )\n return true\n },\n },\n }),\n ]\n },\n})\n\nexport const CollapsibleSummary = Node.create({\n name: 'collapsibleSummary',\n group: '',\n content: 'inline*',\n defining: true,\n\n parseHTML() {\n return [{ tag: 'div[data-type=\"collapsible-summary\"]' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['div', mergeAttributes({ 'data-type': 'collapsible-summary' }, HTMLAttributes), 0]\n },\n})\n\nexport const CollapsibleContent = Node.create({\n name: 'collapsibleContent',\n group: '',\n content: 'block+',\n\n parseHTML() {\n return [{ tag: 'div[data-type=\"collapsible-content\"]' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['div', mergeAttributes({ 'data-type': 'collapsible-content' }, HTMLAttributes), 0]\n },\n})\n","import { Node, mergeAttributes } from '@tiptap/core'\n\nexport type ImageAlign = 'left' | 'center' | 'full'\n\nexport interface ImageBlockOptions {\n HTMLAttributes: Record<string, unknown>\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n imageBlock: {\n setImage: (options: {\n src: string\n alt?: string\n title?: string\n width?: number\n align?: ImageAlign\n }) => ReturnType\n }\n }\n}\n\n/**\n * Block-level image with width + alignment attributes. Binary data goes\n * through the injected UploadService; this node only stores the resulting URL.\n */\nexport const ImageBlock = Node.create<ImageBlockOptions>({\n name: 'imageBlock',\n inline: false,\n group: 'block',\n draggable: true,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n addAttributes() {\n return {\n src: { default: null },\n alt: { default: null },\n title: { default: null },\n width: { default: null },\n align: { default: 'center' as ImageAlign },\n }\n },\n\n parseHTML() {\n return [\n { tag: 'img[data-type=\"tessera-image\"]' },\n // plain <img> pasted from outside becomes a block image\n { tag: 'img[src]:not([data-type])' },\n ]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n const style = node.attrs.width ? `width: ${Number(node.attrs.width)}px` : undefined\n return [\n 'img',\n mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {\n 'data-type': 'tessera-image',\n 'data-align': String(node.attrs.align),\n style,\n }),\n ]\n },\n\n addCommands() {\n return {\n setImage:\n options =>\n ({ commands }) =>\n commands.insertContent({ type: this.name, attrs: options }),\n }\n },\n})\n","import type { Node as PMNode } from '@tiptap/pm/model'\nimport type { EditorState } from '@tiptap/pm/state'\nimport { Table, TableRow, TableCell, TableHeader } from '@tiptap/extension-table'\n\n/**\n * Typed-column table (v1.1 quality focus — Slite's worst-reviewed feature is\n * our opportunity). Column kinds live on the table node (`types`, indexed by\n * column position); cell values for non-text kinds live on the cell attr\n * `value`. Text columns keep rich inline content in the cell itself.\n *\n * Deliberately NOT supported (per Slite teardown §3.6): cell merging and\n * in-cell calculations.\n */\n\nexport type TableColumnKind =\n | 'text'\n | 'checkbox'\n | 'select'\n | 'multiSelect'\n | 'number'\n | 'date'\n | 'link'\n\nexport const TABLE_COLUMN_KINDS: TableColumnKind[] = [\n 'text',\n 'checkbox',\n 'select',\n 'multiSelect',\n 'number',\n 'date',\n 'link',\n]\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n tesseraTable: {\n /** Insert a typed table. Kinds default to `text` for every column. */\n insertTableTyped: (options?: { rows?: number; cols?: number; withHeaderRow?: boolean }) => ReturnType\n /** Change the kind of column `index` (0-based). */\n setColumnType: (index: number, kind: TableColumnKind) => ReturnType\n /** Stable-sort body rows by column `index`. */\n sortTableByColumn: (index: number, direction: 'asc' | 'desc') => ReturnType\n }\n }\n}\n\n/** CSV of the table containing the caret (utility, not a command). */\nexport function tableToCsvAt(editor: import('@tiptap/core').Editor): string | null {\n const table = locateTable(editor.state)\n return table ? tableNodeToCsv(table.node) : null\n}\n\nfunction locateTable(state: EditorState): { pos: number; node: PMNode } | null {\n const { $from } = state.selection\n for (let depth = $from.depth; depth > 0; depth--) {\n const node = $from.node(depth)\n if (node.type.name === 'table') {\n return { pos: $from.before(depth), node }\n }\n }\n return null\n}\n\nfunction columnCount(table: PMNode): number {\n const firstRow = table.content.firstChild\n return firstRow ? firstRow.childCount : 0\n}\n\nexport function normalizeTypes(types: unknown, cols: number): TableColumnKind[] {\n const list = Array.isArray(types) ? ([...types] as TableColumnKind[]) : []\n while (list.length < cols) {\n list.push('text')\n }\n return list.slice(0, cols)\n}\n\nfunction cellSortValue(row: PMNode, index: number, kind: TableColumnKind): string | number | boolean | null {\n const cell = row.maybeChild(index)\n if (!cell) {\n return null\n }\n const value = cell.attrs.value as unknown\n switch (kind) {\n case 'checkbox':\n return value === true || value === 'true'\n case 'number': {\n if (typeof value === 'number') {\n return value\n }\n const parsed = Number(String(value ?? cell.textContent).trim())\n return Number.isFinite(parsed) ? parsed : null\n }\n case 'date':\n return typeof value === 'string' && value ? value : null\n case 'select':\n return Array.isArray(value) ? ((value as string[])[0] ?? null) : ((value as string) ?? null)\n case 'multiSelect':\n return Array.isArray(value) ? [...(value as string[])].sort().join(' ‧ ') : null\n default:\n return cell.textContent.trim() || null\n }\n}\n\nfunction csvEscape(text: string): string {\n if (/[\",\\n]/.test(text)) {\n return `\"${text.replace(/\"/g, '\"\"')}\"`\n }\n return text\n}\n\n/** Serialize a table node to CSV (text form of typed values). */\nexport function tableNodeToCsv(table: PMNode): string {\n const types = normalizeTypes(table.attrs.types, columnCount(table))\n const lines: string[] = []\n table.forEach(row => {\n const isHeaderRow = row.content.firstChild?.type.name === 'tableHeader'\n const cells: string[] = []\n row.forEach((cell, _offset, index) => {\n // header cells are labels — always plain text regardless of column kind\n const kind = isHeaderRow ? 'text' : (types[index] ?? 'text')\n const value = cell.attrs.value as unknown\n let text: string\n switch (kind) {\n case 'checkbox':\n text = value === true || value === 'true' ? '✔' : ''\n break\n case 'select':\n case 'multiSelect':\n text = Array.isArray(value) ? (value as string[]).join(' / ') : String(value ?? '')\n break\n case 'date':\n text = String(value ?? '')\n break\n case 'number':\n case 'link':\n text = value === null || value === undefined ? cell.textContent : String(value)\n break\n default:\n text = cell.textContent\n }\n cells.push(csvEscape(text.trim()))\n })\n lines.push(cells.join(','))\n })\n return lines.join('\\n')\n}\n\nexport const AiTable = Table.extend({\n name: 'table',\n\n addAttributes() {\n return {\n ...this.parent?.(),\n types: {\n default: [] as TableColumnKind[],\n parseHTML: element => {\n try {\n const raw = element.getAttribute('data-types')\n return raw ? (JSON.parse(raw) as TableColumnKind[]) : []\n } catch {\n return []\n }\n },\n renderHTML: attributes => ({\n 'data-types': JSON.stringify(attributes.types ?? []),\n }),\n },\n freezeFirstCol: {\n default: true,\n parseHTML: element => element.getAttribute('data-freeze-first') !== 'false',\n renderHTML: attributes => ({ 'data-freeze-first': String(attributes.freezeFirstCol) }),\n },\n }\n },\n\n addCommands() {\n const parent = this.parent?.() ?? {}\n return {\n ...parent,\n insertTableTyped:\n (options = {}) =>\n ({ commands }) =>\n commands.insertTable({\n rows: options.rows ?? 3,\n cols: options.cols ?? 3,\n withHeaderRow: options.withHeaderRow ?? true,\n }),\n setColumnType:\n (index: number, kind: TableColumnKind) =>\n ({ state, dispatch, tr }) => {\n const table = locateTable(state)\n if (!table || index < 0 || index >= columnCount(table.node)) {\n return false\n }\n const types = normalizeTypes(table.node.attrs.types, columnCount(table.node))\n types[index] = kind\n if (dispatch) {\n tr.setNodeMarkup(table.pos, undefined, { ...table.node.attrs, types })\n dispatch(tr)\n }\n return true\n },\n sortTableByColumn:\n (index: number, direction: 'asc' | 'desc') =>\n ({ state, dispatch, tr }) => {\n const table = locateTable(state)\n if (!table) {\n return false\n }\n const rows: PMNode[] = []\n table.node.forEach(row => rows.push(row))\n const hasHeader = rows.length > 0 && rows[0]!.content.firstChild?.type.name === 'tableHeader'\n const header = hasHeader ? rows[0]! : null\n const body = hasHeader ? rows.slice(1) : rows.slice()\n if (body.length === 0 || index >= columnCount(table.node)) {\n return false\n }\n const types = normalizeTypes(table.node.attrs.types, columnCount(table.node))\n const kind = types[index] ?? 'text'\n const dir = direction === 'asc' ? 1 : -1\n const sorted = [...body].sort((a, b) => {\n const va = cellSortValue(a, index, kind)\n const vb = cellSortValue(b, index, kind)\n if (va === vb) {\n return 0\n }\n if (va === null) {\n return 1\n }\n if (vb === null) {\n return -1\n }\n return va < vb ? -dir : dir\n })\n const start = table.pos + 1 + (header ? header.nodeSize : 0)\n const end = table.pos + table.node.nodeSize - 1\n if (dispatch) {\n tr.replaceWith(start, end, sorted)\n dispatch(tr)\n }\n return true\n },\n }\n },\n})\n\nexport { TableRow as AiTableRow }\n\nfunction valueAttr() {\n return {\n default: null,\n parseHTML: (element: HTMLElement) => {\n const raw = element.getAttribute('data-value')\n if (raw === null || raw === '') {\n return null\n }\n try {\n return JSON.parse(raw)\n } catch {\n return raw\n }\n },\n renderHTML: (attributes: Record<string, unknown>) => ({\n 'data-value':\n attributes.value === null || attributes.value === undefined ? '' : JSON.stringify(attributes.value),\n }),\n }\n}\n\nexport const AiTableCell = TableCell.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n value: valueAttr(),\n }\n },\n})\n\nexport const AiTableHeader = TableHeader.extend({\n addAttributes() {\n return {\n ...this.parent?.(),\n value: valueAttr(),\n }\n },\n})\n","import { Node, mergeAttributes } from '@tiptap/core'\n\n/**\n * Sandboxed iframe embed (v1.1): default sandbox=\"\" — NO scripts, NO\n * same-origin. Hosts may opt into `allowScripts` per instance for app-like\n * embeds; allow-same-origin is never combined with allow-scripts.\n */\nexport const EmbedBlock = Node.create({\n name: 'embedBlock',\n group: 'block',\n atom: true,\n draggable: true,\n\n addAttributes() {\n return {\n src: { default: null },\n title: { default: null },\n height: { default: 360 },\n allowScripts: { default: false },\n }\n },\n\n parseHTML() {\n return [{ tag: 'div[data-type=\"tessera-embed\"]' }]\n },\n\n renderHTML({ node, HTMLAttributes }) {\n return [\n 'div',\n mergeAttributes(HTMLAttributes, {\n 'data-type': 'tessera-embed',\n 'data-src': String(node.attrs.src ?? ''),\n 'data-height': String(node.attrs.height),\n 'data-allow-scripts': String(node.attrs.allowScripts),\n }),\n ]\n },\n\n addCommands() {\n return {\n insertEmbed:\n (attrs: { src: string; height?: number; allowScripts?: boolean }) =>\n ({ commands }) =>\n commands.insertContent({ type: this.name, attrs }),\n }\n },\n})\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n embedBlock: {\n insertEmbed: (attrs: { src: string; height?: number; allowScripts?: boolean }) => ReturnType\n }\n }\n}\n","import { Node, mergeAttributes } from '@tiptap/core'\n\n/**\n * Table-of-contents block (v1.1, Slite /outline): renders the document\n * outline (H1–H4) with anchor jumps. The list itself is derived state — the\n * node stores nothing, so it can never go stale in the canonical JSON.\n */\nexport const TocBlock = Node.create({\n name: 'tocBlock',\n group: 'block',\n atom: true,\n draggable: true,\n\n parseHTML() {\n return [{ tag: 'div[data-type=\"tessera-toc\"]' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'tessera-toc' })]\n },\n\n addCommands() {\n return {\n insertToc:\n () =>\n ({ commands }) =>\n commands.insertContent({ type: this.name }),\n }\n },\n})\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n tocBlock: {\n insertToc: () => ReturnType\n }\n }\n}\n","import { Mark, mergeAttributes } from '@tiptap/core'\n\n/**\n * Attribution mark for AI-written content — the Slite-style \"human vs Agent\"\n * provenance signal. Lifecycle:\n *\n * pending: true → suggestion awaiting Accept / Reject (styled prominently)\n * pending: false → accepted AI content (subtle permanent attribution)\n *\n * Reject deletes the marked range; Accept flips `pending` and stamps metadata.\n */\nexport interface AiAttributionOptions {\n HTMLAttributes: Record<string, unknown>\n}\n\nexport const AiAttribution = Mark.create<AiAttributionOptions>({\n name: 'aiAttribution',\n\n inclusive: false,\n\n addOptions() {\n return {\n HTMLAttributes: {},\n }\n },\n\n addAttributes() {\n return {\n pending: {\n default: true,\n parseHTML: element => element.getAttribute('data-pending') !== 'false',\n renderHTML: attributes => ({ 'data-pending': String(attributes.pending) }),\n },\n action: {\n default: null,\n parseHTML: element => element.getAttribute('data-action'),\n renderHTML: attributes => (attributes.action ? { 'data-action': String(attributes.action) } : {}),\n },\n agent: {\n default: 'ai',\n parseHTML: element => element.getAttribute('data-agent') ?? 'ai',\n renderHTML: attributes => ({ 'data-agent': String(attributes.agent) }),\n },\n ts: { default: null },\n }\n },\n\n parseHTML() {\n return [{ tag: 'span[data-ai]' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['span', mergeAttributes({ 'data-ai': '' }, this.options.HTMLAttributes, HTMLAttributes)]\n },\n})\n","import { Mark, Extension, mergeAttributes } from '@tiptap/core'\nimport { TextSelection } from '@tiptap/pm/state'\n\n/**\n * Inline comment mark (v1.1): anchors a comment thread to a text range.\n * Thread data lives in the injected CommentStore; the mark only carries the\n * thread id + resolved state so the doc stays host-persistable.\n */\nexport const CommentMark = Mark.create({\n name: 'comment',\n\n inclusive: false,\n\n addAttributes() {\n return {\n threadId: {\n default: null,\n parseHTML: element => element.getAttribute('data-thread-id'),\n renderHTML: attributes => ({ 'data-thread-id': String(attributes.threadId ?? '') }),\n },\n resolved: {\n default: false,\n parseHTML: element => element.getAttribute('data-resolved') === 'true',\n renderHTML: attributes => ({ 'data-resolved': String(attributes.resolved) }),\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'span[data-thread-id]' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['span', mergeAttributes({ 'data-comment': '' }, HTMLAttributes)]\n },\n})\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n tesseraComment: {\n /** Attach a comment thread id to the current selection. */\n addCommentThread: (threadId: string) => ReturnType\n /** Flip resolved for every mark of `threadId`. */\n setCommentResolved: (threadId: string, resolved: boolean) => ReturnType\n /** Remove all marks of `threadId` (thread deleted). */\n removeCommentThread: (threadId: string) => ReturnType\n /** Select the next comment range from the caret (wraps around). */\n focusNextCommentThread: () => ReturnType\n }\n }\n}\n\n/** All comment thread ranges in document order. */\nexport function listCommentRanges(state: import('@tiptap/pm/state').EditorState): { threadId: string; from: number; to: number; resolved: boolean }[] {\n const seen = new Map<string, { threadId: string; from: number; to: number; resolved: boolean }>()\n state.doc.descendants((node, pos) => {\n for (const m of node.marks) {\n if (m.type.name === 'comment' && typeof m.attrs.threadId === 'string') {\n const from = pos\n const to = pos + node.nodeSize\n const existing = seen.get(m.attrs.threadId)\n if (!existing) {\n seen.set(m.attrs.threadId, { threadId: m.attrs.threadId, from, to, resolved: Boolean(m.attrs.resolved) })\n } else {\n existing.to = Math.max(existing.to, to)\n existing.resolved = existing.resolved && Boolean(m.attrs.resolved)\n }\n }\n }\n return true\n })\n return [...seen.values()].sort((a, b) => a.from - b.from)\n}\n\nexport const CommentCommands = Extension.create({\n name: 'tesseraCommentCommands',\n\n addCommands() {\n return {\n addCommentThread:\n (threadId: string) =>\n ({ commands }) =>\n commands.setMark('comment', { threadId, resolved: false }),\n setCommentResolved:\n (threadId: string, resolved: boolean) =>\n ({ state, tr, dispatch }) => {\n let touched = false\n state.doc.descendants((node, pos) => {\n node.marks\n .filter(m => m.type.name === 'comment' && m.attrs.threadId === threadId)\n .forEach(m => {\n const next = state.schema.marks.comment!.create({ ...m.attrs, resolved })\n tr.removeMark(pos, pos + node.nodeSize, m)\n tr.addMark(pos, pos + node.nodeSize, next)\n touched = true\n })\n return true\n })\n if (touched && dispatch) {\n dispatch(tr)\n }\n return touched\n },\n removeCommentThread:\n (threadId: string) =>\n ({ state, tr, dispatch }) => {\n let touched = false\n state.doc.descendants((node, pos) => {\n if (node.marks.some(m => m.type.name === 'comment' && m.attrs.threadId === threadId)) {\n tr.removeMark(pos, pos + node.nodeSize, state.schema.marks.comment!)\n touched = true\n }\n return true\n })\n if (touched && dispatch) {\n dispatch(tr)\n }\n return touched\n },\n focusNextCommentThread:\n () =>\n ({ state, tr, dispatch }) => {\n const ranges = listCommentRanges(state)\n if (ranges.length === 0) {\n return false\n }\n const anchor = state.selection.from\n const next = ranges.find(r => r.from > anchor) ?? ranges[0]!\n if (dispatch) {\n tr.setSelection(TextSelection.create(state.doc, next.from, next.to))\n dispatch(tr)\n }\n return true\n },\n }\n },\n})\n","import { Mark, mergeAttributes, Extension } from '@tiptap/core'\n\n/**\n * Placeholder mark (v1.1, Slite's 占位符): dashed-underline token marking a\n * spot to fill in later — text / person / date / doc-link. ⌘⌥P toggles it on\n * a selection; slash items insert ready-made tokens.\n */\nexport type PlaceholderKind = 'text' | 'person' | 'date' | 'doc'\n\nexport const PlaceholderMark = Mark.create({\n name: 'tesseraPlaceholder',\n\n addAttributes() {\n return {\n kind: {\n default: 'text' as PlaceholderKind,\n parseHTML: element => (element.getAttribute('data-kind') as PlaceholderKind) ?? 'text',\n renderHTML: attributes => ({ 'data-kind': String(attributes.kind) }),\n },\n }\n },\n\n parseHTML() {\n return [{ tag: 'span[data-type=\"tessera-placeholder\"]' }]\n },\n\n renderHTML({ HTMLAttributes }) {\n return ['span', mergeAttributes({ 'data-type': 'tessera-placeholder' }, HTMLAttributes)]\n },\n})\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n tesseraPlaceholder: {\n togglePlaceholderMark: (kind?: PlaceholderKind) => ReturnType\n /** Insert a placeholder token at the caret (selection replaced). */\n insertPlaceholderToken: (kind: PlaceholderKind, label: string) => ReturnType\n }\n }\n}\n\nexport const PlaceholderCommands = Extension.create({\n name: 'tesseraPlaceholderCommands',\n\n addCommands() {\n return {\n togglePlaceholderMark:\n (kind: PlaceholderKind = 'text') =>\n ({ commands }) =>\n commands.toggleMark('tesseraPlaceholder', { kind }),\n insertPlaceholderToken:\n (kind: PlaceholderKind, label: string) =>\n ({ chain }) =>\n chain()\n .insertContent({\n type: 'text',\n text: label,\n marks: [{ type: 'tesseraPlaceholder', attrs: { kind } }],\n })\n .run(),\n }\n },\n})\n","import { Extension, wrappingInputRule, markInputRule } from '@tiptap/core'\n\n/**\n * Tessera-specific input rules beyond the StarterKit defaults:\n * `[] ` + typing → task list (mirrors Slite's trigger)\n * `::text::` → highlight mark\n */\nexport const TesseraInputRules = Extension.create({\n name: 'tesseraInputRules',\n\n addInputRules() {\n const taskList = this.editor.schema.nodes.taskList\n const highlight = this.editor.schema.marks.highlight\n const rules = []\n\n if (taskList) {\n rules.push(\n wrappingInputRule({\n find: /^\\[\\] $/,\n type: taskList,\n }),\n )\n }\n if (highlight) {\n rules.push(\n markInputRule({\n find: /::([^:]+)::$/,\n type: highlight,\n }),\n )\n }\n return rules\n },\n})\n","import { Extension } from '@tiptap/core'\nimport type { Editor } from '@tiptap/core'\nimport { TextSelection } from '@tiptap/pm/state'\nimport type { EditorState, Transaction } from '@tiptap/pm/state'\n\n/**\n * The Tessera keyboard map (acceptance checklist §3). Panel-opening shortcuts\n * emit `tessera:*` events that the binding's UI layer listens to, keeping this\n * extension UI-free.\n */\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n tesseraShortcuts: {\n /** Move the top-level block containing the caret up one position. */\n moveBlockUp: () => ReturnType\n /** Move the top-level block containing the caret down one position. */\n moveBlockDown: () => ReturnType\n }\n }\n interface EditorEvents {\n 'tessera:formatPanel': { kind: 'color' | 'highlight' }\n 'tessera:linkPanel': Record<string, never>\n 'tessera:findPanel': Record<string, never>\n 'tessera:insertImage': Record<string, never>\n 'tessera:askPanel': Record<string, never>\n 'tessera:historyPanel': Record<string, never>\n 'tessera:commentPanel': Record<string, never>\n }\n}\n\nexport const TesseraShortcuts = Extension.create({\n name: 'tesseraShortcuts',\n priority: 500,\n\n addCommands() {\n return {\n moveBlockUp:\n () =>\n ({ state, tr, dispatch }) =>\n swapBlock(state, tr, dispatch, -1),\n moveBlockDown:\n () =>\n ({ state, tr, dispatch }) =>\n swapBlock(state, tr, dispatch, 1),\n }\n },\n\n addKeyboardShortcuts() {\n return {\n 'Mod-Shift-1': () => this.editor.commands.toggleHeading({ level: 1 }),\n 'Mod-Shift-2': () => this.editor.commands.toggleHeading({ level: 2 }),\n 'Mod-Shift-3': () => this.editor.commands.toggleHeading({ level: 3 }),\n 'Mod-Shift-4': () => this.editor.commands.toggleHeading({ level: 4 }),\n 'Mod-Shift-7': () => this.editor.commands.toggleOrderedList(),\n 'Mod-Shift-8': () => this.editor.commands.toggleBulletList(),\n 'Mod-Shift-c': () => this.editor.commands.toggleTaskList(),\n 'Mod-Alt-h': () => this.editor.commands.toggleHint(),\n 'Mod-j': () => this.editor.commands.toggleCode(),\n 'Mod-Shift-9': () => this.editor.commands.toggleCodeBlock(),\n 'Mod-Shift-.': () => this.editor.commands.toggleBlockquote(),\n 'Mod-e': () => {\n this.editor.emit('tessera:formatPanel', { kind: 'color' })\n return true\n },\n 'Mod-k': () => {\n this.editor.emit('tessera:linkPanel', {})\n return true\n },\n 'Mod-f': () => {\n this.editor.emit('tessera:findPanel', {})\n return true\n },\n 'Mod-Shift-k': () => {\n this.editor.emit('tessera:askPanel', {})\n return true\n },\n 'Mod-Alt-s': () => this.editor.commands.insertTableTyped({ withHeaderRow: true }),\n 'Mod-Alt-t': () => this.editor.commands.insertTableTyped({ withHeaderRow: false }),\n 'Mod-Alt-p': () => this.editor.commands.togglePlaceholderMark('text'),\n 'Mod-Alt-m': () => {\n this.editor.emit('tessera:commentPanel', {})\n return true\n },\n 'Alt-ArrowUp': () => this.editor.commands.moveBlockUp(),\n 'Alt-ArrowDown': () => this.editor.commands.moveBlockDown(),\n }\n },\n})\n\ntype Dispatch = ((args?: unknown) => void) | undefined\n\nfunction swapBlock(state: EditorState, tr: Transaction, dispatch: Dispatch, direction: -1 | 1): boolean {\n const { $from } = state.selection\n if ($from.depth < 1) {\n return false\n }\n const index = $from.index(0)\n const other = index + direction\n if (other < 0 || other >= state.doc.childCount) {\n return false\n }\n const node = state.doc.child(index)\n const otherNode = state.doc.child(other)\n const pos = $from.before(1)\n const nodeStart = direction === -1 ? pos - otherNode.nodeSize : pos\n const rangeEnd = nodeStart + otherNode.nodeSize + node.nodeSize\n if (dispatch) {\n const content = direction === -1 ? [node, otherNode] : [otherNode, node]\n tr.replaceWith(nodeStart, rangeEnd, content)\n const anchor = tr.mapping.map(state.selection.anchor)\n tr.setSelection(TextSelection.near(tr.doc.resolve(Math.min(anchor, tr.doc.content.size))))\n dispatch(tr)\n }\n return true\n}\n\nexport type { Editor }\n","import { Extension } from '@tiptap/core'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { Decoration, DecorationSet } from '@tiptap/pm/view'\n\n/**\n * Find & replace (acceptance §3: ⌘F). The core plugin owns match computation\n * and decorations; the binding renders the panel and calls these commands.\n */\n\nexport interface FindMatch {\n from: number\n to: number\n}\n\nexport interface FindReplaceState {\n query: string\n matches: FindMatch[]\n active: number\n visible: boolean\n}\n\ninterface FindReplaceStorage extends FindReplaceState {}\n\nexport const findReplaceKey = new PluginKey<FindReplaceState>('tesseraFindReplace')\n\nfunction computeMatches(doc: import('@tiptap/pm/model').Node, query: string): FindMatch[] {\n if (!query) {\n return []\n }\n const matches: FindMatch[] = []\n const needle = query.toLowerCase()\n doc.descendants((node, pos) => {\n if (node.isText && node.text) {\n const haystack = node.text.toLowerCase()\n let idx = haystack.indexOf(needle)\n while (idx !== -1) {\n matches.push({ from: pos + idx, to: pos + idx + needle.length })\n idx = haystack.indexOf(needle, idx + needle.length)\n }\n }\n return true\n })\n return matches\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n findReplace: {\n openFindPanel: () => ReturnType\n closeFindPanel: () => ReturnType\n setFindQuery: (query: string) => ReturnType\n findNext: () => ReturnType\n findPrev: () => ReturnType\n replaceCurrent: (replacement: string) => ReturnType\n replaceAll: (replacement: string) => ReturnType\n }\n }\n}\n\nexport const TesseraFindReplace = Extension.create<Record<string, never>, FindReplaceStorage>({\n name: 'tesseraFindReplace',\n\n addStorage() {\n return {\n query: '',\n matches: [],\n active: 0,\n visible: false,\n }\n },\n\n addCommands() {\n return {\n openFindPanel:\n () =>\n ({ tr, dispatch }) => {\n if (dispatch) {\n tr.setMeta(findReplaceKey, { type: 'open' })\n dispatch(tr)\n }\n return true\n },\n closeFindPanel:\n () =>\n ({ tr, dispatch }) => {\n if (dispatch) {\n tr.setMeta(findReplaceKey, { type: 'close' })\n dispatch(tr)\n }\n return true\n },\n setFindQuery:\n (query: string) =>\n ({ tr, dispatch }) => {\n if (dispatch) {\n tr.setMeta(findReplaceKey, { type: 'query', query })\n dispatch(tr)\n }\n return true\n },\n findNext:\n () =>\n ({ tr, state, dispatch }) => {\n const s = findReplaceKey.getState(state)\n if (!s || s.matches.length === 0) {\n return false\n }\n if (dispatch) {\n tr.setMeta(findReplaceKey, { type: 'active', active: (s.active + 1) % s.matches.length })\n dispatch(tr)\n }\n return true\n },\n findPrev:\n () =>\n ({ tr, state, dispatch }) => {\n const s = findReplaceKey.getState(state)\n if (!s || s.matches.length === 0) {\n return false\n }\n if (dispatch) {\n tr.setMeta(findReplaceKey, {\n type: 'active',\n active: (s.active - 1 + s.matches.length) % s.matches.length,\n })\n dispatch(tr)\n }\n return true\n },\n replaceCurrent:\n (replacement: string) =>\n ({ state, tr, dispatch }) => {\n const s = findReplaceKey.getState(state)\n if (!s || s.matches.length === 0) {\n return false\n }\n const m = s.matches[s.active]\n if (!m) {\n return false\n }\n if (dispatch) {\n tr.insertText(replacement, m.from, m.to)\n tr.setMeta(findReplaceKey, { type: 'requery' })\n dispatch(tr)\n }\n return true\n },\n replaceAll:\n (replacement: string) =>\n ({ state, tr, dispatch }) => {\n const s = findReplaceKey.getState(state)\n if (!s || s.matches.length === 0) {\n return false\n }\n if (dispatch) {\n for (let i = s.matches.length - 1; i >= 0; i--) {\n const m = s.matches[i]\n tr.insertText(replacement, m.from, m.to)\n }\n tr.setMeta(findReplaceKey, { type: 'requery' })\n dispatch(tr)\n }\n return true\n },\n }\n },\n\n addProseMirrorPlugins() {\n return [\n new Plugin<FindReplaceState>({\n key: findReplaceKey,\n state: {\n init: (): FindReplaceState => ({ query: '', matches: [], active: 0, visible: false }),\n apply: (tr, prev, _oldState, newState) => {\n const meta = tr.getMeta(findReplaceKey) as\n | { type: 'open' | 'close' | 'requery' }\n | { type: 'query'; query: string }\n | { type: 'active'; active: number }\n | undefined\n let next: FindReplaceState | null = null\n if (meta?.type === 'open') {\n next = { ...prev, visible: true }\n } else if (meta?.type === 'close') {\n next = { ...prev, visible: false, matches: [], query: '', active: 0 }\n } else if (meta?.type === 'query') {\n const matches = computeMatches(newState.doc, meta.query)\n next = { query: meta.query, matches, active: 0, visible: true }\n } else if (meta?.type === 'active') {\n next = { ...prev, active: meta.active }\n } else if (meta?.type === 'requery') {\n next = { ...prev, matches: [], active: 0 }\n }\n\n if (!next) {\n // doc changed outside our commands: recompute if a query is live\n if (prev.query && prev.visible && tr.docChanged) {\n const matches = computeMatches(newState.doc, prev.query)\n return { ...prev, matches, active: 0 }\n }\n return prev\n }\n // mirror state into editor storage for reactive UI\n this.storage.query = next.query\n this.storage.matches = next.matches\n this.storage.active = next.active\n this.storage.visible = next.visible\n return next\n },\n },\n props: {\n decorations(state) {\n const s = findReplaceKey.getState(state)\n if (!s || !s.visible || s.matches.length === 0) {\n return DecorationSet.empty\n }\n const decorations = s.matches.map((m, i) =>\n Decoration.inline(m.from, m.to, {\n class: i === s.active ? 'tessera-find-match tessera-find-match--active' : 'tessera-find-match',\n }),\n )\n return DecorationSet.create(state.doc, decorations)\n },\n },\n }),\n ]\n },\n})\n\nexport type { FindReplaceStorage }\n","import { Extension } from '@tiptap/core'\nimport type { Editor, Range } from '@tiptap/core'\nimport Suggestion from '@tiptap/suggestion'\nimport type { SuggestionOptions } from '@tiptap/suggestion'\nimport { PluginKey } from '@tiptap/pm/state'\nimport { createTesseraT, type TesseraLocale, type TesseraTranslator } from '../i18n'\n\n/**\n * Slash menu (acceptance §1): framework-neutral extension built on\n * @tiptap/suggestion. The binding injects a `render` implementation; items are\n * data (title/description/shortcut/command) so React or Vue can render them.\n */\n\nexport interface SlashMenuItem {\n id: string\n group: 'basic' | 'advanced' | 'ai'\n title: string\n description?: string\n /** display-only hint, e.g. \"⌘⇧9\" */\n shortcut?: string\n keywords?: string[]\n command: (props: { editor: Editor; range: Range }) => void\n}\n\nexport type SlashRenderFactory = SuggestionOptions<SlashMenuItem>['render']\n\nexport interface SlashMenuOptions {\n locale: TesseraLocale\n /** extra host items (e.g. AI actions registered by @tessera-editor/ai) */\n extraItems?: (ctx: { editor: Editor; t: TesseraTranslator }) => SlashMenuItem[]\n includeAiItems?: boolean\n render?: SlashRenderFactory\n}\n\nfunction chainDelete(editor: Editor, range: Range) {\n return editor.chain().focus().deleteRange(range)\n}\n\n/** Default block items — mirrors the Slite slash palette for the M1 scope. */\nexport function defaultSlashItems(t: TesseraTranslator): SlashMenuItem[] {\n return [\n {\n id: 'text',\n group: 'basic',\n title: t('itemText'),\n description: t('itemTextDesc'),\n keywords: ['text', 'paragraph', '文本', '段落'],\n command: ({ editor, range }) => chainDelete(editor, range).setParagraph().run(),\n },\n {\n id: 'h1',\n group: 'basic',\n title: t('itemH1'),\n shortcut: '⌘⇧1',\n keywords: ['heading', 'title', '标题'],\n command: ({ editor, range }) => chainDelete(editor, range).toggleHeading({ level: 1 }).run(),\n },\n {\n id: 'h2',\n group: 'basic',\n title: t('itemH2'),\n shortcut: '⌘⇧2',\n keywords: ['heading', 'title', '标题'],\n command: ({ editor, range }) => chainDelete(editor, range).toggleHeading({ level: 2 }).run(),\n },\n {\n id: 'h3',\n group: 'basic',\n title: t('itemH3'),\n shortcut: '⌘⇧3',\n keywords: ['heading', 'title', '标题'],\n command: ({ editor, range }) => chainDelete(editor, range).toggleHeading({ level: 3 }).run(),\n },\n {\n id: 'h4',\n group: 'basic',\n title: t('itemH4'),\n shortcut: '⌘⇧4',\n keywords: ['heading', 'title', '标题'],\n command: ({ editor, range }) => chainDelete(editor, range).toggleHeading({ level: 4 }).run(),\n },\n {\n id: 'bulletList',\n group: 'basic',\n title: t('itemBullet'),\n description: t('itemBulletDesc'),\n shortcut: '⌘⇧8',\n keywords: ['bullet', 'list', 'unordered', '列表'],\n command: ({ editor, range }) => chainDelete(editor, range).toggleBulletList().run(),\n },\n {\n id: 'orderedList',\n group: 'basic',\n title: t('itemOrdered'),\n description: t('itemOrderedDesc'),\n shortcut: '⌘⇧7',\n keywords: ['ordered', 'list', 'numbered', '列表'],\n command: ({ editor, range }) => chainDelete(editor, range).toggleOrderedList().run(),\n },\n {\n id: 'taskList',\n group: 'basic',\n title: t('itemTask'),\n description: t('itemTaskDesc'),\n shortcut: '⌘⇧C',\n keywords: ['task', 'todo', 'checkbox', '任务', '清单'],\n command: ({ editor, range }) => chainDelete(editor, range).toggleTaskList().run(),\n },\n {\n id: 'quote',\n group: 'basic',\n title: t('itemQuote'),\n description: t('itemQuoteDesc'),\n shortcut: '⌘⇧.',\n keywords: ['quote', 'blockquote', '引用'],\n command: ({ editor, range }) => chainDelete(editor, range).toggleBlockquote().run(),\n },\n {\n id: 'codeBlock',\n group: 'advanced',\n title: t('itemCode'),\n description: t('itemCodeDesc'),\n shortcut: '⌘⇧9',\n keywords: ['code', '代码'],\n command: ({ editor, range }) => chainDelete(editor, range).toggleCodeBlock().run(),\n },\n {\n id: 'divider',\n group: 'advanced',\n title: t('itemDivider'),\n description: t('itemDividerDesc'),\n keywords: ['divider', 'hr', 'rule', '分割线'],\n command: ({ editor, range }) => chainDelete(editor, range).setHorizontalRule().run(),\n },\n {\n id: 'hint',\n group: 'advanced',\n title: t('itemHint'),\n description: t('itemHintDesc'),\n shortcut: '⌘⌥H',\n keywords: ['hint', 'callout', 'info', '提示'],\n command: ({ editor, range }) => chainDelete(editor, range).setHint().run(),\n },\n {\n id: 'collapsible',\n group: 'advanced',\n title: t('itemCollapsible'),\n description: t('itemCollapsibleDesc'),\n keywords: ['collapsible', 'fold', 'details', '折叠'],\n command: ({ editor, range }) => chainDelete(editor, range).insertCollapsible().run(),\n },\n {\n id: 'image',\n group: 'advanced',\n title: t('itemImage'),\n description: t('itemImageDesc'),\n keywords: ['image', 'picture', 'photo', '图片'],\n command: ({ editor, range }) => {\n // no file dialog in core — emit for the binding (host opens picker)\n chainDelete(editor, range).run()\n editor.emit('tessera:insertImage', {})\n },\n },\n {\n id: 'table',\n group: 'advanced',\n title: t('itemTable'),\n description: t('itemTableDesc'),\n shortcut: '⌘⌥S',\n keywords: ['table', '表格'],\n command: ({ editor, range }) => chainDelete(editor, range).insertTableTyped({ withHeaderRow: true }).run(),\n },\n {\n id: 'table-simple',\n group: 'advanced',\n title: t('itemTableSimple'),\n description: t('itemTableSimpleDesc'),\n shortcut: '⌘⌥T',\n keywords: ['table', 'simple', '表格'],\n command: ({ editor, range }) => chainDelete(editor, range).insertTableTyped({ withHeaderRow: false }).run(),\n },\n {\n id: 'embed',\n group: 'advanced',\n title: t('itemEmbed'),\n description: t('itemEmbedDesc'),\n keywords: ['embed', 'iframe', '嵌入'],\n command: ({ editor, range }) => chainDelete(editor, range).insertEmbed({ src: '' }).run(),\n },\n {\n id: 'toc',\n group: 'advanced',\n title: t('itemToc'),\n description: t('itemTocDesc'),\n keywords: ['toc', 'outline', '目录', '大纲'],\n command: ({ editor, range }) => chainDelete(editor, range).insertToc().run(),\n },\n {\n id: 'placeholder-person',\n group: 'advanced',\n title: t('placeholderPerson'),\n keywords: ['somebody', 'person', 'owner', '待填人'],\n command: ({ editor, range }) => chainDelete(editor, range).insertPlaceholderToken('person', t('placeholderPerson')).run(),\n },\n {\n id: 'placeholder-date',\n group: 'advanced',\n title: t('placeholderDate'),\n keywords: ['date', 'due', '待填日期'],\n command: ({ editor, range }) => chainDelete(editor, range).insertPlaceholderToken('date', t('placeholderDate')).run(),\n },\n {\n id: 'history',\n group: 'advanced',\n title: t('itemHistory'),\n keywords: ['history', 'version', 'snapshot', '历史', '版本'],\n command: ({ editor, range }) => {\n chainDelete(editor, range).run()\n editor.emit('tessera:historyPanel', {})\n },\n },\n ]\n}\n\nexport const SlashMenu = Extension.create<SlashMenuOptions>({\n name: 'tesseraSlashMenu',\n\n addOptions() {\n return {\n locale: 'zh-CN',\n extraItems: undefined,\n includeAiItems: false,\n render: undefined,\n }\n },\n\n addProseMirrorPlugins() {\n const editor = this.editor\n const options = this.options\n const t = createTesseraT(options.locale)\n\n const items = [\n ...defaultSlashItems(t),\n ...(options.extraItems?.({ editor, t }) ?? []),\n ]\n\n return [\n Suggestion({\n editor,\n pluginKey: new PluginKey('tesseraSlashMenu'),\n char: '/',\n startOfLine: true,\n items: ({ query }) => {\n const q = query.toLowerCase()\n if (!q) {\n return items\n }\n return items.filter(\n item =>\n item.title.toLowerCase().includes(q) ||\n item.id.toLowerCase().includes(q) ||\n item.keywords?.some(k => k.toLowerCase().includes(q)),\n )\n },\n command: ({ editor: e, range, props }) => {\n ;(props as SlashMenuItem).command({ editor: e, range })\n },\n render: options.render as SuggestionOptions<SlashMenuItem>['render'],\n }),\n ]\n },\n})\n","/**\n * Tessera i18n: zh-CN / en-US dictionaries for every UI string the component\n * family renders (menus, toolbars, panels, AI actions). Hosts may extend with\n * additional locales by supplying messages to the binding.\n */\n\nexport type TesseraLocale = 'zh-CN' | 'en-US'\n\nexport const tesseraMessages = {\n 'zh-CN': {\n // placeholder\n placeholderEmpty: \"输入 / 唤起菜单,或直接开始书写…\",\n // slash menu groups\n groupBasic: '基础块',\n groupAdvanced: '高级块',\n groupAi: 'AI',\n // slash items\n itemText: '文本',\n itemTextDesc: '普通段落',\n itemH1: '标题 1',\n itemH2: '标题 2',\n itemH3: '标题 3',\n itemH4: '标题 4',\n itemBullet: '无序列表',\n itemBulletDesc: '简单的项目符号列表',\n itemOrdered: '有序列表',\n itemOrderedDesc: '带编号的列表',\n itemTask: '任务清单',\n itemTaskDesc: '用复选框跟踪待办',\n itemQuote: '引用',\n itemQuoteDesc: '引用一段文字',\n itemCode: '代码块',\n itemCodeDesc: '带语法高亮的代码',\n itemDivider: '分割线',\n itemDividerDesc: '水平分割线',\n itemHint: '提示块',\n itemHintDesc: '醒目的信息/警告容器(!! + 空格)',\n itemCollapsible: '折叠块',\n itemCollapsibleDesc: '可折叠的内容区(>> + 空格)',\n itemImage: '图片',\n itemImageDesc: '上传或粘贴图片',\n itemImageUrl: '图片链接',\n // AI slash items\n itemSummarize: 'AI 摘要',\n itemSummarizeDesc: '为整篇文档生成 TL;DR',\n itemAsk: 'AI 问答',\n itemAskDesc: '针对当前文档提问',\n itemImprove: 'AI 改写',\n itemImproveDesc: '改写选中的文字',\n // selection toolbar\n tooltipBold: '加粗',\n tooltipItalic: '斜体',\n tooltipUnderline: '下划线',\n tooltipStrike: '删除线',\n tooltipCode: '行内代码',\n tooltipColor: '文字颜色',\n tooltipHighlight: '高亮',\n tooltipLink: '链接',\n tooltipComment: '评论(v1.x)',\n tooltipTurnCollapsible: '转为折叠块',\n tooltipMore: '更多',\n tooltipImprove: 'AI 改写',\n tooltipCopyMarkdown: '复制为 Markdown',\n // color/highlight panel\n colorDefault: '默认',\n highlightNone: '无高亮',\n // link panel\n linkPlaceholder: '链接地址…',\n linkApply: '应用',\n linkRemove: '移除链接',\n linkOpen: '打开',\n // empty-line toolbar\n emptyLineExpand: '展开全部块',\n // find & replace\n findPlaceholder: '查找…',\n replacePlaceholder: '替换为…',\n findNext: '下一个',\n findPrev: '上一个',\n replaceOne: '替换',\n replaceAll: '全部替换',\n findCount: (n: number) => `${n} 个结果`,\n findClose: '关闭',\n // image\n imageUploadFailed: '图片上传失败',\n imageAlignLeft: '左对齐',\n imageAlignCenter: '居中',\n imageAlignFull: '全宽',\n // AI panel\n aiTitle: 'AI',\n aiAskPlaceholder: '针对本文档提问…',\n aiSend: '发送',\n aiThinking: '思考中…',\n aiAccept: '接受',\n aiReject: '拒绝',\n aiImprovePrompt: '改写要求(可选)…',\n aiImproveRun: '执行',\n aiStreaming: '生成中…',\n aiRuntimeMissing: '未注入 AI Runtime,此操作不可用',\n // v1.1: tables\n itemTable: '表格',\n itemTableDesc: '带类型化列的结构化表格(⌘⌥S)',\n itemTableSimple: '无表头表格',\n itemTableSimpleDesc: '纯文本简易布局表(⌘⌥T)',\n colTypeText: '文本',\n colTypeCheckbox: '复选框',\n colTypeSelect: '单选标签',\n colTypeMultiSelect: '多选标签',\n colTypeNumber: '数字',\n colTypeDate: '日期',\n colTypeLink: '链接',\n colMenuTitle: '列操作',\n colMenuSortAsc: '升序排序',\n colMenuSortDesc: '降序排序',\n colMenuInsertLeft: '左侧插入列',\n colMenuInsertRight: '右侧插入列',\n colMenuDelete: '删除此列',\n colMenuType: '列类型',\n rowMenuTitle: '行操作',\n rowMenuInsertAbove: '上方插入行',\n rowMenuInsertBelow: '下方插入行',\n rowMenuDelete: '删除此行',\n tableDelete: '删除表格',\n tableCopyCsv: '复制为 CSV',\n tableToggleHeader: '切换表头',\n cellEmpty: '空',\n // v1.1: history\n itemHistory: '版本历史',\n historyTitle: '版本历史',\n historyEmpty: '暂无快照(编辑后空闲自动保存,或手动捕获)',\n historyCapture: '捕获快照',\n historyRestore: '恢复此版本',\n historyCurrent: '当前',\n historyDiffAdded: '新增',\n historyDiffRemoved: '删除',\n historyDiffChanged: '修改',\n historyConfirmRestore: '恢复到该版本?当前内容将被替换(可撤销)',\n // v1.1: comments\n tooltipCommentV11: '评论',\n commentTitle: '评论',\n commentEmpty: '暂无评论',\n commentPlaceholder: '写下评论…(Shift+Enter 换行)',\n commentSend: '发送',\n commentResolve: '解决',\n commentReopen: '重新打开',\n commentDelete: '删除',\n commentResolvedBadge: '已解决',\n commentCount: (n: number) => `${n} 条评论`,\n // v1.1: embed / toc / placeholder\n itemEmbed: '嵌入',\n itemEmbedDesc: '嵌入外部网页(iframe 沙箱)',\n itemToc: '目录',\n itemTocDesc: '自动生成全文大纲(H1–H4)',\n embedPlaceholder: '粘贴要嵌入的链接…',\n embedApply: '嵌入',\n embedInvalid: '无效链接',\n embedOpen: '打开原链接',\n tocEmpty: '暂无标题——添加 H1–H4 后自动出现',\n placeholderText: '待补充',\n placeholderPerson: '待填人',\n placeholderDate: '待填日期',\n // v1.1: block context menu\n menuCopyAnchor: '复制锚链接',\n menuCopyBlockId: '复制块 ID',\n menuDeleteBlock: '删除此块',\n },\n 'en-US': {\n placeholderEmpty: \"Type / for blocks, or just start writing…\",\n groupBasic: 'Basic blocks',\n groupAdvanced: 'Advanced blocks',\n groupAi: 'AI',\n itemText: 'Text',\n itemTextDesc: 'Plain paragraph',\n itemH1: 'Heading 1',\n itemH2: 'Heading 2',\n itemH3: 'Heading 3',\n itemH4: 'Heading 4',\n itemBullet: 'Bullet list',\n itemBulletDesc: 'Simple bulleted list',\n itemOrdered: 'Numbered list',\n itemOrderedDesc: 'List with numbering',\n itemTask: 'Task list',\n itemTaskDesc: 'Track to-dos with checkboxes',\n itemQuote: 'Quote',\n itemQuoteDesc: 'Quote a passage',\n itemCode: 'Code block',\n itemCodeDesc: 'Code with syntax highlighting',\n itemDivider: 'Divider',\n itemDividerDesc: 'Horizontal rule',\n itemHint: 'Hint',\n itemHintDesc: 'Callout container (!! + space)',\n itemCollapsible: 'Collapsible',\n itemCollapsibleDesc: 'Foldable section (>> + space)',\n itemImage: 'Image',\n itemImageDesc: 'Upload or paste an image',\n itemImageUrl: 'Image URL',\n itemSummarize: 'AI Summarize',\n itemSummarizeDesc: 'Generate a TL;DR for this doc',\n itemAsk: 'AI Ask',\n itemAskDesc: 'Ask questions about this doc',\n itemImprove: 'AI Improve',\n itemImproveDesc: 'Rewrite the selection',\n tooltipBold: 'Bold',\n tooltipItalic: 'Italic',\n tooltipUnderline: 'Underline',\n tooltipStrike: 'Strikethrough',\n tooltipCode: 'Inline code',\n tooltipColor: 'Text color',\n tooltipHighlight: 'Highlight',\n tooltipLink: 'Link',\n tooltipComment: 'Comment (v1.x)',\n tooltipTurnCollapsible: 'Turn into collapsible',\n tooltipMore: 'More',\n tooltipImprove: 'AI Improve',\n tooltipCopyMarkdown: 'Copy as Markdown',\n colorDefault: 'Default',\n highlightNone: 'No highlight',\n linkPlaceholder: 'Link URL…',\n linkApply: 'Apply',\n linkRemove: 'Remove link',\n linkOpen: 'Open',\n emptyLineExpand: 'Show all blocks',\n findPlaceholder: 'Find…',\n replacePlaceholder: 'Replace with…',\n findNext: 'Next',\n findPrev: 'Prev',\n replaceOne: 'Replace',\n replaceAll: 'Replace all',\n findCount: (n: number) => `${n} result${n === 1 ? '' : 's'}`,\n findClose: 'Close',\n imageUploadFailed: 'Image upload failed',\n imageAlignLeft: 'Align left',\n imageAlignCenter: 'Center',\n imageAlignFull: 'Full width',\n aiTitle: 'AI',\n aiAskPlaceholder: 'Ask about this doc…',\n aiSend: 'Send',\n aiThinking: 'Thinking…',\n aiAccept: 'Accept',\n aiReject: 'Reject',\n aiImprovePrompt: 'Instruction (optional)…',\n aiImproveRun: 'Run',\n aiStreaming: 'Generating…',\n aiRuntimeMissing: 'No AI Runtime injected; action unavailable',\n // v1.1: tables\n itemTable: 'Table',\n itemTableDesc: 'Structured table with typed columns (⌘⌥S)',\n itemTableSimple: 'Table (no header)',\n itemTableSimpleDesc: 'Plain layout table without header (⌘⌥T)',\n colTypeText: 'Text',\n colTypeCheckbox: 'Checkbox',\n colTypeSelect: 'Select tag',\n colTypeMultiSelect: 'Multi-select',\n colTypeNumber: 'Number',\n colTypeDate: 'Date',\n colTypeLink: 'Link',\n colMenuTitle: 'Column',\n colMenuSortAsc: 'Sort ascending',\n colMenuSortDesc: 'Sort descending',\n colMenuInsertLeft: 'Insert column left',\n colMenuInsertRight: 'Insert column right',\n colMenuDelete: 'Delete column',\n colMenuType: 'Column type',\n rowMenuTitle: 'Row',\n rowMenuInsertAbove: 'Insert row above',\n rowMenuInsertBelow: 'Insert row below',\n rowMenuDelete: 'Delete row',\n tableDelete: 'Delete table',\n tableCopyCsv: 'Copy as CSV',\n tableToggleHeader: 'Toggle header row',\n cellEmpty: 'Empty',\n // v1.1: history\n itemHistory: 'Version history',\n historyTitle: 'Version history',\n historyEmpty: 'No snapshots yet (auto-captured when idle, or capture manually)',\n historyCapture: 'Capture snapshot',\n historyRestore: 'Restore this version',\n historyCurrent: 'Current',\n historyDiffAdded: 'Added',\n historyDiffRemoved: 'Removed',\n historyDiffChanged: 'Changed',\n historyConfirmRestore: 'Restore this version? Current content will be replaced (undoable)',\n // v1.1: comments\n tooltipCommentV11: 'Comment',\n commentTitle: 'Comments',\n commentEmpty: 'No comments yet',\n commentPlaceholder: 'Write a comment… (Shift+Enter for newline)',\n commentSend: 'Send',\n commentResolve: 'Resolve',\n commentReopen: 'Reopen',\n commentDelete: 'Delete',\n commentResolvedBadge: 'Resolved',\n commentCount: (n: number) => `${n} comment${n === 1 ? '' : 's'}`,\n // v1.1: embed / toc / placeholder\n itemEmbed: 'Embed',\n itemEmbedDesc: 'Embed an external page (sandboxed iframe)',\n itemToc: 'Table of contents',\n itemTocDesc: 'Auto outline from H1–H4',\n embedPlaceholder: 'Paste a link to embed…',\n embedApply: 'Embed',\n embedInvalid: 'Invalid URL',\n embedOpen: 'Open original',\n tocEmpty: 'No headings yet — add H1–H4 and they appear here',\n placeholderText: 'to fill in',\n placeholderPerson: 'assignee',\n placeholderDate: 'due date',\n // v1.1: block context menu\n menuCopyAnchor: 'Copy anchor link',\n menuCopyBlockId: 'Copy block ID',\n menuDeleteBlock: 'Delete block',\n },\n} as const\n\nexport type TesseraMessageKey = keyof typeof tesseraMessages['zh-CN']\n\nexport type TesseraTranslator = (key: TesseraMessageKey) => string\n\nexport function createTesseraT(locale: TesseraLocale = 'zh-CN'): TesseraTranslator {\n const table = tesseraMessages[locale] ?? tesseraMessages['zh-CN']\n return key => (table as Record<string, string | ((n: number) => string)>)[key] as string ?? key\n}\n","import { Extension } from '@tiptap/core'\nimport { PluginKey } from '@tiptap/pm/state'\nimport Suggestion from '@tiptap/suggestion'\nimport type { SuggestionOptions, SuggestionProps, SuggestionKeyDownProps } from '@tiptap/suggestion'\n\n/**\n * Emoji picker (acceptance §2, v1.1): typing `:` anywhere opens a picker\n * filtered by name/keywords; Return / click inserts the emoji and closes.\n * Runs on @tiptap/suggestion like the slash menu — IME composition guard\n * comes for free (suggestion ignores composing transactions).\n */\n\nexport interface EmojiItem {\n char: string\n name: string\n keywords: string[]\n}\n\n/** Curated common set; hosts may append via `extraItems`. */\nexport const EMOJI_ITEMS: EmojiItem[] = [\n { char: '😀', name: 'grinning', keywords: ['face', 'happy', 'smile'] },\n { char: '😄', name: 'smile', keywords: ['face', 'happy', 'joy'] },\n { char: '😁', name: 'beaming', keywords: ['face', 'grin'] },\n { char: '😂', name: 'joy', keywords: ['face', 'tears', 'lol'] },\n { char: '🤣', name: 'rofl', keywords: ['face', 'laugh', 'floor'] },\n { char: '😊', name: 'blush', keywords: ['face', 'happy', 'warm'] },\n { char: '🙂', name: 'slight_smile', keywords: ['face', 'smile'] },\n { char: '😉', name: 'wink', keywords: ['face'] },\n { char: '😍', name: 'heart_eyes', keywords: ['face', 'love'] },\n { char: '😘', name: 'kiss', keywords: ['face', 'love'] },\n { char: '😜', name: 'zany', keywords: ['face', 'crazy', 'tongue'] },\n { char: '🤔', name: 'thinking', keywords: ['face', 'hmm'] },\n { char: '🤗', name: 'hug', keywords: ['face'] },\n { char: '🤨', name: 'eyebrow', keywords: ['face', 'suspicious'] },\n { char: '😐', name: 'neutral', keywords: ['face', 'meh'] },\n { char: '😴', name: 'sleeping', keywords: ['face', 'zzz'] },\n { char: '😪', name: 'sleepy', keywords: ['face', 'tired'] },\n { char: '😫', name: 'tired', keywords: ['face', 'exhausted'] },\n { char: '🥳', name: 'partying', keywords: ['face', 'celebrate'] },\n { char: '😎', name: 'cool', keywords: ['face', 'sunglasses'] },\n { char: '🤓', name: 'nerd', keywords: ['face', 'glasses'] },\n { char: '😭', name: 'sob', keywords: ['face', 'cry', 'tears'] },\n { char: '😡', name: 'angry', keywords: ['face', 'rage'] },\n { char: '😱', name: 'scream', keywords: ['face', 'fear'] },\n { char: '🤯', name: 'exploding_head', keywords: ['face', 'mind', 'blown'] },\n { char: '🥺', name: 'pleading', keywords: ['face', 'puppy'] },\n { char: '😇', name: 'innocent', keywords: ['face', 'angel', 'halo'] },\n { char: '🤝', name: 'handshake', keywords: ['hands', 'deal'] },\n { char: '👍', name: 'thumbsup', keywords: ['hand', 'ok', 'like', 'yes'] },\n { char: '👎', name: 'thumbsdown', keywords: ['hand', 'dislike', 'no'] },\n { char: '👌', name: 'ok_hand', keywords: ['hand'] },\n { char: '✌️', name: 'victory', keywords: ['hand', 'peace'] },\n { char: '🤞', name: 'crossed_fingers', keywords: ['hand', 'luck'] },\n { char: '👏', name: 'clap', keywords: ['hands', 'praise'] },\n { char: '🙏', name: 'pray', keywords: ['hands', 'thanks'] },\n { char: '💪', name: 'muscle', keywords: ['arm', 'strong'] },\n { char: '❤️', name: 'heart', keywords: ['love', 'red'] },\n { char: '🧡', name: 'orange_heart', keywords: ['love'] },\n { char: '💛', name: 'yellow_heart', keywords: ['love'] },\n { char: '💚', name: 'green_heart', keywords: ['love'] },\n { char: '💙', name: 'blue_heart', keywords: ['love'] },\n { char: '💜', name: 'purple_heart', keywords: ['love'] },\n { char: '🖤', name: 'black_heart', keywords: ['love'] },\n { char: '💔', name: 'broken_heart', keywords: ['love', 'sad'] },\n { char: '⭐', name: 'star', keywords: ['favorite'] },\n { char: '🌟', name: 'glowing_star', keywords: ['star', 'shine'] },\n { char: '✨', name: 'sparkles', keywords: ['magic', 'shine', 'ai'] },\n { char: '🔥', name: 'fire', keywords: ['hot', 'flame'] },\n { char: '⚡', name: 'zap', keywords: ['lightning', 'fast'] },\n { char: '💡', name: 'bulb', keywords: ['idea', 'light'] },\n { char: '✅', name: 'check', keywords: ['done', 'ok', 'complete'] },\n { char: '❌', name: 'x', keywords: ['wrong', 'no', 'cancel'] },\n { char: '⚠️', name: 'warning', keywords: ['caution', 'alert'] },\n { char: '❓', name: 'question', keywords: ['ask', 'help'] },\n { char: '❗', name: 'exclamation', keywords: ['important'] },\n { char: '🚀', name: 'rocket', keywords: ['ship', 'launch', 'fast'] },\n { char: '🎉', name: 'tada', keywords: ['party', 'celebrate', 'congrats'] },\n { char: '🎊', name: 'confetti', keywords: ['party'] },\n { char: '🎯', name: 'dart', keywords: ['target', 'goal'] },\n { char: '📌', name: 'pushpin', keywords: ['pin'] },\n { char: '📎', name: 'paperclip', keywords: ['attach'] },\n { char: '📝', name: 'memo', keywords: ['note', 'doc', 'write'] },\n { char: '📅', name: 'calendar', keywords: ['date', 'schedule'] },\n { char: '⏰', name: 'alarm', keywords: ['clock', 'time'] },\n { char: '💰', name: 'moneybag', keywords: ['money', 'cash'] },\n { char: '🎁', name: 'gift', keywords: ['present'] },\n { char: '☕', name: 'coffee', keywords: ['drink', 'tea'] },\n { char: '🍕', name: 'pizza', keywords: ['food'] },\n { char: '🌈', name: 'rainbow', keywords: ['color'] },\n { char: '☀️', name: 'sunny', keywords: ['weather', 'sun'] },\n { char: '🌙', name: 'crescent', keywords: ['weather', 'moon', 'night'] },\n { char: '☁️', name: 'cloud', keywords: ['weather'] },\n { char: '👀', name: 'eyes', keywords: ['look', 'watch'] },\n { char: '🤖', name: 'robot', keywords: ['ai', 'bot'] },\n { char: '🐞', name: 'bug', keywords: ['insect', 'error'] },\n]\n\nexport function filterEmojiItems(query: string, items: EmojiItem[] = EMOJI_ITEMS): EmojiItem[] {\n const q = query.toLowerCase()\n if (!q) {\n return items\n }\n return items.filter(\n item => item.name.toLowerCase().includes(q) || item.keywords.some(k => k.toLowerCase().includes(q)),\n )\n}\n\nexport interface EmojiMenuOptions {\n /** UI renderer provided by a binding (same contract as the slash menu). */\n render?: () => {\n onStart: (props: SuggestionProps<EmojiItem>) => void\n onUpdate: (props: SuggestionProps<EmojiItem>) => void\n onExit: (props: SuggestionProps<EmojiItem>) => void\n onKeyDown?: (props: SuggestionKeyDownProps) => boolean\n }\n /** Hosts may append their own emoji entries. */\n extraItems?: () => EmojiItem[]\n}\n\nexport const EmojiMenu = Extension.create<EmojiMenuOptions>({\n name: 'tesseraEmojiMenu',\n\n addOptions() {\n return {\n render: undefined,\n extraItems: undefined,\n }\n },\n\n addProseMirrorPlugins() {\n const options = this.options\n const items = [...EMOJI_ITEMS, ...(options.extraItems?.() ?? [])]\n\n return [\n Suggestion({\n editor: this.editor,\n pluginKey: new PluginKey('tesseraEmojiMenu'),\n char: ':',\n startOfLine: false,\n items: ({ query }) => filterEmojiItems(query, items),\n command: ({ editor: e, range, props }) => {\n e.chain().focus().insertContentAt(range, `${(props as EmojiItem).char} `).run()\n },\n render: options.render as SuggestionOptions<EmojiItem>['render'],\n }),\n ]\n },\n})\n","import { Extension } from '@tiptap/core'\nimport type { JSONContent } from '@tiptap/core'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { getStorageService, type DocSnapshot } from '../services'\n\n/**\n * Version history capture (v1.1): snapshots the canonical JSON into the\n * injected StorageService. Auto-capture fires after `idleMs` of inactivity\n * (Slite: 5 minutes); manual capture is always available as a command.\n */\n\nexport interface HistorySnapshotOptions {\n /** idle window before auto-capture (default 5 minutes) */\n idleMs?: number\n /** minimum ms between two auto-captures (default 60s) */\n minIntervalMs?: number\n /** snapshot label source */\n label?: () => string | undefined\n}\n\ndeclare module '@tiptap/core' {\n interface Commands<ReturnType> {\n tesseraHistory: {\n captureSnapshot: (label?: string) => ReturnType\n }\n }\n interface EditorEvents {\n 'tessera:snapshotSaved': { snapshot: DocSnapshot }\n }\n}\n\nexport const historyKey = new PluginKey('tesseraHistory')\n\nexport const TesseraHistory = Extension.create<HistorySnapshotOptions>({\n name: 'tesseraHistory',\n\n addOptions() {\n return {\n idleMs: 5 * 60 * 1000,\n minIntervalMs: 60 * 1000,\n label: undefined,\n }\n },\n\n addCommands() {\n return {\n captureSnapshot:\n (label?: string) =>\n ({ editor, state }) => {\n const storage = getStorageService(editor)\n if (!storage) {\n return false\n }\n const doc = editor.getJSON() as JSONContent\n const snapshot: DocSnapshot = {\n id: `snap-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`,\n ts: Date.now(),\n doc,\n label: label ?? this.options.label?.(),\n }\n void storage.saveSnapshot(snapshot).then(() => {\n editor.emit('tessera:snapshotSaved', { snapshot })\n })\n const tr = state.tr.setMeta(historyKey, { type: 'captured', ts: snapshot.ts })\n editor.view.dispatch(tr)\n return true\n },\n }\n },\n\n addProseMirrorPlugins() {\n const editor = this.editor\n const options = this.options\n return [\n new Plugin({\n key: historyKey,\n state: {\n init: () => ({ lastChange: 0, lastCapture: 0, timer: null as ReturnType<typeof setTimeout> | null }),\n apply: (tr, prev) => {\n const meta = tr.getMeta(historyKey) as { type: string; ts?: number } | undefined\n if (meta?.type === 'captured') {\n return { ...prev, lastCapture: meta.ts ?? Date.now() }\n }\n if (!tr.docChanged) {\n return prev\n }\n return { ...prev, lastChange: Date.now() }\n },\n },\n view() {\n return {\n update: (_view, prevState) => {\n const before = historyKey.getState(prevState)\n const after = historyKey.getState(editor.state)\n if (!before || !after || after.lastChange === before.lastChange) {\n return\n }\n const storage = getStorageService(editor)\n if (!storage) {\n return\n }\n const s = historyKey.getState(editor.state)\n if (s?.timer) {\n clearTimeout(s.timer)\n }\n const timer = setTimeout(() => {\n const now = Date.now()\n const cur = historyKey.getState(editor.state)\n if (!cur || now - cur.lastChange < options.idleMs! - 50) {\n return\n }\n if (now - cur.lastCapture < options.minIntervalMs!) {\n return\n }\n editor.commands.captureSnapshot()\n }, options.idleMs!)\n const st = historyKey.getState(editor.state)\n if (st) {\n st.timer = timer\n }\n },\n destroy() {\n const s = historyKey.getState(editor.state)\n if (s?.timer) {\n clearTimeout(s.timer)\n }\n },\n }\n },\n }),\n ]\n },\n})\n","import { Extension } from '@tiptap/core'\nimport type { JSONContent } from '@tiptap/core'\n\n/**\n * Injected services (ADR-0001 family): the component family never performs\n * network or storage I/O itself. Hosts provide implementations through the\n * binding; the editor reads them from `editor.storage.tesseraServices`.\n */\n\nexport interface UploadedAsset {\n url: string\n name?: string\n mime?: string\n}\n\nexport interface UploadService {\n uploadImage(file: File | Blob): Promise<UploadedAsset>\n uploadFile?(file: File | Blob): Promise<UploadedAsset>\n}\n\n/** v1.1: persistent version history storage (snapshots keyed by time). */\nexport interface DocSnapshot {\n id: string\n ts: number\n doc: JSONContent\n label?: string\n}\n\nexport interface StorageService {\n saveSnapshot(snapshot: DocSnapshot): Promise<void>\n listSnapshots(): Promise<DocSnapshot[]>\n deleteSnapshot?(id: string): Promise<void>\n}\n\n/** v1.1: inline comments. */\nexport interface CommentEntry {\n id: string\n authorId: string\n authorName: string\n text: string\n ts: number\n}\n\nexport interface CommentThread {\n id: string\n quote: string\n resolved: boolean\n createdAt: number\n entries: CommentEntry[]\n}\n\nexport interface CommentStore {\n list(): Promise<CommentThread[]>\n upsert(thread: CommentThread): Promise<void>\n remove(id: string): Promise<void>\n}\n\n/** v1.1: who is editing (author of comments / history labels). */\nexport interface IdentityService {\n getCurrentUser(): { id: string; name: string } | null\n}\n\nexport interface TesseraServicesStorage {\n upload?: UploadService\n storage?: StorageService\n comments?: CommentStore\n identity?: IdentityService\n}\n\nexport const TesseraServices = Extension.create({\n name: 'tesseraServices',\n\n addStorage() {\n return {\n upload: undefined,\n storage: undefined,\n comments: undefined,\n identity: undefined,\n } satisfies TesseraServicesStorage\n },\n})\n\ntype ServicesEditor = { storage: unknown }\n\nfunction servicesBag(editor: ServicesEditor): TesseraServicesStorage | undefined {\n return (editor.storage as Record<string, TesseraServicesStorage | undefined>).tesseraServices\n}\n\nexport function getUploadService(editor: ServicesEditor): UploadService | undefined {\n return servicesBag(editor)?.upload\n}\n\nexport function getStorageService(editor: ServicesEditor): StorageService | undefined {\n return servicesBag(editor)?.storage\n}\n\nexport function getCommentStore(editor: ServicesEditor): CommentStore | undefined {\n return servicesBag(editor)?.comments\n}\n\nexport function getIdentityService(editor: ServicesEditor): IdentityService | undefined {\n return servicesBag(editor)?.identity\n}\n","import { Extension } from '@tiptap/core'\nimport { Plugin } from '@tiptap/pm/state'\n\n/**\n * Block context menu (v1.1): right-click a block → `tessera:blockMenu` event.\n * The binding renders the menu (copy anchor link / copy block id / delete;\n * row & column ops when the target is a table).\n */\nexport const BlockContextMenu = Extension.create({\n name: 'tesseraBlockMenu',\n\n addProseMirrorPlugins() {\n const editor = this.editor\n return [\n new Plugin({\n props: {\n handleDOMEvents: {\n contextmenu: (view, event) => {\n const coords = view.posAtCoords({ left: event.clientX, top: event.clientY })\n if (!coords) {\n return false\n }\n const $pos = view.state.doc.resolve(coords.pos)\n for (let depth = $pos.depth; depth >= 1; depth--) {\n const node = $pos.node(depth)\n if (typeof node.attrs.id === 'string') {\n editor.emit('tessera:blockMenu', {\n blockId: node.attrs.id as string,\n blockType: node.type.name,\n clientX: event.clientX,\n clientY: event.clientY,\n })\n event.preventDefault()\n return true\n }\n }\n return false\n },\n },\n },\n }),\n ]\n },\n})\n\ndeclare module '@tiptap/core' {\n interface EditorEvents {\n 'tessera:blockMenu': {\n blockId: string\n blockType: string\n clientX: number\n clientY: number\n }\n }\n}\n","import { Extension } from '@tiptap/core'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\n\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport { Decoration, DecorationSet } from '@tiptap/pm/view'\nimport type { DecorationAttrs } from '@tiptap/pm/view'\n\n/**\n * Image gallery (acceptance §6, v1.1): runs of two or more consecutive\n * top-level image blocks are flagged with data-gallery attributes so the\n * theme can lay them out three per row (CSS: inline-block thirds).\n * Purely presentational — the document format is unchanged (still\n * sibling imageBlock nodes), so Markdown/JSON round-trips are unaffected.\n */\n\nexport const galleryKey = new PluginKey('tesseraGallery')\n\ninterface GalleryRun {\n from: number\n to: number\n size: number\n}\n\n/** Shared run detection so tests and the plugin agree on the definition. */\nexport function findGalleryRuns(doc: ProseMirrorNode): GalleryRun[] {\n const runs: GalleryRun[] = []\n let start = -1\n let size = 0\n doc.forEach((node, offset) => {\n if (node.type.name === 'imageBlock') {\n if (start < 0) {\n start = offset\n size = 0\n }\n size += 1\n } else if (start >= 0) {\n if (size >= 2) {\n runs.push({ from: start, to: offset, size })\n }\n start = -1\n size = 0\n }\n })\n if (start >= 0 && size >= 2) {\n runs.push({ from: start, to: doc.content.size, size })\n }\n return runs\n}\n\nfunction galleryDecorations(doc: ProseMirrorNode): DecorationSet {\n const decorations: Decoration[] = []\n for (const run of findGalleryRuns(doc)) {\n let index = 0\n doc.nodesBetween(run.from, run.to, (node: ProseMirrorNode, pos: number) => {\n if (node.type.name !== 'imageBlock') {\n return false\n }\n const attrs: DecorationAttrs = {\n 'data-gallery': 'true',\n 'data-gallery-index': String(index),\n 'data-gallery-size': String(run.size),\n }\n decorations.push(Decoration.node(pos, pos + node.nodeSize, attrs))\n index += 1\n return false\n })\n }\n // props.decorations must yield a DecorationSet — a plain array breaks\n // DecorationGroup.from (it flattens only set members)\n return DecorationSet.create(doc, decorations)\n}\n\nexport const TesseraGallery = Extension.create({\n name: 'tesseraGallery',\n\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: galleryKey,\n state: {\n init: (_config, state) => galleryDecorations(state.doc),\n apply: (tr, old) => (tr.docChanged ? galleryDecorations(tr.doc) : old),\n },\n props: {\n decorations(state) {\n return galleryKey.getState(state)\n },\n },\n }),\n ]\n },\n})\n\n/**\n * Read the gallery attributes (if any) a NodeView should apply for `node`:\n * finds the node decoration covering `pos` that carries data-gallery attrs.\n * NodeViews must apply these themselves — custom NodeViews bypass PM's\n * automatic decoration-attr application.\n */\nexport function galleryAttrsFor(\n decorations: readonly Decoration[],\n pos: number,\n): DecorationAttrs | null {\n for (const deco of decorations) {\n const attrs = (deco as unknown as { type?: { attrs?: DecorationAttrs } }).type?.attrs\n if (attrs && 'data-gallery' in attrs && deco.from <= pos && pos <= deco.to) {\n return attrs\n }\n }\n return null\n}\n","import { Extension } from '@tiptap/core'\nimport type { Editor } from '@tiptap/core'\nimport { docToMarkdown } from '../markdown'\n\n/**\n * Performance metrics (acceptance §8, v1.1): long-document observability.\n * The architecture keeps per-block NodeViews and lazy decoration passes in\n * place; this exposes the numbers a host needs to watch (block/word counts,\n * heavy-node counts, markdown serialize cost) so virtualization work can be\n * measured rather than guessed. Usage: `getTesseraMetrics(editor)`.\n */\n\nexport interface TesseraMetricsSnapshot {\n /** Top-level blocks in the document. */\n blocks: number\n /** Whitespace-split word count of the document text. */\n words: number\n /** imageBlock nodes. */\n images: number\n /** aiTable nodes. */\n tables: number\n /** NodeView wrapper elements currently mounted. */\n mountedNodeViews: number\n /** Milliseconds for a full Markdown serialization of the current doc. */\n serializeMs: number\n}\n\nexport function measureTesseraMetrics(editor: Editor): TesseraMetricsSnapshot {\n let images = 0\n let tables = 0\n editor.state.doc.descendants(node => {\n if (node.type.name === 'imageBlock') images += 1\n if (node.type.name === 'table') tables += 1\n return true\n })\n\n const started = performance.now()\n docToMarkdown(editor.state.doc, editor.state.schema)\n const serializeMs = Math.round((performance.now() - started) * 100) / 100\n\n return {\n blocks: editor.state.doc.childCount,\n words: editor.state.doc.textBetween(0, editor.state.doc.content.size, ' ', ' ')\n .split(/\\s+/)\n .filter(Boolean).length,\n images,\n tables,\n mountedNodeViews: editor.view\n ? editor.view.dom.querySelectorAll('[data-node-view-wrapper]').length\n : 0,\n serializeMs,\n }\n}\n\nexport const TesseraMetrics = Extension.create({\n name: 'tesseraMetrics',\n})\n\nexport function getTesseraMetrics(editor: Editor): TesseraMetricsSnapshot {\n return measureTesseraMetrics(editor)\n}\n","import MarkdownIt from 'markdown-it'\nimport { DOMParser as PMDOMParser, DOMSerializer } from '@tiptap/pm/model'\nimport { MarkdownSerializer, defaultMarkdownSerializer } from 'prosemirror-markdown'\nimport type { Node as PMNode, Schema } from '@tiptap/pm/model'\nimport type { JSONContent } from '@tiptap/core'\n\n/**\n * Interchange format layer (ADR-0004): the canonical format is JSON; Markdown\n * is the interchange format with guaranteed two-way conversion.\n *\n * Standard blocks → plain Markdown. Task lists → GFM `- [x]`.\n * Tessera structural blocks (hint / collapsible / imageBlock) → semantic HTML,\n * which round-trips through our parseHTML rules and stays portable elsewhere.\n *\n * Export limitations (documented): text color and AI attribution marks do not\n * carry into Markdown (no static syntax); they survive JSON only.\n */\n\n/** markdown-it plugin: GFM task lists (`- [x] text`) → ul/li[data-*]. */\ninterface MdToken {\n type: string\n content?: string\n children?: MdToken[]\n attrSet?: (name: string, value: string) => void\n}\ninterface MdState {\n tokens: MdToken[]\n}\ninterface MarkdownItLike {\n core: {\n ruler: {\n after: (afterName: string, ruleName: string, fn: (state: MdState) => void) => void\n }\n }\n}\n\nfunction taskListPlugin(md: MarkdownItLike): void {\n md.core.ruler.after('inline', 'tessera-tasklist', state => {\n const tokens = state.tokens\n const taskItems = new Set<number>()\n for (let i = 0; i < tokens.length; i++) {\n if (tokens[i]!.type !== 'inline') continue\n let p = -1\n if (tokens[i - 1]?.type === 'paragraph_open') p = i - 2\n if (p === -1 || tokens[p]?.type !== 'list_item_open') continue\n const children = tokens[i]!.children\n if (!children || children.length === 0) continue\n const first = children[0]!\n const m = /^\\[([ xX])\\]\\s+/.exec(first.content ?? '')\n if (!m) continue\n first.content = (first.content ?? '').slice(m[0].length)\n for (let j = 1; j < children.length; j++) {\n const child = children[j]!\n child.content = (child.content ?? '').replace(/^\\[([ xX])\\]\\s+/, '')\n }\n tokens[p]!.attrSet?.('data-type', 'taskItem')\n tokens[p]!.attrSet?.('data-checked', m[1] === ' ' ? 'false' : 'true')\n taskItems.add(p)\n }\n for (let i = 0; i < tokens.length; i++) {\n if (tokens[i]!.type !== 'bullet_list_open') continue\n for (let j = i + 1; j < tokens.length; j++) {\n if (tokens[j]!.type === 'bullet_list_close') break\n if (tokens[j]!.type === 'list_item_open' && taskItems.has(j)) {\n tokens[i]!.attrSet?.('data-type', 'taskList')\n break\n }\n }\n }\n })\n}\n\nconst md = MarkdownIt({ html: true, linkify: true }).use(\n // structural mismatch is only in the type layer (markdown-it Token typings)\n taskListPlugin as unknown as Parameters<ReturnType<typeof MarkdownIt>['use']>[0],\n)\n\ninterface SerializerState {\n write: (s: string) => void\n renderContent: (n: PMNode) => void\n renderList: (n: PMNode, delim: string, firstDelim: (index: number) => string) => void\n closeBlock: (n: PMNode) => void\n}\n\nfunction stripIds(json: JSONContent): JSONContent {\n const walk = (node: JSONContent): JSONContent => {\n const attrs = node.attrs && 'id' in node.attrs\n ? Object.fromEntries(Object.entries(node.attrs).filter(([k]) => k !== 'id'))\n : node.attrs\n return {\n ...node,\n attrs,\n content: node.content?.map(walk),\n } as JSONContent\n }\n return walk(json)\n}\n\nfunction nodeToHtml(node: PMNode): string {\n // strip ids: interchange HTML must not leak internal block identity\n const clean = node.type.schema.nodeFromJSON(stripIds(node.toJSON()))\n const dom = DOMSerializer.fromSchema(node.type.schema).serializeNode(clean) as HTMLElement\n return dom.outerHTML\n}\n\nexport function createMarkdownSerializer(schema: Schema): MarkdownSerializer {\n const nodes: Record<string, (state: SerializerState, node: PMNode) => void> = {\n ...defaultMarkdownSerializer.nodes,\n } as never\n\n // prosemirror-markdown's defaults use example-schema snake_case node\n // names; provide camelCase (TipTap) equivalents.\n const rep = (s: string, n: number) => ' '.repeat(n)\n nodes.bulletList = (state, node) => {\n state.renderList(node, ' ', () => '- ')\n state.closeBlock(node)\n }\n nodes.orderedList = (state, node) => {\n const start = Number(node.attrs.order ?? 1)\n const maxW = String(start + node.childCount - 1).length\n const space = rep(' ', maxW + 2)\n state.renderList(node, space, i => {\n const n = String(start + i)\n return rep(' ', maxW - n.length) + n + '. '\n })\n state.closeBlock(node)\n }\n nodes.listItem = (state, node) => {\n state.renderContent(node)\n }\n nodes.codeBlock = (state, node) => {\n state.write('```' + (node.attrs.language ?? '') + '\\n')\n state.write(node.textContent)\n state.write('\\n```')\n state.closeBlock(node)\n }\n nodes.horizontalRule = (state, node) => {\n state.write('---')\n state.closeBlock(node)\n }\n nodes.hardBreak = state => {\n state.write('\\\\\\n')\n }\n\n nodes.taskList = (state, node) => {\n state.renderList(node, ' ', () => '- ')\n state.closeBlock(node)\n }\n nodes.taskItem = (state, node) => {\n state.write(node.attrs.checked ? '[x] ' : '[ ] ')\n state.renderContent(node)\n }\n nodes.hint = (state, node) => {\n state.write(nodeToHtml(node))\n state.closeBlock(node)\n }\n nodes.collapsible = (state, node) => {\n state.write(nodeToHtml(node))\n state.closeBlock(node)\n }\n nodes.imageBlock = (state, node) => {\n state.write(nodeToHtml(node))\n state.closeBlock(node)\n }\n nodes.table = (state, node) => {\n // tables carry typed-column metadata in attrs — HTML keeps it round-trip\n state.write(nodeToHtml(node))\n state.closeBlock(node)\n }\n nodes.tableRow = () => {}\n nodes.tableCell = () => {}\n nodes.tableHeader = () => {}\n nodes.embedBlock = (state, node) => {\n state.write(nodeToHtml(node))\n state.closeBlock(node)\n }\n nodes.tocBlock = (state, node) => {\n state.write('<div data-type=\"tessera-toc\"></div>')\n state.closeBlock(node)\n }\n\n // prosemirror-markdown's defaults use the example-schema mark names\n // (strong/em); map TipTap's names explicitly.\n const marks = {\n ...defaultMarkdownSerializer.marks,\n bold: { open: '**', close: '**', mixable: true, expelEnclosingWhitespace: true },\n italic: { open: '*', close: '*', mixable: true, expelEnclosingWhitespace: true },\n strike: { open: '~~', close: '~~', mixable: true, expelEnclosingWhitespace: true },\n code: { open: '`', close: '`', escape: false },\n link: {\n open: '[',\n close: (state: { out: string }, mark: { attrs: { href: string } }) => `](${mark.attrs.href})`,\n mixable: false,\n } as never,\n underline: { open: '<u>', close: '</u>', mixable: true, expelEnclosingWhitespace: true },\n highlight: { open: '<mark>', close: '</mark>', mixable: true, expelEnclosingWhitespace: true },\n // transparent passthroughs: these marks carry no Markdown syntax.\n // Omitting them makes prosemirror-markdown THROW on export (crashes the\n // host app) — textStyle always accompanies Color, and aiAttribution rides\n // on AI-written text.\n textStyle: { open: '', close: '', mixable: true },\n color: { open: '', close: '', mixable: true },\n aiAttribution: { open: '', close: '', mixable: true },\n tesseraPlaceholder: { open: '', close: '', mixable: true },\n comment: { open: '', close: '', mixable: true },\n }\n\n return new MarkdownSerializer(nodes as never, marks as never)\n}\n\n/** Canonical JSON (or doc node) → Markdown. */\nexport function docToMarkdown(doc: PMNode | JSONContent, schema: Schema): string {\n const isNode = typeof (doc as PMNode).nodeSize === 'number' && typeof (doc as PMNode).type === 'object'\n const realDoc = isNode ? (doc as PMNode) : schema.nodeFromJSON(doc as JSONContent)\n return createMarkdownSerializer(schema).serialize(realDoc)\n}\n\n/** Markdown → canonical JSON (authoritative format). Requires DOM (browser/jsdom). */\nexport function markdownToDoc(markdown: string, schema: Schema): JSONContent {\n const html = md.render(markdown)\n const container = document.createElement('div')\n container.innerHTML = html\n const parsed = PMDOMParser.fromSchema(schema).parse(container)\n return parsed.toJSON()\n}\n\n/** Strip volatile/whitespace-irrelevant fields for round-trip comparisons. */\nexport function stableJson(json: JSONContent): JSONContent {\n const clone = JSON.parse(JSON.stringify(json)) as JSONContent\n const walk = (node: JSONContent) => {\n if (node.attrs && 'id' in node.attrs) {\n const { id: _drop, ...rest } = node.attrs\n if (Object.keys(rest).length === 0) {\n delete node.attrs\n } else {\n node.attrs = rest\n }\n }\n // highlight color: null (default) vs \"\" (parsed) are equivalent absence\n node.marks = node.marks?.map(mark => {\n if (mark.attrs) {\n const attrs = Object.fromEntries(\n Object.entries(mark.attrs).filter(([, v]) => v !== null && v !== ''),\n )\n return { ...mark, attrs }\n }\n return mark\n })\n // code blocks: trailing whitespace-only diff is not semantic\n if (node.type === 'codeBlock' && node.content) {\n node.content = node.content.map(child =>\n child.type === 'text' ? { ...child, text: (child.text ?? '').replace(/\\s+$/, '') } : child,\n )\n node.content = node.content.filter(child => !(child.type === 'text' && child.text === ''))\n }\n node.content?.forEach(walk)\n }\n walk(clone)\n return clone\n}\n","import { Extension } from '@tiptap/core'\nimport { Plugin, PluginKey } from '@tiptap/pm/state'\nimport { cleanWordHtml, isWordHtml } from '../wordpaste'\n\n/**\n * Word-source paste cleaning (acceptance §9, v1.1): when the pasted HTML is\n * detected as Word export, the rules table in wordpaste.ts runs before the\n * schema-based parse. Non-Word pastes pass through untouched.\n */\nexport const TesseraWordPaste = Extension.create({\n name: 'tesseraWordPaste',\n\n addProseMirrorPlugins() {\n return [\n new Plugin({\n key: new PluginKey('tesseraWordPaste'),\n props: {\n transformPastedHTML(html) {\n return isWordHtml(html) ? cleanWordHtml(html) : html\n },\n },\n }),\n ]\n },\n})\n","/**\n * Word paste cleaning (acceptance §9, v1.1).\n *\n * Word export HTML is full of Office plumbing that ProseMirror's default\n * schema-based cleaning handles badly (mso styles leak as text, namespace\n * tags become unknown nodes, empty paragraphs multiply). When pasted HTML\n * is detected as Word source, these rules run BEFORE PM parses it:\n *\n * R1 drop comments incl. `<!--[if ...]>...<![endif]-->` conditionals\n * R2 drop <style>/<script>/<meta>/<link> blocks and tags\n * R3 strip Office namespace tags entirely (<o:p>, <w:*, <st1:*>, <v:*>)\n * R4 drop class / style / lang attributes (visual plumbing; bold/italic/\n * underline survive via <b>/<i>/<u> tags which PM keeps)\n * R5 drop Word list markers (\"l\" bullets in mso-list spans are removed\n * with R3/R4; list paragraphs become plain paragraphs — semantic list\n * reconstruction is explicitly out of scope for v1.1)\n * R6 &nbsp; collapses to a normal space\n * R7 empty paragraphs (<p></p>, <p><br></p>, whitespace-only) are removed\n */\n\nexport function isWordHtml(html: string): boolean {\n return (\n html.includes('urn:schemas-microsoft-com:office:word') ||\n html.includes('urn:schemas-microsoft-com:office:office') ||\n /mso-[\\w-]+/.test(html) ||\n /\\bMso\\w+/.test(html) ||\n /<w:/i.test(html) ||\n /<o:/i.test(html)\n )\n}\n\nexport function cleanWordHtml(html: string): string {\n let out = html\n // R1 comments + conditionals\n out = out.replace(/<!--\\[if[\\s\\S]*?<!\\[endif\\]-->/gi, '')\n out = out.replace(/<!--[\\s\\S]*?-->/g, '')\n // R2 style/script blocks, meta/link tags, xml prolog\n out = out.replace(/<(style|script)\\b[\\s\\S]*?<\\/\\1>/gi, '')\n out = out.replace(/<(meta|link)\\b[^>]*>/gi, '')\n out = out.replace(/<\\?xml[^>]*\\?>/gi, '')\n out = out.replace(/<!DOCTYPE[^>]*>/gi, '')\n // R3 office namespace tags\n out = out.replace(/<\\/?[a-z][a-z0-9]*:[^>]*>/gi, '')\n // R4 visual-plumbing attributes (double- and single-quoted)\n out = out.replace(/\\s(class|style|lang|xml:lang|face)\\s*=\\s*\"[^\"]*\"/gi, '')\n out = out.replace(/\\s(class|style|lang|xml:lang|face)\\s*=\\s*'[^']*'/gi, '')\n // R6 non-breaking spaces\n out = out.replace(/&nbsp;/gi, ' ')\n // R7 empty paragraphs (iterate: nested whitespace collapses progressively)\n let prev = ''\n while (out !== prev) {\n prev = out\n out = out.replace(/<p\\b[^>]*>(\\s|<br\\s*\\/?>)*<\\/p>/gi, '')\n }\n return out.trim()\n}\n","import type { Editor } from '@tiptap/core'\n\n/**\n * Block menu helpers shared by the right-click context menu and the drag\n * handle menu (acceptance §5). Pure functions so both bindings — and the\n * tests — operate on the same logic.\n */\n\n/** Resolves the document position of a top-level block by its stable id. */\nexport function findBlockPosById(editor: Editor, id: string): number | null {\n let found: number | null = null\n editor.state.doc.forEach((node, offset) => {\n if (found === null && node.attrs.id === id) {\n found = offset\n }\n })\n return found\n}\n\n/** Removes a top-level block by its stable id (single transaction). */\nexport function deleteBlockById(editor: Editor, id: string): boolean {\n const pos = findBlockPosById(editor, id)\n if (pos === null) {\n return false\n }\n const node = editor.state.doc.nodeAt(pos)\n if (!node) {\n return false\n }\n const tr = editor.state.tr.delete(pos, pos + node.nodeSize)\n editor.view.dispatch(tr)\n return true\n}\n\n/** Anchor URL for a block id (`#block-<id>` on the current page). */\nexport function blockAnchorUrl(blockId: string): string {\n return `${location.origin}${location.pathname}#block-${blockId}`\n}\n","import type { Extensions } from '@tiptap/core'\nimport StarterKit from '@tiptap/starter-kit'\nimport { TaskList, TaskItem } from '@tiptap/extension-list'\nimport { TextStyle } from '@tiptap/extension-text-style'\nimport { Color } from '@tiptap/extension-color'\nimport { Highlight } from '@tiptap/extension-highlight'\nimport { UniqueID } from '@tiptap/extension-unique-id'\nimport { Placeholder } from '@tiptap/extensions'\nimport { Hint } from './nodes/hint'\nimport { Collapsible, CollapsibleSummary, CollapsibleContent } from './nodes/collapsible'\nimport { ImageBlock } from './nodes/image'\nimport { AiTable, AiTableRow, AiTableCell, AiTableHeader } from './nodes/table'\nimport { EmbedBlock } from './nodes/embed'\nimport { TocBlock } from './nodes/toc'\nimport { AiAttribution } from './marks/ai'\nimport { CommentMark, CommentCommands } from './marks/comment'\nimport { PlaceholderMark, PlaceholderCommands } from './marks/placeholder'\nimport { TesseraInputRules } from './extensions/input-rules'\nimport { TesseraShortcuts } from './extensions/shortcuts'\nimport { TesseraFindReplace } from './extensions/find-replace'\nimport { SlashMenu } from './extensions/slash'\nimport { EmojiMenu } from './extensions/emoji'\nimport { TesseraHistory } from './extensions/history'\nimport { BlockContextMenu } from './extensions/context-menu'\nimport { TesseraGallery } from './extensions/gallery'\nimport { TesseraMetrics } from './extensions/metrics'\nimport { TesseraWordPaste } from './extensions/word-paste'\nimport { TesseraServices } from './services'\nimport { createTesseraT, type TesseraLocale } from './i18n'\n\nexport interface TesseraPresetOptions {\n locale?: TesseraLocale\n /** v1.1 history auto-capture idle window (playground uses a short one) */\n historyIdleMs?: number\n}\n\n/** Node types that receive stable block IDs (write-back protocol basis). */\nexport const ID_BLOCK_TYPES = [\n 'paragraph',\n 'heading',\n 'bulletList',\n 'orderedList',\n 'taskList',\n 'listItem',\n 'taskItem',\n 'blockquote',\n 'codeBlock',\n 'horizontalRule',\n 'hint',\n 'collapsible',\n 'imageBlock',\n 'table',\n 'tableRow',\n 'embedBlock',\n 'tocBlock',\n]\n\n/**\n * The Tessera extension preset: framework-agnostic, UI-free. The binding layers\n * rendering (slash menu renderer, node views) on top of this.\n */\nexport function createTesseraExtensions(options: TesseraPresetOptions = {}): Extensions {\n const t = createTesseraT(options.locale ?? 'zh-CN')\n\n return [\n StarterKit.configure({\n heading: { levels: [1, 2, 3, 4] },\n link: {\n openOnClick: false,\n autolink: true,\n defaultProtocol: 'https',\n },\n // undoRedo keeps defaults (newGroupDelay 500ms): streaming AI chunks\n // arriving faster than that already merge into one undo step.\n }),\n TextStyle,\n Color,\n Highlight.configure({ multicolor: true }),\n TaskList,\n TaskItem.configure({ nested: true }),\n Hint,\n Collapsible,\n CollapsibleSummary,\n CollapsibleContent,\n ImageBlock,\n AiTable,\n AiTableRow,\n AiTableCell,\n AiTableHeader,\n EmbedBlock,\n TocBlock,\n AiAttribution,\n CommentMark,\n CommentCommands,\n PlaceholderMark,\n PlaceholderCommands,\n UniqueID.configure({\n types: ID_BLOCK_TYPES,\n attributeName: 'id',\n }),\n Placeholder.configure({\n placeholder: ({ node }) => (node.type.name === 'paragraph' ? t('placeholderEmpty') : ''),\n showOnlyWhenEditable: true,\n }),\n TesseraInputRules,\n TesseraShortcuts,\n TesseraFindReplace,\n TesseraHistory.configure({ idleMs: options.historyIdleMs }),\n BlockContextMenu,\n SlashMenu.configure({ locale: options.locale ?? 'zh-CN' }),\n EmojiMenu,\n TesseraGallery,\n TesseraMetrics,\n TesseraWordPaste,\n TesseraServices,\n ]\n}\n","import type { JSONContent } from '@tiptap/core'\n\n/**\n * Document diff (v1.1 history panel): block-level via stable ids (LCS on the\n * id sequence) + word-level inside changed text blocks. Pure utility — the\n * panel renders it.\n */\n\nexport interface WordDiffPart {\n text: string\n type: 'same' | 'add' | 'del'\n}\n\nexport interface BlockDiffEntry {\n kind: 'added' | 'removed' | 'changed' | 'unchanged'\n id?: string\n before?: JSONContent\n after?: JSONContent\n wordDiff?: WordDiffPart[]\n}\n\nfunction topLevel(doc: JSONContent): JSONContent[] {\n return doc.content ?? []\n}\n\nfunction blockId(block: JSONContent): string | null {\n const id = block.attrs?.id\n return typeof id === 'string' ? id : null\n}\n\nfunction collectText(node: JSONContent): string {\n let text = ''\n if (node.text) {\n text += node.text\n }\n for (const child of node.content ?? []) {\n text += collectText(child)\n }\n return text\n}\n\nfunction tokenize(text: string): string[] {\n return text.match(/[\\u4e00-\\u9fa5]|[a-zA-Z0-9]+|\\s+|[^\\sa-zA-Z0-9\\u4e00-\\u9fa5]/g) ?? []\n}\n\n/** Classic LCS word diff with a size guard. */\nexport function wordDiff(beforeText: string, afterText: string): WordDiffPart[] {\n const a = tokenize(beforeText)\n const b = tokenize(afterText)\n if (a.length * b.length > 4_000_000) {\n return [\n { text: beforeText, type: 'del' },\n { text: afterText, type: 'add' },\n ]\n }\n // dp[i][j] = LCS length of a[i:], b[j:]\n const dp: Uint32Array[] = Array.from({ length: a.length + 1 }, () => new Uint32Array(b.length + 1))\n for (let i = a.length - 1; i >= 0; i--) {\n for (let j = b.length - 1; j >= 0; j--) {\n dp[i]![j] = a[i] === b[j] ? dp[i + 1]![j + 1]! + 1 : Math.max(dp[i + 1]![j]!, dp[i]![j + 1]!)\n }\n }\n const parts: WordDiffPart[] = []\n const push = (text: string, type: WordDiffPart['type']) => {\n const last = parts[parts.length - 1]\n if (last && last.type === type) {\n last.text += text\n } else {\n parts.push({ text, type })\n }\n }\n let i = 0\n let j = 0\n while (i < a.length && j < b.length) {\n if (a[i] === b[j]) {\n push(a[i]!, 'same')\n i++\n j++\n } else if (dp[i + 1]![j]! >= dp[i]![j + 1]!) {\n push(a[i]!, 'del')\n i++\n } else {\n push(b[j]!, 'add')\n j++\n }\n }\n while (i < a.length) {\n push(a[i++]!, 'del')\n }\n while (j < b.length) {\n push(b[j++]!, 'add')\n }\n return parts\n}\n\nfunction sameBlock(a: JSONContent, b: JSONContent): boolean {\n return JSON.stringify(a) === JSON.stringify(b)\n}\n\nexport function diffDocs(before: JSONContent, after: JSONContent): BlockDiffEntry[] {\n const beforeBlocks = topLevel(before)\n const afterBlocks = topLevel(after)\n const afterById = new Map<string, JSONContent>()\n for (const block of afterBlocks) {\n const id = blockId(block)\n if (id) {\n afterById.set(id, block)\n }\n }\n const seen = new Set<string>()\n const entries: BlockDiffEntry[] = []\n\n for (const block of beforeBlocks) {\n const id = blockId(block)\n if (id && afterById.has(id)) {\n seen.add(id)\n const next = afterById.get(id)!\n if (sameBlock(block, next)) {\n entries.push({ kind: 'unchanged', id, before: block, after: next })\n } else {\n entries.push({ kind: 'changed', id, before: block, after: next, wordDiff: wordDiff(collectText(block), collectText(next)) })\n }\n } else {\n entries.push({ kind: 'removed', id: id ?? undefined, before: block })\n }\n }\n for (const block of afterBlocks) {\n const id = blockId(block)\n if (id && seen.has(id)) {\n continue\n }\n if (!id || !beforeBlocks.some(b => blockId(b) === id)) {\n entries.push({ kind: 'added', id: id ?? undefined, after: block })\n }\n }\n return entries\n}\n\n/** Compact summary for the panel header. */\nexport function diffSummary(entries: BlockDiffEntry[]): { added: number; removed: number; changed: number } {\n let added = 0\n let removed = 0\n let changed = 0\n for (const entry of entries) {\n if (entry.kind === 'added') added++\n else if (entry.kind === 'removed') removed++\n else if (entry.kind === 'changed') changed++\n }\n return { added, removed, changed }\n}\n","import type { Editor, JSONContent } from '@tiptap/core'\n\n/**\n * Write-back protocol (ADR-0001 / product-definition §4): AI and host code\n * mutate the document by stable block IDs — never whole-doc rewrites.\n * Semantics mirror SliteML's modifyRange / appendBlocks / removeBlocks.\n */\n\nexport interface BlockHandle {\n /** stable block id (UniqueID extension); null when the block predates ids */\n id: string | null\n type: string\n pos: number\n node: import('@tiptap/pm/model').Node\n}\n\n/** Top-level blocks with their ids, in document order. */\nexport function getTopLevelBlocks(editor: Editor): BlockHandle[] {\n const blocks: BlockHandle[] = []\n editor.state.doc.forEach((node, offset) => {\n blocks.push({ id: (node.attrs.id as string | undefined) ?? null, type: node.type.name, pos: offset, node })\n })\n return blocks\n}\n\nfunction findBlockPosById(editor: Editor, id: string): number | null {\n let found: number | null = null\n editor.state.doc.forEach((node, offset) => {\n if (found === null && node.attrs.id === id) {\n found = offset\n }\n })\n return found\n}\n\nfunction newBlockId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID()\n }\n return `tessera-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`\n}\n\nfunction resolveBlocks(editor: Editor, blocks: JSONContent[]) {\n return blocks.map(json => {\n const clean = { ...json }\n // Write-back content carries fresh ids of its own: UniqueID skips nodes\n // that already have one, so the ids land inside the same transaction\n // (single undo step) instead of a follow-up append.\n clean.attrs = { ...(clean.attrs ?? {}), id: newBlockId() }\n return editor.state.schema.nodeFromJSON(clean)\n })\n}\n\nexport interface ModifyRangeOptions {\n /** first block to replace (default: first block in doc) */\n fromId?: string\n /** last block to replace, inclusive (default: fromId) */\n toId?: string\n content: JSONContent[]\n}\n\n/**\n * Replace the inclusive block range [fromId … toId] with `content`.\n * One transaction → one undo step.\n */\nexport function modifyRange(editor: Editor, options: ModifyRangeOptions): boolean {\n const blocks = getTopLevelBlocks(editor).filter(b => b.id)\n if (blocks.length === 0) {\n return false\n }\n const ids = blocks.map(b => b.id as string)\n const fromId = options.fromId ?? ids[0]\n const toId = options.toId ?? fromId\n\n let fromIndex = ids.indexOf(fromId)\n let toIndex = ids.indexOf(toId)\n if (fromIndex === -1 || toIndex === -1) {\n return false\n }\n if (fromIndex > toIndex) {\n ;[fromIndex, toIndex] = [toIndex, fromIndex]\n }\n\n const fromBlock = blocks[fromIndex]\n const toBlock = blocks[toIndex]\n const from = fromBlock.pos\n const to = toBlock.pos + toBlock.node.nodeSize\n\n const nodes = resolveBlocks(editor, options.content)\n const tr = editor.state.tr\n tr.replaceWith(from, to, nodes)\n editor.view.dispatch(tr)\n return true\n}\n\nexport interface AppendBlocksOptions {\n /** insert after this block (default: end of document) */\n afterId?: string\n content: JSONContent[]\n}\n\n/** Append blocks after `afterId` (or at the document end). */\nexport function appendBlocks(editor: Editor, options: AppendBlocksOptions): boolean {\n const nodes = resolveBlocks(editor, options.content)\n if (nodes.length === 0) {\n return false\n }\n let insertPos = editor.state.doc.content.size\n if (options.afterId) {\n const pos = findBlockPosById(editor, options.afterId)\n if (pos === null) {\n return false\n }\n const node = editor.state.doc.nodeAt(pos)\n if (!node) {\n return false\n }\n insertPos = pos + node.nodeSize\n }\n const tr = editor.state.tr\n tr.insert(insertPos, nodes)\n editor.view.dispatch(tr)\n return true\n}\n\n/** Remove blocks by ids. One transaction → one undo step. */\nexport function removeBlocks(editor: Editor, ids: string[]): boolean {\n if (ids.length === 0) {\n return false\n }\n const ranges: { from: number; to: number }[] = []\n editor.state.doc.forEach((node, offset) => {\n if (node.attrs.id && ids.includes(node.attrs.id)) {\n ranges.push({ from: offset, to: offset + node.nodeSize })\n }\n })\n if (ranges.length === 0) {\n return false\n }\n const tr = editor.state.tr\n for (let i = ranges.length - 1; i >= 0; i--) {\n tr.delete(ranges[i].from, ranges[i].to)\n }\n editor.view.dispatch(tr)\n return true\n}\n\n/** Read a block (and its subtree) by id as canonical JSON. */\nexport function getBlockJson(editor: Editor, id: string): JSONContent | null {\n const pos = findBlockPosById(editor, id)\n if (pos === null) {\n return null\n }\n const node = editor.state.doc.nodeAt(pos)\n return node ? node.toJSON() : null\n}\n"],"mappings":"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","names":["Node","mergeAttributes","Node","mergeAttributes","Node","mergeAttributes","Node","mergeAttributes","mergeAttributes","Mark","mergeAttributes","TextSelection","Mark","mergeAttributes","Extension","Extension","wrappingInputRule","Extension","TextSelection","Extension","Plugin","PluginKey","Extension","PluginKey","Extension","PluginKey","Extension","PluginKey","Suggestion","Extension","Plugin","PluginKey","Extension","PluginKey","Extension","Plugin","Extension","Plugin","Extension","Plugin","PluginKey","Decoration","DecorationSet","Extension","md","Extension","Extension","Plugin","PluginKey","Extension","Plugin","PluginKey","blockId","i","j","findBlockPosById"]}