xiaolai/vmark

tiptap-editor

Tiptap editor API patterns for vmark WYSIWYG development. Use when working with editor commands, node traversal, selection handling, or format operations.

First seen Feb 15, 2026

Installation

$ npx skills add xiaolai/vmark --skill tiptap-editor

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from xiaolai/vmark · top by installs.

npx skills add xiaolai/vmark

Browse all from xiaolai/vmark

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 556
License LICENSE
Default branch main
Open issues 3
Status Active

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 2,919 B
  • docs SUMMARY.md 175 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 292 installs

SKILL.md

Tiptap Editor API Patterns

Overview

This skill documents proper Tiptap API usage patterns for vmark development. It helps distinguish when to use Tiptap's high-level API vs direct ProseMirror access.

When to Use Tiptap API

Always prefer Tiptap API for:

  • Format commands (bold, italic, underline, etc.)
  • Block type changes (heading, paragraph, code block)
  • List operations (bullet, ordered, toggle, indent/outdent)
  • Table operations via Tiptap table extension
  • Content insertion and replacement
  • Editor state queries (isActive, getAttributes)

Tiptap patterns to use:

// Direct commands
editor.commands.toggleBold()
editor.commands.setHeading({ level: 2 })
editor.commands.setContent(doc, { emitUpdate: false })

// Chained commands (for multiple operations)
editor.chain().focus().setHeading({ level: 2 }).run()
editor.chain().focus().toggleMark("underline").run()

// State queries
editor.isActive("blockquote")
editor.isActive("heading", { level: 2 })
editor.getAttributes("link")

When Direct ProseMirror is Appropriate

Use ProseMirror directly for:

  • Markdown conversion layer (proseMirrorToMdast.ts, mdastToProseMirror.ts)
  • Multi-cursor/selection subclassing (MultiSelection.ts)
  • Custom node views
  • Low-level transaction manipulation
  • Schema-level operations

Known Issues in vmark

1. cursorHandlers.ts Block Boundary Issue

src/hooks/mcpBridge/cursorHandlers.ts uses doc.textContent which flattens the document and loses block boundaries. The correct approach is to use $pos helpers:

// WRONG - loses block structure
const text = doc.textContent;

// RIGHT - respects block boundaries
const $pos = doc.resolve(from);
const currentNode = $pos.parent;
const blockStart = $pos.before($pos.depth);
const blockEnd = $pos.after($pos.depth);

2. Cursor Sync Drift After WYSIWYG Edits

sourceLine attributes are only set on initial parse. After WYSIWYG edits that add/remove blocks, line numbers no longer match the source. This is a known limitation.

3. HtmlNodeView.ts Store Issue

src/plugins/markdownArtifacts/HtmlNodeView.ts writes cursor info to wrong store.

References

  • references/patterns.md - Detailed API patterns and $pos usage
  • references/examples.md - Real code examples from vmark codebase

Workflow

  1. Identify operation type (format, block, selection, traversal)
  2. Check if Tiptap has a built-in command for it
  3. Use editor.commands.xxx() for single operations
  4. Use editor.chain().focus().xxx().run() when focus is needed or chaining
  5. For node traversal, use doc.resolve(pos) to get $pos helpers
  6. For state queries, use editor.isActive() or editor.getAttributes()