AI agents

Add a block or feature

Agent playbook for adding an own block or feature to @skaile/forge-editor: an ordered checklist where each step links to the tutorial chapter that shows it.

Two ways to add a block: Path A passes extensions and a commands transformer to SimpleEditor (no feature object); Path B ships an EditorFeature that composes with any preset. The tutorial builds the same „Hinweis" callout both ways; follow the chapters in order and use this list as the checklist.

  1. Node. Node.create in a Vue-free node.ts; group, content, attributes with parseHTML/renderHTML, commands and a free shortcut. Tutorial: own block, path A
  2. Block IDs. editorBlock: true if AI operations, flash/reveal, paste de-duplication or the server ID backfill should reach it. Tutorial: own block, path A
  3. Abilities. abilities on the node for what is allowed inside; for a custom ability id, grant it through the abilities prop (root). Tutorial: own feature, path B
  4. Markdown. renderMarkdown, markdownTokenName, markdownTokenizer, parseMarkdown with syntax no other stage claims; test the round trip (getMarkdown() → parseBlocks), including multi-block bodies. Tutorial: own block, path A
  5. View and CSS. Node view in a separate index.ts (Node.extend), stylesheet imported after core.css. Tutorial: own block, path A, CSS order: CSS and UI-provider requirements
  6. Path A. extensions (constant) and the commands transformer prop (a command with slash: {}), nothing else needed. Tutorial: own block, path A
  7. Path B. An EditorFeature: extensions, then commands (one CommandDef per command with toolbar and/or slash placement, creates, ability) and toolbarGroups if you need a new group, blockActions with your ability, conversions with a custom target; requires for features you depend on. Tutorial: own feature, path B, every member: Feature contract
  8. Compose. defineEditor({ features: [...advancedEditor().features, yourFeature()] }) in setup (advancedEditor from /vue/advanced or /react/advanced); mount with EditorSurface and pass abilities for custom ability ids; add blockUiFeature() to a smaller list when you use hover actions. Tutorial: compose features, Tutorial: own feature, path B
  9. Server. When documents with your block are collaborative, pass YourNode in the server's schema option (provideEditorServer({ ports, schema: () => [...advancedSchemaExtensions(), YourNode] }); the collab server uses it instead of advancedSchemaExtensions()), or build getSchema([...advancedSchemaExtensions(), YourNode]) in your own Hocuspocus server. Tutorial: backend and collaboration, Vue-free schema for servers
  10. AI. Decide what the model should see (renderMarkdown) and write; describe the block in aiContext.blocks (id, label, description, syntax, example, matching your Markdown); aiContext is additive, a block id may be described only once; add a custom conversion provider if the block should be a convert target. Tutorial: AI, AI guide
  11. Bundle proof. If you ship the block in a package, add a fixture and a FIXTURES entry for bun run check:editor-entries (Dependency rules); bun run check:editor-composition covers defineEditor validation. Verify

Then check the invariants.

Copyright © 2026