Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5e60288
docs(exploration): explore tiptap to blocknote editor migration
Jul 13, 2026
603ac25
feat(editor): BlockNote-based XNetEditor core with xNet schema specs …
Jul 13, 2026
c50b07d
feat(plugins)!: EditorContribution carries BlockNote specs, not TipTa…
Jul 13, 2026
da16261
feat(editor): BlockNote Expo WebView embed, e2e retarget, changelog f…
Jul 13, 2026
b19c753
docs(exploration): check off 0312 phase 1-2 core items
Jul 13, 2026
85c9700
feat(editor): swap apps/web to XNetEditor; re-target fragment readers…
Jul 13, 2026
37ce3f2
docs(exploration): check off 0312 fragment-reader re-targeting
Jul 13, 2026
de20120
docs(exploration): record 0312 comments decision (keep 0276 panel thr…
Jul 13, 2026
6a5a15e
feat(plugins)!: AI page-markdown surface reads/writes BlockNote conte…
Jul 13, 2026
4191078
docs(exploration): check off 0312 AI surface + linkify items
Jul 13, 2026
a376cbd
feat(editor): swap Electron PageView/MeetingsView to XNetEditor; meet…
Jul 13, 2026
86b97b3
docs(exploration): check off 0312 phase 1 core swap + phase 3 surfaces
Jul 13, 2026
7df7a3f
feat(editor): BlockNote seed docs in devtools; canvas inline page sur…
Jul 13, 2026
883655d
docs(exploration): check off 0312 devtools seed regeneration
Jul 13, 2026
8a9bce8
feat(editor)!: delete the TipTap chrome — BlockNote is the editor (0312)
Jul 13, 2026
2a7b80f
docs(changeset): document EditorContribution BlockNote retype as majo…
Jul 13, 2026
1437fd1
fix(web): split BlockNote/Mantine/ProseMirror into editor-vendor chun…
Jul 13, 2026
9d75a18
test(editor): two-peer Yjs convergence + all-spec round-trip; dedupe …
Jul 13, 2026
786aeea
docs(exploration): check off tiptap to blocknote editor migration
Jul 13, 2026
e86a9fe
Merge remote-tracking branch 'origin/main' into claude/0312-tiptap-to…
Jul 13, 2026
0a4b222
fix(ci): prettier pass, BlockNote editor-ux unit tests, storybook shi…
Jul 13, 2026
01d5e66
fix(editor): stable editor identity, Mantine 8 pin, contiguous slash …
Jul 13, 2026
58478ef
style(editor): prettier pass on math spec
Jul 13, 2026
27e41c4
Merge remote-tracking branch 'origin/main' into claude/0312-tiptap-to…
Jul 13, 2026
c57932d
Merge remote-tracking branch 'origin/main' into claude/0312-tiptap-to…
Jul 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .changeset/ai-surface-blocknote-page-markdown.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
'@xnetjs/plugins': major
---

AI page-markdown surface re-targeted to the BlockNote editor (exploration 0312).

- **Breaking**: the page-markdown apply adapter mode `'tiptap-yjs'` is renamed
to `'blocknote-yjs'` in `AiPageMarkdownApplyAdapterResult['mode']` and
`AiPageMarkdownApplyResult['mode']`. Adapters that returned
`mode: 'tiptap-yjs'` must return `'blocknote-yjs'` (or `'yjs'`/`'custom'`).
- New Yjs-fragment ↔ markdown conversion for BlockNote (`content-v4`)
documents, dependency-light (walks the Yjs XML tree directly, no editor/DOM):
- `xnetPageFragmentToMarkdown(doc)` reads the BlockNote fragment
(paragraph/heading/lists/check items/code/quote/callout/table + inline
`mention`/`hashtag`/`wikilink`/`inlineMath` atoms), falling back to the
legacy TipTap `content` fragment when `content-v4` is empty
(`blockNoteFragmentToMarkdown` / `legacyFragmentToMarkdown` are also
exported).
- `replaceXNetPageFragmentWithMarkdown(doc, markdown)` writes the AI
markdown subset (paragraphs, headings, bullet/numbered/check lists with
nesting, fenced code, quotes, callouts, wikilinks) as BlockNote PM XML —
`blockGroup > blockContainer` (unique `id` per block) wrappers — in one
Yjs transaction.
- `createBlockNotePageMarkdownAdapter({ resolveDoc })` packages both as an
`AiPageMarkdownApplyAdapter` (plus `readMarkdown`) for
`xnet_apply_page_markdown`, replacing the TipTap-era document bridge.
- `XNET_PAGE_FRAGMENT_FIELD` (`'content-v4'`) and
`XNET_PAGE_LEGACY_FRAGMENT_FIELD` (`'content'`) constants.
- `@xnetjs/plugins` now depends on `yjs`; the unused `@tiptap/core`
devDependency is gone.
19 changes: 19 additions & 0 deletions .changeset/blocknote-editor-contribution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
'@xnetjs/plugins': major
---

`EditorContribution` carries BlockNote specs instead of TipTap extensions (exploration 0312).

- **Breaking**: `EditorContribution.extension` (TipTap `Extension`) and
`EditorContribution.toolbar` (`ToolbarContribution`, removed entirely) are
gone. Plugins now contribute `blockSpecs` / `inlineContentSpecs` /
`styleSpecs` (opaque BlockNote spec objects keyed by spec name) plus
behavior-only `slashMenuItems`.
- **Breaking**: the editor schema-skew guard is spec-based —
`isSchemaDefiningExtension` is replaced by `isSchemaDefiningContribution`,
and `findEditorSchemaRisks` / `warnOnEditorSchemaRisks` take the host's
statically bundled spec names and flag any contributed spec outside that
set (0205 invariant: schema specs must be identical across all
collaborators or Yjs silently drops content).
- `SlashCommandContext.editor` is now a BlockNote editor instance.
- The `@tiptap/core` dependency is removed.
29 changes: 29 additions & 0 deletions .changeset/blocknote-fragment-readers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
'@xnetjs/data': minor
'@xnetjs/history': minor
'@xnetjs/react': minor
'@xnetjs/runtime': patch
---

Yjs fragment readers understand the BlockNote document schema (exploration 0312).

Documents now live in the `content-v4` fragment using BlockNote's ProseMirror
shape (`blockGroup > blockContainer > blockContent`); the legacy TipTap
`content` fragment remains readable as a fallback until each doc is lazily
imported.

- `@xnetjs/data`: `getRichTextPlainText` extracts text from BlockNote-shaped
rich-text cells, including the new inline atoms (`mention` → `@label`,
`hashtag` → `#name`, `wikilink` → title, `inlineMath` → latex), while still
reading legacy TipTap-shaped cells.
- `@xnetjs/history`: version-diff text extraction prefers `content-v4` (legacy
`content` fallback) and renders BlockNote inline atoms as readable text.
- `@xnetjs/react`: new `useMergedEditorContributions` /
`mergeEditorContributions` (+ `MergedEditorContributions` type) collect
plugin-contributed BlockNote `blockSpecs`/`inlineContentSpecs`/`styleSpecs`
and slash menu items from the plugin registry, running the editor
schema-skew guard (`warnOnEditorSchemaRisks`) against the host's statically
bundled spec names and excluding un-bundled (skew-hazard) specs.
- `@xnetjs/runtime`: blob-CID retention scanning now also walks the
`content-v4` and `content` fragments, so blobs referenced from page
documents are discovered.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ jobs:
run: pnpm --filter @xnetjs/e2e-tests exec playwright install-deps chromium webkit

- name: Run focused editor interaction tests
run: pnpm --filter @xnetjs/editor exec vitest run src/nodeviews/hooks/useNodeFocus.test.ts src/components/FloatingToolbar.test.tsx src/components/SlashMenu.test.tsx src/components/editor-ux-state.test.ts src/extensions/live-preview/inline-marks.integration.test.ts
run: pnpm --filter @xnetjs/editor exec vitest run src/blocknote/collab-convergence.test.tsx src/blocknote/doc-utils.test.ts src/blocknote/legacy-import.test.ts

- name: Start web app
run: pnpm --filter xnet-web dev --host 127.0.0.1 --port 5173 > /tmp/xnet-web.log 2>&1 &
Expand Down
9 changes: 9 additions & 0 deletions .storybook/shims/xnet-plugins-browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,12 @@ export type {
} from '../../packages/plugins/src/workspace'
export type { SlotContribution, SlotRegion } from '../../packages/plugins/src/contributions'
export { evaluateInstallConsent, scaffoldPlugin } from '../../packages/plugins/src/ecosystem'

// Editor schema-skew guard (0205, spec-based since 0312) — used by
// packages/react's useMergedEditorContributions.
export {
findEditorSchemaRisks,
isSchemaDefiningContribution,
warnOnEditorSchemaRisks
} from '../../packages/plugins/src/editor-schema-safety'
export type { EditorSchemaRisk } from '../../packages/plugins/src/editor-schema-safety'
6 changes: 3 additions & 3 deletions apps/electron/src/renderer/components/MeetingsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
* The recorder/list/detail cores are shared from @xnetjs/views (0277
* shared-view-core pattern); this wrapper keeps the desktop deltas: local
* mode state (the desktop shell has no router — same idiom as
* DataWorkspaceView), the EditorSurface notes editor, and the close
* DataWorkspaceView), the XNetEditor notes editor, and the close
* affordance back to the home canvas. `window.xnetMeetings` is present here,
* so the recorder runs at the system-audio tier with the native engines.
*/

import { EditorSurface } from '@xnetjs/editor/react'
import { XNetEditor } from '@xnetjs/editor/react'
import { MeetingDetailView, MeetingRecorderView, MeetingsListView } from '@xnetjs/views'
import { ArrowLeft, X } from 'lucide-react'
import React, { useState } from 'react'
Expand Down Expand Up @@ -58,7 +58,7 @@ export function MeetingsView({ onClose }: MeetingsViewProps): React.ReactElement
<MeetingDetailView
className="min-h-0 flex-1"
meetingId={mode.meetingId}
renderNotes={({ doc }) => <EditorSurface ydoc={doc} surfaceMode="page" />}
renderNotes={({ doc }) => <XNetEditor ydoc={doc} />}
/>
) : (
<MeetingsListView
Expand Down
Loading
Loading