Skip to content

Commit f431866

Browse files
committed
v2
1 parent a1c4529 commit f431866

372 files changed

Lines changed: 20010 additions & 8220 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/rules/plate-next.mdc

Lines changed: 246 additions & 13 deletions
Large diffs are not rendered by default.

.agents/skills/plate-next/SKILL.md

Lines changed: 239 additions & 13 deletions
Large diffs are not rendered by default.

AGENTS.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ Primary user-facing entrypoints:
5454
- `auto` as the ergonomic Plate/Plite front door: route public GitHub queue
5555
prompts to `maintainer`, post-merge/current-tree closure to `autoclosure`,
5656
and internal Plate/Plite quality prompts to `auto`.
57+
- `plate-next` for Plate v2 cleanup review: deeply audit migrated Plate files,
58+
APIs, and packages against the Plite boundary, then cut old Slate/Plate
59+
compatibility sludge or route the decision to `plate-plan`.
5760
- `autoclosure` for post-merge/current-tree until-clean closure.
5861
- `maintainer` for public Plate/Plite issue, PR, and security queue work.
5962
- `architecture-cleanup` for repo-grounded architecture/code cleanup,
@@ -81,6 +84,9 @@ Default routing:
8184
question -> `maintainer` unless the user explicitly names a narrower owner.
8285
- Internal Plate/Plite quality, behavior, perf, browser proof, API cleanup,
8386
benchmark repair, docs/API cohesion, or long autonomous loop -> `auto`.
87+
- Plate v2 cleanup review, "why does this migrated Plate helper exist?",
88+
old Slate compatibility cuts in Plate/Core, or no-arg autopilot for the next
89+
Plate-to-Plite cleanup packet -> `plate-next`.
8490
- Post-merge, current-tree, teammate branch, external PR, ready-to-commit, or
8591
until-clean closure of already-applied work -> `autoclosure`.
8692
- Broad architecture cleanup, refactor opportunities, module consolidation,

apps/www/public/r/comment-docs.json

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

apps/www/public/r/comment-kit.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
"files": [
1414
{
1515
"path": "src/registry/components/editor/plugins/comment-kit.tsx",
16-
"content": "'use client';\n\nimport type { ExtendConfig, Path } from 'platejs';\n\nimport {\n type BaseCommentConfig,\n BaseCommentPlugin,\n getDraftCommentKey,\n} from '@platejs/comment';\nimport { toTPlatePlugin } from 'platejs/react';\n\nimport { CommentLeaf } from '@/registry/ui/comment-node';\nimport { getDiscussionClickTarget } from './discussion-kit';\n\ntype CommentConfig = ExtendConfig<\n BaseCommentConfig,\n {\n activeId: string | null;\n commentingBlock: Path | null;\n hoverId: string | null;\n }\n>;\n\nexport const commentPlugin = toTPlatePlugin<CommentConfig>(BaseCommentPlugin, {\n handlers: {\n onClick: ({ api, event, setOption, type }) => {\n const activeTarget = getDiscussionClickTarget({\n selector: `.slate-${type}`,\n target: event.target,\n });\n\n if (!activeTarget) {\n setOption('activeId', null);\n return;\n }\n\n const commentEntry = api.comment?.node();\n\n setOption(\n 'activeId',\n commentEntry ? (api.comment?.nodeId(commentEntry[0]) ?? null) : null\n );\n },\n },\n options: {\n activeId: null,\n commentingBlock: null,\n hoverId: null,\n },\n})\n .extendTransforms(\n ({\n editor,\n setOption,\n tf: {\n comment: { setDraft },\n },\n }) => ({\n setDraft: () => {\n if (editor.api.isCollapsed()) {\n editor.tf.select(editor.api.block()![1]);\n }\n\n setDraft();\n\n editor.tf.collapse();\n setOption('activeId', getDraftCommentKey());\n setOption('commentingBlock', editor.selection!.focus.path.slice(0, 1));\n },\n })\n )\n .configure({\n node: { component: CommentLeaf },\n shortcuts: {\n setDraft: { keys: 'mod+shift+m' },\n },\n });\n\nexport const CommentKit = [commentPlugin];\n",
16+
"content": "'use client';\n\nimport type { ExtendConfig, Path } from 'platejs';\n\nimport { TextApi } from 'platejs';\nimport {\n type BaseCommentConfig,\n BaseCommentPlugin,\n getDraftCommentKey,\n} from '@platejs/comment';\nimport { toPlatePlugin } from 'platejs/react';\n\nimport { CommentLeaf } from '@/registry/ui/comment-node';\nimport { getDiscussionClickTarget } from './discussion-kit';\n\ntype CommentConfig = ExtendConfig<\n BaseCommentConfig,\n {\n activeId: string | null;\n commentingBlock: Path | null;\n hoverId: string | null;\n }\n>;\n\nexport const commentPlugin = toPlatePlugin<CommentConfig>(BaseCommentPlugin, {\n handlers: {\n onClick: ({ api, event, setOption, type }) => {\n const activeTarget = getDiscussionClickTarget({\n selector: `.plite-${type}`,\n target: event.target,\n });\n\n if (!activeTarget) {\n setOption('activeId', null);\n return;\n }\n\n const commentEntry = api.comment?.node();\n\n setOption(\n 'activeId',\n commentEntry ? (api.comment?.nodeId(commentEntry[0]) ?? null) : null\n );\n },\n },\n options: {\n activeId: null,\n commentingBlock: null,\n hoverId: null,\n },\n})\n .extendTx(({ editor, setOption, type }) => (tx) => ({\n setDraft: (options = {}) => {\n const commentingBlock = editor.selection?.focus.path.slice(0, 1) ?? null;\n\n if (editor.api.isCollapsed()) {\n const blockEntry = editor.api.block();\n\n if (blockEntry) {\n tx.selection.set(blockEntry[1]);\n }\n }\n\n tx.nodes.set(\n {\n [getDraftCommentKey()]: true,\n [type]: true,\n },\n { match: TextApi.isText, split: true, ...options }\n );\n\n tx.selection.collapse();\n setOption('activeId', getDraftCommentKey());\n setOption('commentingBlock', commentingBlock);\n },\n }))\n .configure({\n node: { component: CommentLeaf },\n shortcuts: {\n setDraft: { keys: 'mod+shift+m' },\n },\n });\n\nexport const CommentKit = [commentPlugin];\n",
1717
"type": "registry:component",
1818
"target": "@components/editor/plugins/comment-kit.tsx"
1919
}
2020
],
2121
"type": "registry:component"
22-
}
22+
}

apps/www/public/r/registry.json

Lines changed: 9 additions & 5 deletions
Large diffs are not rendered by default.

apps/www/public/r/suggestion-docs.json

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

apps/www/public/r/suggestion-kit.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
"files": [
1414
{
1515
"path": "src/registry/components/editor/plugins/suggestion-kit.tsx",
16-
"content": "'use client';\n\nimport type { Element } from '@platejs/slate';\nimport type {\n ExtendConfig,\n TInlineSuggestionData,\n TSuggestionData,\n TSuggestionText,\n} from 'platejs';\n\nimport { KEYS, TextApi, TrailingBlockPlugin } from 'platejs';\nimport {\n type BaseSuggestionConfig,\n BaseSuggestionPlugin,\n} from '@platejs/suggestion';\nimport { toTPlatePlugin } from 'platejs/react';\n\nimport {\n SuggestionLeaf,\n SuggestionLineBreak,\n VoidRemoveSuggestionOverlay,\n} from '@/registry/ui/suggestion-node';\nimport {\n discussionPlugin,\n getDiscussionBlockClickTarget,\n getDiscussionClickTarget,\n} from './discussion-kit';\n\nexport type SuggestionConfig = ExtendConfig<\n BaseSuggestionConfig,\n {\n activeId: string | null;\n hoverId: string | null;\n }\n>;\n\nconst INLINE_SUGGESTION_TARGET_PLUGINS = [\n KEYS.date,\n KEYS.inlineEquation,\n KEYS.link,\n KEYS.mention,\n];\n\nfunction getInlineSuggestionData(editor: any, element: Element) {\n const suggestionApi = editor.getPluginApi(BaseSuggestionPlugin).suggestion;\n const data = suggestionApi.suggestionData(element) as\n | TSuggestionData\n | TInlineSuggestionData\n | undefined;\n\n if (data) return data;\n if (typeof suggestionApi.dataList !== 'function') return;\n\n for (const child of element.children) {\n if (!TextApi.isText(child)) continue;\n\n const childData = suggestionApi.dataList(child as TSuggestionText).at(-1);\n\n if (childData) return childData;\n }\n}\n\nexport const suggestionPlugin = toTPlatePlugin<SuggestionConfig>(\n BaseSuggestionPlugin,\n ({ editor }) => ({\n options: {\n activeId: null,\n currentUserId: editor.getOption(discussionPlugin, 'currentUserId'),\n hoverId: null,\n },\n })\n).configure({\n handlers: {\n // unset active suggestion when clicking outside of suggestion\n onClick: ({ api, event, setOption, type }) => {\n const markTarget = getDiscussionClickTarget({\n selector: `.slate-${type}`,\n target: event.target,\n });\n const blockTarget = markTarget\n ? null\n : getDiscussionBlockClickTarget({\n target: event.target,\n });\n\n if (!markTarget && !blockTarget) {\n setOption('activeId', null);\n return;\n }\n\n const suggestionEntry = api.suggestion?.node({\n isText: !blockTarget,\n });\n\n setOption(\n 'activeId',\n suggestionEntry\n ? (api.suggestion?.nodeId(suggestionEntry[0]) ?? null)\n : null\n );\n },\n },\n inject: {\n isElement: true,\n nodeProps: {\n nodeKey: '',\n styleKey: 'cssText',\n transformProps: ({ editor, element, props }) => {\n if (!element) return props;\n\n const suggestionData = getInlineSuggestionData(editor, element);\n\n if (!suggestionData) return props;\n\n return {\n ...props,\n 'data-inline-suggestion': suggestionData.type,\n };\n },\n transformStyle: () => ({}) as CSSStyleDeclaration,\n },\n targetPlugins: INLINE_SUGGESTION_TARGET_PLUGINS,\n },\n render: {\n belowNodes: SuggestionLineBreak as any,\n belowRootNodes: VoidRemoveSuggestionOverlay as any,\n node: SuggestionLeaf,\n },\n});\n\nconst trailingBlockPlugin = TrailingBlockPlugin.configure({\n options: {\n insert: (editor, { insert }) => {\n editor\n .getPluginApi(suggestionPlugin)\n .suggestion.withoutSuggestions(insert);\n },\n },\n});\n\nexport const SuggestionKit = [suggestionPlugin, trailingBlockPlugin];\n",
16+
"content": "'use client';\n\nimport type { Element } from '@platejs/plite';\nimport type {\n ExtendConfig,\n TInlineSuggestionData,\n TSuggestionData,\n TSuggestionText,\n} from 'platejs';\n\nimport { KEYS, TextApi, TrailingBlockPlugin } from 'platejs';\nimport {\n type BaseSuggestionConfig,\n BaseSuggestionPlugin,\n} from '@platejs/suggestion';\nimport { toPlatePlugin } from 'platejs/react';\n\nimport {\n SuggestionLeaf,\n SuggestionLineBreak,\n VoidRemoveSuggestionOverlay,\n} from '@/registry/ui/suggestion-node';\nimport {\n discussionPlugin,\n getDiscussionBlockClickTarget,\n getDiscussionClickTarget,\n} from './discussion-kit';\n\nexport type SuggestionConfig = ExtendConfig<\n BaseSuggestionConfig,\n {\n activeId: string | null;\n hoverId: string | null;\n }\n>;\n\nconst INLINE_SUGGESTION_TARGET_PLUGINS = [\n KEYS.date,\n KEYS.inlineEquation,\n KEYS.link,\n KEYS.mention,\n];\n\nfunction getInlineSuggestionData(editor: any, element: Element) {\n const suggestionApi = editor.getPluginApi(BaseSuggestionPlugin).suggestion;\n const data = suggestionApi.suggestionData(element) as\n | TSuggestionData\n | TInlineSuggestionData\n | undefined;\n\n if (data) return data;\n if (typeof suggestionApi.dataList !== 'function') return;\n\n for (const child of element.children) {\n if (!TextApi.isText(child)) continue;\n\n const childData = suggestionApi.dataList(child as TSuggestionText).at(-1);\n\n if (childData) return childData;\n }\n}\n\nexport const suggestionPlugin = toPlatePlugin<SuggestionConfig>(\n BaseSuggestionPlugin,\n ({ editor }) => ({\n options: {\n activeId: null,\n currentUserId: editor.getOption(discussionPlugin, 'currentUserId'),\n hoverId: null,\n },\n })\n).configure({\n handlers: {\n // unset active suggestion when clicking outside of suggestion\n onClick: ({ api, event, setOption, type }) => {\n const markTarget = getDiscussionClickTarget({\n selector: `.plite-${type}`,\n target: event.target,\n });\n const blockTarget = markTarget\n ? null\n : getDiscussionBlockClickTarget({\n target: event.target,\n });\n\n if (!markTarget && !blockTarget) {\n setOption('activeId', null);\n return;\n }\n\n const suggestionEntry = api.suggestion?.node({\n isText: !blockTarget,\n });\n\n setOption(\n 'activeId',\n suggestionEntry\n ? (api.suggestion?.nodeId(suggestionEntry[0]) ?? null)\n : null\n );\n },\n },\n inject: {\n isElement: true,\n nodeProps: {\n nodeKey: '',\n styleKey: 'cssText',\n transformProps: ({ editor, element, props }) => {\n if (!element) return props;\n\n const suggestionData = getInlineSuggestionData(editor, element);\n\n if (!suggestionData) return props;\n\n return {\n ...props,\n 'data-inline-suggestion': suggestionData.type,\n };\n },\n transformStyle: () => ({}) as CSSStyleDeclaration,\n },\n targetPlugins: INLINE_SUGGESTION_TARGET_PLUGINS,\n },\n render: {\n belowNodes: SuggestionLineBreak as any,\n belowRootNodes: VoidRemoveSuggestionOverlay as any,\n node: SuggestionLeaf,\n },\n});\n\nconst trailingBlockPlugin = TrailingBlockPlugin.configure({\n options: {\n insert: (editor, { insert }) => {\n editor\n .getPluginApi(suggestionPlugin)\n .suggestion.withoutSuggestions(insert);\n },\n },\n});\n\nexport const SuggestionKit = [suggestionPlugin, trailingBlockPlugin];\n",
1717
"type": "registry:component",
1818
"target": "@components/editor/plugins/suggestion-kit.tsx"
1919
}
2020
],
2121
"type": "registry:component"
22-
}
22+
}

0 commit comments

Comments
 (0)