plate-plugin-creator
GitHub用于构建和重构 Plate 编辑器插件,规范 Slate-first 架构、类型定义及 React/Plate 包装器边界。指导插件 API 设计、文件放置及核心契约遵循,确保语义所有权清晰。
触发场景
安装
npx skills add udecode/plate --skill plate-plugin-creator -g -y
SKILL.md
Frontmatter
{
"name": "plate-plugin-creator",
"metadata": {
"skiller": {
"source": ".agents\/rules\/plate-plugin-creator.mdc"
}
},
"description": "Build new Plate plugins with Slate-first architecture, sane typing, and explicit React\/Plate wrapper boundaries. Use when authoring or refactoring Plate plugin packages, deciding between createSlatePlugin vs createPlatePlugin, defining plugin APIs\/transforms\/options, or lifting semantic base plugins into React\/Plate wrappers."
}
Plate Plugin Creator
Repo-specific companion to Plate's core plugin APIs.
Before shaping a reusable public API, architecture decision, builder/factory pattern, naming convention, runtime/service boundary, or perf-sensitive public surface, read north-star first. This skill is the execution companion, not the constitutional source of truth.
Use this skill for Plate-specific plugin authorship: semantic ownership, authoring order, type-contract fidelity, and React/Plate wrapper boundaries.
Use docs-creator for public plugin docs.
North-Star Gate
Binary contract:
- If the lane materially changes reusable API shape, runtime boundaries,
builder/factory patterns, or reusable naming/layering, stop and route to
north-star first. Then include:
north-star updated- or
north-star reaffirmed: <section-name>
- If not, continue here for plugin execution mechanics.
Owner map:
| Owner | Scope |
|---|---|
north-star |
doctrine, API shape, runtime boundaries, perf law |
plate-plugin-creator |
plugin mechanics, typing, wrappers, file placement |
Do not restate long-form north-star law, precedence, or anti-pattern prose
here. Keep only the routing gate, short derived checklist, and execution
mechanics.
Derived checklist from north-star:
- Is the owner/layer explicit?
- Is this canonical semantics or local sugar?
- Is the config explicit and copyable?
- Does the shape add hidden runtime work on the hot path?
- Does core own a primitive here instead of feature semantics?
Repo Surfaces
packages/*/src/lib— semantic base plugins, transforms, parsers, rulespackages/*/src/react— Plate/React wrappers, hooks, node props, componentspackages/core/src/lib/plugin— Slate-first authoring primitivespackages/core/src/react/plugin— Plate wrapper primitivespackages/core/type-tests— plugin contract source of truth
Principles
- Start where semantics live. If the behavior matters without React, start
in
src/lib. - Use inference before ceremony. Reach for
createT*only when explicit contract control buys something real. - Wrap base plugins. If a semantic base already exists, lift it with
toPlatePluginortoTPlatePlugininstead of re-authoring it in React. - Design the API shape on purpose. Plugin-specific surfaces and merged editor surfaces are different tools.
- Use shared keys. Shipped plugin keys and cross-plugin references should
come from
packages/utils/src/lib/plate-keys.ts, not random string literals. - Core contracts beat precedent. Type tests and core authoring APIs outrank noisy old package examples.
- Keep the lane narrow. This skill owns plugin authoring, not public docs.
Critical Rules
Barrel & File Placement
- Never hand-write or hand-edit
index.ts/index.tsxbarrel files. Treat them as generated output only. - When adding, moving, renaming, or deleting public files under exported
package folders, run
pnpm brlafter the file work and before final verification. - If
pnpm brlproduces a broken barrel, fix the barrel generator/config or file placement. Do not patch the generatedindex.tsby hand afterbrl. - Any helper, matcher, fallback branch, or possible future fork logic that is
not part of the intended public contract should live under an
internal/directory. - Default to
internal/unless the user-facing API genuinely needs the file to be importable.
Creation Flow → creation-flow.md
- Start with the decision tree before writing code.
createSlatePlugin/createTSlatePluginown semantic base plugins.toPlatePlugin/toTPlatePluginlift a semantic base into the React/Plate surface.createPlatePlugin/createTPlatePluginare for real React/Plate-native plugins or bundles of existing Plate plugins.- If you only need to bundle existing Plate plugins, do not invent a fake base plugin first.
Typing & Context → typing.md
- Callback context already provides
editor,plugin,type,api,tf,getOptions,setOption, and friends. Use them. - Forbid
anyin source files. The only acceptable exception is non-type test code where the looseness is intentional and local to the test. - Do not thread
SlateEditorthrough callbacks, options, or helper signatures when plugin context already has the editor. - Prefer
KEYSfrompackages/utils/src/lib/plate-keys.tsfor shipped/shared plugin keys and cross-plugin references. Useeditor.getType(KEYS.foo)when you need the resolved node type. createTSlatePluginandcreateTPlatePluginare explicit-contract tools, not default ceremony.- Trust
packages/core/type-tests/*over stale package precedent.
Composition & API Shape → composition.md
extendApi/extendTransformsare plugin-specific surfaces.extendEditorApi/extendEditorTransformsfeed the merged editor surface.- Use
configurePluginto override nested child plugins instead of cloning their config by hand. - Use
overrideEditorwhen the real ownership is editor behavior, not random event glue. - For React-only augmentation of existing rendered nodes, prefer
inject.nodeProps.transformPropsbefore inventing wrapper components or heavier node plumbing. This is especially right when the augmentation needs hooks.
Hard Law
Slate-first, Plate-second.
If a plugin has meaningful document semantics without React, author the base in
packages/*/src/lib first. Add the React/Plate layer only when rendering,
hooks, or Plate-only editor integration is actually needed.
Named exceptions:
- React-only hook or
useHooksplugins - DOM/editor-surface plugins with no meaningful Slate-only base
- Plate-only bundle plugins that just compose existing Plate plugins
- React node-prop injection that truly depends on hooks or component context
Do Not Copy
- Do not start in
src/reactjust because the consumer eventually uses React. - Do not re-author a base plugin with
createPlatePluginjust to add a component or small wrapper config. - Do not hardcode shipped/shared plugin keys when
KEYSalready owns that contract. - Do not cargo-cult
({ editor }: { editor: SlateEditor }) => ...callback annotations when inference already knows the editor type. - Do not extract editor-locked helpers just to placate TypeScript.
- Do not create new public top-level files when
internal/is enough. - Do not treat
transformPropslike a universal replacement fornode.component,render, oruseHooks. Use it when the real job is prop augmentation. - Do not trust the loudest old plugin file over core APIs and type tests.
Key Patterns
// Good: semantic base first, thin Plate wrapper second.
export const BaseCommentPlugin = createTSlatePlugin<BaseCommentConfig>({
key: KEYS.comment,
}).extendApi(...);
export const CommentPlugin = toPlatePlugin(BaseCommentPlugin);
// Good: wrapper adds Plate-only child wiring without re-authoring semantics.
export const CodeBlockPlugin = toPlatePlugin(BaseCodeBlockPlugin, {
plugins: [CodeLinePlugin, CodeSyntaxPlugin],
});
// Good: direct Plate plugin when the job is React/editor integration.
export const EventEditorPlugin = createPlatePlugin({
key: 'eventEditor',
handlers: { ... },
});
// Good: bundle existing Plate plugins without fake base-plugin theater.
export const BasicBlocksPlugin = createPlatePlugin({
plugins: [BlockquotePlugin, HeadingPlugin, HorizontalRulePlugin],
});
Workflow
- Read creation-flow.md before choosing an API.
- Search the closest analog in
packages/*/src/lib,packages/*/src/react, andpackages/core/type-tests. - Decide whether this is:
- a semantic base plugin
- a Plate/React wrapper
- a React-native exception
- a bundle plugin
- Lock the contract shape:
- options
- plugin-specific API/transforms
- merged editor API/transforms
- nested child plugins
- Apply the typing rules before adding explicit annotations.
- Add docs only by handing off to docs-creator.
- Verify the smallest honest surface:
- package tests for semantic/plugin behavior
- type tests or targeted typecheck when public contract changed
- React tests only when the wrapper layer changed
Audit References
- plugin-authoring-audit.md — real repo examples of good patterns and cautionary ones
Detailed References
版本历史
- af5e430 当前 2026-08-20 19:27


