You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@answer.apache.org by ro...@apache.org on 2025/12/25 03:52:03 UTC

(answer) 10/12: Remove TipTap editor utility files including commands, constants, error handling, events, position conversion, and table extension to streamline the editor's functionality and reduce code complexity.

This is an automated email from the ASF dual-hosted git repository.

robin0716 pushed a commit to branch feat/1.7.2/ui
in repository https://gitbox.apache.org/repos/asf/answer.git

commit aa7e19b89675a75124d0d3141b8524909802eff0
Author: robin <ro...@rnode.me>
AuthorDate: Mon Dec 22 18:25:42 2025 +0800

    Remove TipTap editor utility files including commands, constants, error handling, events, position conversion, and table extension to streamline the editor's functionality and reduce code complexity.
---
 ui/package.json                                    |   9 +-
 ui/pnpm-lock.yaml                                  | 671 +------------------
 ui/src/components/Editor/RichEditor.tsx            | 206 ------
 ui/src/components/Editor/index.tsx                 |  40 +-
 ui/src/components/Editor/utils/tiptap/adapter.ts   |  59 --
 ui/src/components/Editor/utils/tiptap/base.ts      | 358 ----------
 ui/src/components/Editor/utils/tiptap/commands.ts  | 720 ---------------------
 ui/src/components/Editor/utils/tiptap/constants.ts |  48 --
 .../components/Editor/utils/tiptap/errorHandler.ts | 155 -----
 ui/src/components/Editor/utils/tiptap/events.ts    | 104 ---
 ui/src/components/Editor/utils/tiptap/position.ts  | 147 -----
 .../Editor/utils/tiptap/tableExtension.ts          |  81 ---
 12 files changed, 5 insertions(+), 2593 deletions(-)

diff --git a/ui/package.json b/ui/package.json
index 005a6aba..b88fc12d 100644
--- a/ui/package.json
+++ b/ui/package.json
@@ -21,13 +21,6 @@
     "@codemirror/language-data": "^6.5.0",
     "@codemirror/state": "^6.5.0",
     "@codemirror/view": "^6.26.1",
-    "@tiptap/core": "^3.13.0",
-    "@tiptap/extension-image": "^3.13.0",
-    "@tiptap/extension-placeholder": "^3.13.0",
-    "@tiptap/extension-table": "^3.13.0",
-    "@tiptap/markdown": "^3.13.0",
-    "@tiptap/react": "^3.13.0",
-    "@tiptap/starter-kit": "^3.13.0",
     "axios": "^1.7.7",
     "bootstrap": "^5.3.2",
     "bootstrap-icons": "^1.10.5",
@@ -107,4 +100,4 @@
     "pnpm": ">=9"
   },
   "license": "MIT"
-}
\ No newline at end of file
+}
diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml
index 3fa75e7b..89a37ab1 100644
--- a/ui/pnpm-lock.yaml
+++ b/ui/pnpm-lock.yaml
@@ -20,27 +20,6 @@ importers:
       '@codemirror/view':
         specifier: ^6.26.1
         version: 6.35.3
-      '@tiptap/core':
-        specifier: ^3.13.0
-        version: 3.13.0(@tiptap/pm@3.13.0)
-      '@tiptap/extension-image':
-        specifier: ^3.13.0
-        version: 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))
-      '@tiptap/extension-placeholder':
-        specifier: ^3.13.0
-        version: 3.13.0(@tiptap/extensions@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0))
-      '@tiptap/extension-table':
-        specifier: ^3.13.0
-        version: 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)
-      '@tiptap/markdown':
-        specifier: ^3.13.0
-        version: 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)
-      '@tiptap/react':
-        specifier: ^3.13.0
-        version: 3.13.0(@floating-ui/dom@1.7.4)(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
-      '@tiptap/starter-kit':
-        specifier: ^3.13.0
-        version: 3.13.0
       axios:
         specifier: ^1.7.7
         version: 1.7.9
@@ -1245,15 +1224,6 @@ packages:
     resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==}
     engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
 
-  '@floating-ui/core@1.7.3':
-    resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==}
-
-  '@floating-ui/dom@1.7.4':
-    resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==}
-
-  '@floating-ui/utils@0.2.10':
-    resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==}
-
   '@fullhuman/postcss-purgecss@4.1.3':
     resolution: {integrity: sha512-jqcsyfvq09VOsMXxJMPLRF6Fhg/NNltzWKnC9qtzva+QKTxerCO4esG6je7hbnmkpZtaDyPTwMBj9bzfWorsrw==}
     peerDependencies:
@@ -1497,9 +1467,6 @@ packages:
     peerDependencies:
       react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1
 
-  '@remirror/core-constants@3.0.0':
-    resolution: {integrity: sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==}
-
   '@restart/hooks@0.4.16':
     resolution: {integrity: sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==}
     peerDependencies:
@@ -1717,177 +1684,6 @@ packages:
     peerDependencies:
       '@testing-library/dom': '>=7.21.4'
 
-  '@tiptap/core@3.13.0':
-    resolution: {integrity: sha512-iUelgiTMgPVMpY5ZqASUpk8mC8HuR9FWKaDzK27w9oWip9tuB54Z8mePTxNcQaSPb6ErzEaC8x8egrRt7OsdGQ==}
-    peerDependencies:
-      '@tiptap/pm': ^3.13.0
-
-  '@tiptap/extension-blockquote@3.13.0':
-    resolution: {integrity: sha512-K1z/PAIIwEmiWbzrP//4cC7iG1TZknDlF1yb42G7qkx2S2X4P0NiqX7sKOej3yqrPjKjGwPujLMSuDnCF87QkQ==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-
-  '@tiptap/extension-bold@3.13.0':
-    resolution: {integrity: sha512-VYiDN9EEwR6ShaDLclG8mphkb/wlIzqfk7hxaKboq1G+NSDj8PcaSI9hldKKtTCLeaSNu6UR5nkdu/YHdzYWTw==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-
-  '@tiptap/extension-bubble-menu@3.13.0':
-    resolution: {integrity: sha512-qZ3j2DBsqP9DjG2UlExQ+tHMRhAnWlCKNreKddKocb/nAFrPdBCtvkqIEu+68zPlbLD4ukpoyjUklRJg+NipFg==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-      '@tiptap/pm': ^3.13.0
-
-  '@tiptap/extension-bullet-list@3.13.0':
-    resolution: {integrity: sha512-fFQmmEUoPzRGiQJ/KKutG35ZX21GE+1UCDo8Q6PoWH7Al9lex47nvyeU1BiDYOhcTKgIaJRtEH5lInsOsRJcSA==}
-    peerDependencies:
-      '@tiptap/extension-list': ^3.13.0
-
-  '@tiptap/extension-code-block@3.13.0':
-    resolution: {integrity: sha512-kIwfQ4iqootsWg9e74iYJK54/YMIj6ahUxEltjZRML5z/h4gTDcQt2eTpnEC8yjDjHeUVOR94zH9auCySyk9CQ==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-      '@tiptap/pm': ^3.13.0
-
-  '@tiptap/extension-code@3.13.0':
-    resolution: {integrity: sha512-sF5raBni6iSVpXWvwJCAcOXw5/kZ+djDHx1YSGWhopm4+fsj0xW7GvVO+VTwiFjZGKSw+K5NeAxzcQTJZd3Vhw==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-
-  '@tiptap/extension-document@3.13.0':
-    resolution: {integrity: sha512-RjU7hTJwjKXIdY57o/Pc+Yr8swLkrwT7PBQ/m+LCX5oO/V2wYoWCjoBYnK5KSHrWlNy/aLzC33BvLeqZZ9nzlQ==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-
-  '@tiptap/extension-dropcursor@3.13.0':
-    resolution: {integrity: sha512-m7GPT3c/83ni+bbU8c+3dpNa8ug+aQ4phNB1Q52VQG3oTonDJnZS7WCtn3lB/Hi1LqoqMtEHwhepU2eD+JeXqQ==}
-    peerDependencies:
-      '@tiptap/extensions': ^3.13.0
-
-  '@tiptap/extension-floating-menu@3.13.0':
-    resolution: {integrity: sha512-OsezV2cMofZM4c13gvgi93IEYBUzZgnu8BXTYZQiQYekz4bX4uulBmLa1KOA9EN71FzS+SoLkXHU0YzlbLjlxA==}
-    peerDependencies:
-      '@floating-ui/dom': ^1.0.0
-      '@tiptap/core': ^3.13.0
-      '@tiptap/pm': ^3.13.0
-
-  '@tiptap/extension-gapcursor@3.13.0':
-    resolution: {integrity: sha512-KVxjQKkd964nin+1IdM2Dvej/Jy4JTMcMgq5seusUhJ9T9P8F9s2D5Iefwgkps3OCzub/aF+eAsZe+1P5KSIgA==}
-    peerDependencies:
-      '@tiptap/extensions': ^3.13.0
-
-  '@tiptap/extension-hard-break@3.13.0':
-    resolution: {integrity: sha512-nH1OBaO+/pakhu+P1jF208mPgB70IKlrR/9d46RMYoYbqJTNf4KVLx5lHAOHytIhjcNg+MjyTfJWfkK+dyCCyg==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-
-  '@tiptap/extension-heading@3.13.0':
-    resolution: {integrity: sha512-8VKWX8waYPtUWN97J89em9fOtxNteh6pvUEd0htcOAtoxjt2uZjbW5N4lKyWhNKifZBrVhH2Cc2NUPuftCVgxw==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-
-  '@tiptap/extension-horizontal-rule@3.13.0':
-    resolution: {integrity: sha512-ZUFyORtjj22ib8ykbxRhWFQOTZjNKqOsMQjaAGof30cuD2DN5J5pMz7Haj2fFRtLpugWYH+f0Mi+WumQXC3hCw==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-      '@tiptap/pm': ^3.13.0
-
-  '@tiptap/extension-image@3.13.0':
-    resolution: {integrity: sha512-223uzLUkIa1rkK7aQK3AcIXe6LbCtmnpVb7sY5OEp+LpSaSPyXwyrZ4A0EO1o98qXG68/0B2OqMntFtA9c5Fbw==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-
-  '@tiptap/extension-italic@3.13.0':
-    resolution: {integrity: sha512-XbVTgmzk1kgUMTirA6AGdLTcKHUvEJoh3R4qMdPtwwygEOe7sBuvKuLtF6AwUtpnOM+Y3tfWUTNEDWv9AcEdww==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-
-  '@tiptap/extension-link@3.13.0':
-    resolution: {integrity: sha512-LuFPJ5GoL12GHW4A+USsj60O90pLcwUPdvEUSWewl9USyG6gnLnY/j5ZOXPYH7LiwYW8+lhq7ABwrDF2PKyBbA==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-      '@tiptap/pm': ^3.13.0
-
-  '@tiptap/extension-list-item@3.13.0':
-    resolution: {integrity: sha512-63NbcS/XeQP2jcdDEnEAE3rjJICDj8y1SN1h/MsJmSt1LusnEo8WQ2ub86QELO6XnD3M04V03cY6Knf6I5mTkw==}
-    peerDependencies:
-      '@tiptap/extension-list': ^3.13.0
-
-  '@tiptap/extension-list-keymap@3.13.0':
-    resolution: {integrity: sha512-P+HtIa1iwosb1feFc8B/9MN5EAwzS+/dZ0UH0CTF2E4wnp5Z9OMxKl1IYjfiCwHzZrU5Let+S/maOvJR/EmV0g==}
-    peerDependencies:
-      '@tiptap/extension-list': ^3.13.0
-
-  '@tiptap/extension-list@3.13.0':
-    resolution: {integrity: sha512-MMFH0jQ4LeCPkJJFyZ77kt6eM/vcKujvTbMzW1xSHCIEA6s4lEcx9QdZMPpfmnOvTzeoVKR4nsu2t2qT9ZXzAw==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-      '@tiptap/pm': ^3.13.0
-
-  '@tiptap/extension-ordered-list@3.13.0':
-    resolution: {integrity: sha512-QuDyLzuK/3vCvx9GeKhgvHWrGECBzmJyAx6gli2HY+Iil7XicbfltV4nvhIxgxzpx3LDHLKzJN9pBi+2MzX60g==}
-    peerDependencies:
-      '@tiptap/extension-list': ^3.13.0
-
-  '@tiptap/extension-paragraph@3.13.0':
-    resolution: {integrity: sha512-9csQde1i0yeZI5oQQ9e1GYNtGL2JcC2d8Fwtw9FsGC8yz2W0h+Fmk+3bc2kobbtO5LGqupSc1fKM8fAg5rSRDg==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-
-  '@tiptap/extension-placeholder@3.13.0':
-    resolution: {integrity: sha512-Au4ktRBraQktX9gjSzGWyJV6kPof7+kOhzE8ej+rOMjIrHbx3DCHy1CJWftSO9BbqIyonjsFmm4nE+vjzZ3Z5Q==}
-    peerDependencies:
-      '@tiptap/extensions': ^3.13.0
-
-  '@tiptap/extension-strike@3.13.0':
-    resolution: {integrity: sha512-VHhWNqTAMOfrC48m2FcPIZB0nhl6XHQviAV16SBc+EFznKNv9tQUsqQrnuQ2y6ZVfqq5UxvZ3hKF/JlN/Ff7xw==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-
-  '@tiptap/extension-table@3.13.0':
-    resolution: {integrity: sha512-LcH9KE4QBUJ6IPwt1Uo5iU7zatFjUUvXbctIu2fKQ9nqJ7nNSFxRhkNyporVFkTWYH7/rb0qMoF1VxSUGefG5w==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-      '@tiptap/pm': ^3.13.0
-
-  '@tiptap/extension-text@3.13.0':
-    resolution: {integrity: sha512-VcZIna93rixw7hRkHGCxDbL3kvJWi80vIT25a2pXg0WP1e7Pi3nBYvZIL4SQtkbBCji9EHrbZx3p8nNPzfazYw==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-
-  '@tiptap/extension-underline@3.13.0':
-    resolution: {integrity: sha512-VDQi+UYw0tFnfghpthJTFmtJ3yx90kXeDwFvhmT8G+O+si5VmP05xYDBYBmYCix5jqKigJxEASiBL0gYOgMDEg==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-
-  '@tiptap/extensions@3.13.0':
-    resolution: {integrity: sha512-i7O0ptSibEtTy+2PIPsNKEvhTvMaFJg1W4Oxfnbuxvaigs7cJV9Q0lwDUcc7CPsNw2T1+44wcxg431CzTvdYoA==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-      '@tiptap/pm': ^3.13.0
-
-  '@tiptap/markdown@3.13.0':
-    resolution: {integrity: sha512-BI1GZxDFBrEeYbngbKh/si48tRSXO6HVGg7KzlfOwdncSD982/loG2KUnFIjoVGjmMzXNDWbI6O/eqfLVQPB5Q==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-      '@tiptap/pm': ^3.13.0
-
-  '@tiptap/pm@3.13.0':
-    resolution: {integrity: sha512-WKR4ucALq+lwx0WJZW17CspeTpXorbIOpvKv5mulZica6QxqfMhn8n1IXCkDws/mCoLRx4Drk5d377tIjFNsvQ==}
-
-  '@tiptap/react@3.13.0':
-    resolution: {integrity: sha512-VqpqNZ9qtPr3pWK4NsZYxXgLSEiAnzl6oS7tEGmkkvJbcGSC+F7R13Xc9twv/zT5QCLxaHdEbmxHbuAIkrMgJQ==}
-    peerDependencies:
-      '@tiptap/core': ^3.13.0
-      '@tiptap/pm': ^3.13.0
-      '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
-      '@types/react-dom': ^17.0.0 || ^18.0.0 || ^19.0.0
-      react: ^17.0.0 || ^18.0.0 || ^19.0.0
-      react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0
-
-  '@tiptap/starter-kit@3.13.0':
-    resolution: {integrity: sha512-Ojn6sRub04CRuyQ+9wqN62JUOMv+rG1vXhc2s6DCBCpu28lkCMMW+vTe7kXJcEdbot82+5swPbERw9vohswFzg==}
-
   '@tootallnate/once@1.1.2':
     resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==}
     engines: {node: '>= 6'}
@@ -2007,21 +1803,12 @@ packages:
   '@types/json5@0.0.29':
     resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
 
-  '@types/linkify-it@5.0.0':
-    resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==}
-
   '@types/lodash@4.17.13':
     resolution: {integrity: sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==}
 
-  '@types/markdown-it@14.1.2':
-    resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==}
-
   '@types/marked@4.3.2':
     resolution: {integrity: sha512-a79Yc3TOk6dGdituy8hmTTJXjOkZ7zsFYV10L337ttq/rec8lRMDBpV7fL3uLx6TgbFCa5DU/h8FmIBQPSbU0w==}
 
-  '@types/mdurl@2.0.0':
-    resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==}
-
   '@types/mime@1.3.5':
     resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==}
 
@@ -2096,9 +1883,6 @@ packages:
   '@types/trusted-types@2.0.7':
     resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
 
-  '@types/use-sync-external-store@0.0.6':
-    resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==}
-
   '@types/warning@3.0.3':
     resolution: {integrity: sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q==}
 
@@ -3380,10 +3164,6 @@ packages:
   entities@2.2.0:
     resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==}
 
-  entities@4.5.0:
-    resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
-    engines: {node: '>=0.12'}
-
   environment@1.1.0:
     resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==}
     engines: {node: '>=18'}
@@ -3747,10 +3527,6 @@ packages:
   fast-diff@1.3.0:
     resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
 
-  fast-equals@5.4.0:
-    resolution: {integrity: sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw==}
-    engines: {node: '>=6.0.0'}
-
   fast-glob@3.3.2:
     resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
     engines: {node: '>=8.6.0'}
@@ -4775,12 +4551,6 @@ packages:
   lines-and-columns@1.2.4:
     resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
 
-  linkify-it@5.0.0:
-    resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==}
-
-  linkifyjs@4.3.2:
-    resolution: {integrity: sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==}
-
   lint-staged@15.5.0:
     resolution: {integrity: sha512-WyCzSbfYGhK7cU+UuDDkzUiytbfbi0ZdPy2orwtM75P3WTtQBzmG40cCxIa8Ii2+XjfxzLH6Be46tUfWS85Xfg==}
     engines: {node: '>=18.12.0'}
@@ -4909,15 +4679,6 @@ packages:
     resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==}
     engines: {node: '>=8'}
 
-  markdown-it@14.1.0:
-    resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==}
-    hasBin: true
-
-  marked@15.0.12:
-    resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==}
-    engines: {node: '>= 18'}
-    hasBin: true
-
   marked@4.3.0:
     resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==}
     engines: {node: '>= 12'}
@@ -4929,9 +4690,6 @@ packages:
   mdn-data@2.0.4:
     resolution: {integrity: sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==}
 
-  mdurl@2.0.0:
-    resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
-
   media-typer@0.3.0:
     resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==}
     engines: {node: '>= 0.6'}
@@ -5210,9 +4968,6 @@ packages:
     resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
     engines: {node: '>= 0.8.0'}
 
-  orderedmap@2.1.1:
-    resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==}
-
   p-limit@2.3.0:
     resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
     engines: {node: '>=6'}
@@ -5825,64 +5580,6 @@ packages:
   prop-types@15.8.1:
     resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
 
-  prosemirror-changeset@2.3.1:
-    resolution: {integrity: sha512-j0kORIBm8ayJNl3zQvD1TTPHJX3g042et6y/KQhZhnPrruO8exkTgG8X+NRpj7kIyMMEx74Xb3DyMIBtO0IKkQ==}
-
-  prosemirror-collab@1.3.1:
-    resolution: {integrity: sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==}
-
-  prosemirror-commands@1.7.1:
-    resolution: {integrity: sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==}
-
-  prosemirror-dropcursor@1.8.2:
-    resolution: {integrity: sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==}
-
-  prosemirror-gapcursor@1.4.0:
-    resolution: {integrity: sha512-z00qvurSdCEWUIulij/isHaqu4uLS8r/Fi61IbjdIPJEonQgggbJsLnstW7Lgdk4zQ68/yr6B6bf7sJXowIgdQ==}
-
-  prosemirror-history@1.5.0:
-    resolution: {integrity: sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==}
-
-  prosemirror-inputrules@1.5.1:
-    resolution: {integrity: sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==}
-
-  prosemirror-keymap@1.2.3:
-    resolution: {integrity: sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==}
-
-  prosemirror-markdown@1.13.2:
-    resolution: {integrity: sha512-FPD9rHPdA9fqzNmIIDhhnYQ6WgNoSWX9StUZ8LEKapaXU9i6XgykaHKhp6XMyXlOWetmaFgGDS/nu/w9/vUc5g==}
-
-  prosemirror-menu@1.2.5:
-    resolution: {integrity: sha512-qwXzynnpBIeg1D7BAtjOusR+81xCp53j7iWu/IargiRZqRjGIlQuu1f3jFi+ehrHhWMLoyOQTSRx/IWZJqOYtQ==}
-
-  prosemirror-model@1.25.4:
-    resolution: {integrity: sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==}
-
-  prosemirror-schema-basic@1.2.4:
-    resolution: {integrity: sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==}
-
-  prosemirror-schema-list@1.5.1:
-    resolution: {integrity: sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==}
-
-  prosemirror-state@1.4.4:
-    resolution: {integrity: sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==}
-
-  prosemirror-tables@1.8.1:
-    resolution: {integrity: sha512-DAgDoUYHCcc6tOGpLVPSU1k84kCUWTWnfWX3UDy2Delv4ryH0KqTD6RBI6k4yi9j9I8gl3j8MkPpRD/vWPZbug==}
-
-  prosemirror-trailing-node@3.0.0:
-    resolution: {integrity: sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==}
-    peerDependencies:
-      prosemirror-model: ^1.22.1
-      prosemirror-state: ^1.4.2
-      prosemirror-view: ^1.33.8
-
-  prosemirror-transform@1.10.5:
-    resolution: {integrity: sha512-RPDQCxIDhIBb1o36xxwsaeAvivO8VLJcgBtzmOwQ64bMtsVFh5SSuJ6dWSxO1UsHTiTXPCgQm3PDJt7p6IOLbw==}
-
-  prosemirror-view@1.41.3:
-    resolution: {integrity: sha512-SqMiYMUQNNBP9kfPhLO8WXEk/fon47vc52FQsUiJzTBuyjKgEcoAwMyF04eQ4WZ2ArMn7+ReypYL60aKngbACQ==}
-
   proxy-addr@2.0.7:
     resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==}
     engines: {node: '>= 0.10'}
@@ -5893,10 +5590,6 @@ packages:
   psl@1.15.0:
     resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==}
 
-  punycode.js@2.3.1:
-    resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==}
-    engines: {node: '>=6'}
-
   punycode@2.3.1:
     resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
     engines: {node: '>=6'}
@@ -6242,9 +5935,6 @@ packages:
     engines: {node: '>=10.0.0'}
     hasBin: true
 
-  rope-sequence@1.3.4:
-    resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==}
-
   run-parallel@1.2.0:
     resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
 
@@ -6911,9 +6601,6 @@ packages:
     engines: {node: '>=4.2.0'}
     hasBin: true
 
-  uc.micro@2.1.0:
-    resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==}
-
   unbox-primitive@1.0.2:
     resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
 
@@ -8729,20 +8416,6 @@ snapshots:
 
   '@eslint/js@8.57.1': {}
 
-  '@floating-ui/core@1.7.3':
-    dependencies:
-      '@floating-ui/utils': 0.2.10
-    optional: true
-
-  '@floating-ui/dom@1.7.4':
-    dependencies:
-      '@floating-ui/core': 1.7.3
-      '@floating-ui/utils': 0.2.10
-    optional: true
-
-  '@floating-ui/utils@0.2.10':
-    optional: true
-
   '@fullhuman/postcss-purgecss@4.1.3(postcss@8.4.49)':
     dependencies:
       postcss: 8.4.49
@@ -9129,8 +8802,6 @@ snapshots:
       '@swc/helpers': 0.5.15
       react: 18.3.1
 
-  '@remirror/core-constants@3.0.0': {}
-
   '@restart/hooks@0.4.16(react@18.3.1)':
     dependencies:
       dequal: 2.0.3
@@ -9374,202 +9045,6 @@ snapshots:
       '@babel/runtime': 7.26.0
       '@testing-library/dom': 8.20.1
 
-  '@tiptap/core@3.13.0(@tiptap/pm@3.13.0)':
-    dependencies:
-      '@tiptap/pm': 3.13.0
-
-  '@tiptap/extension-blockquote@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-
-  '@tiptap/extension-bold@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-
-  '@tiptap/extension-bubble-menu@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)':
-    dependencies:
-      '@floating-ui/dom': 1.7.4
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-      '@tiptap/pm': 3.13.0
-    optional: true
-
-  '@tiptap/extension-bullet-list@3.13.0(@tiptap/extension-list@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/extension-list': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)
-
-  '@tiptap/extension-code-block@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-      '@tiptap/pm': 3.13.0
-
-  '@tiptap/extension-code@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-
-  '@tiptap/extension-document@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-
-  '@tiptap/extension-dropcursor@3.13.0(@tiptap/extensions@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/extensions': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)
-
-  '@tiptap/extension-floating-menu@3.13.0(@floating-ui/dom@1.7.4)(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)':
-    dependencies:
-      '@floating-ui/dom': 1.7.4
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-      '@tiptap/pm': 3.13.0
-    optional: true
-
-  '@tiptap/extension-gapcursor@3.13.0(@tiptap/extensions@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/extensions': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)
-
-  '@tiptap/extension-hard-break@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-
-  '@tiptap/extension-heading@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-
-  '@tiptap/extension-horizontal-rule@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-      '@tiptap/pm': 3.13.0
-
-  '@tiptap/extension-image@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-
-  '@tiptap/extension-italic@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-
-  '@tiptap/extension-link@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-      '@tiptap/pm': 3.13.0
-      linkifyjs: 4.3.2
-
-  '@tiptap/extension-list-item@3.13.0(@tiptap/extension-list@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/extension-list': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)
-
-  '@tiptap/extension-list-keymap@3.13.0(@tiptap/extension-list@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/extension-list': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)
-
-  '@tiptap/extension-list@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-      '@tiptap/pm': 3.13.0
-
-  '@tiptap/extension-ordered-list@3.13.0(@tiptap/extension-list@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/extension-list': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)
-
-  '@tiptap/extension-paragraph@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-
-  '@tiptap/extension-placeholder@3.13.0(@tiptap/extensions@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/extensions': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)
-
-  '@tiptap/extension-strike@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-
-  '@tiptap/extension-table@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-      '@tiptap/pm': 3.13.0
-
-  '@tiptap/extension-text@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-
-  '@tiptap/extension-underline@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-
-  '@tiptap/extensions@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-      '@tiptap/pm': 3.13.0
-
-  '@tiptap/markdown@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-      '@tiptap/pm': 3.13.0
-      marked: 15.0.12
-
-  '@tiptap/pm@3.13.0':
-    dependencies:
-      prosemirror-changeset: 2.3.1
-      prosemirror-collab: 1.3.1
-      prosemirror-commands: 1.7.1
-      prosemirror-dropcursor: 1.8.2
-      prosemirror-gapcursor: 1.4.0
-      prosemirror-history: 1.5.0
-      prosemirror-inputrules: 1.5.1
-      prosemirror-keymap: 1.2.3
-      prosemirror-markdown: 1.13.2
-      prosemirror-menu: 1.2.5
-      prosemirror-model: 1.25.4
-      prosemirror-schema-basic: 1.2.4
-      prosemirror-schema-list: 1.5.1
-      prosemirror-state: 1.4.4
-      prosemirror-tables: 1.8.1
-      prosemirror-trailing-node: 3.0.0(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.3)
-      prosemirror-transform: 1.10.5
-      prosemirror-view: 1.41.3
-
-  '@tiptap/react@3.13.0(@floating-ui/dom@1.7.4)(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)(@types/react-dom@18.3.5(@types/react@18.3.16))(@types/react@18.3.16)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-      '@tiptap/pm': 3.13.0
-      '@types/react': 18.3.16
-      '@types/react-dom': 18.3.5(@types/react@18.3.16)
-      '@types/use-sync-external-store': 0.0.6
-      fast-equals: 5.4.0
-      react: 18.3.1
-      react-dom: 18.3.1(react@18.3.1)
-      use-sync-external-store: 1.6.0(react@18.3.1)
-    optionalDependencies:
-      '@tiptap/extension-bubble-menu': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)
-      '@tiptap/extension-floating-menu': 3.13.0(@floating-ui/dom@1.7.4)(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)
-    transitivePeerDependencies:
-      - '@floating-ui/dom'
-
-  '@tiptap/starter-kit@3.13.0':
-    dependencies:
-      '@tiptap/core': 3.13.0(@tiptap/pm@3.13.0)
-      '@tiptap/extension-blockquote': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))
-      '@tiptap/extension-bold': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))
-      '@tiptap/extension-bullet-list': 3.13.0(@tiptap/extension-list@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0))
-      '@tiptap/extension-code': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))
-      '@tiptap/extension-code-block': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)
-      '@tiptap/extension-document': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))
-      '@tiptap/extension-dropcursor': 3.13.0(@tiptap/extensions@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0))
-      '@tiptap/extension-gapcursor': 3.13.0(@tiptap/extensions@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0))
-      '@tiptap/extension-hard-break': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))
-      '@tiptap/extension-heading': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))
-      '@tiptap/extension-horizontal-rule': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)
-      '@tiptap/extension-italic': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))
-      '@tiptap/extension-link': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)
-      '@tiptap/extension-list': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)
-      '@tiptap/extension-list-item': 3.13.0(@tiptap/extension-list@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0))
-      '@tiptap/extension-list-keymap': 3.13.0(@tiptap/extension-list@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0))
-      '@tiptap/extension-ordered-list': 3.13.0(@tiptap/extension-list@3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0))
-      '@tiptap/extension-paragraph': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))
-      '@tiptap/extension-strike': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))
-      '@tiptap/extension-text': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))
-      '@tiptap/extension-underline': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))
-      '@tiptap/extensions': 3.13.0(@tiptap/core@3.13.0(@tiptap/pm@3.13.0))(@tiptap/pm@3.13.0)
-      '@tiptap/pm': 3.13.0
-
   '@tootallnate/once@1.1.2': {}
 
   '@trysound/sax@0.2.0': {}
@@ -9715,19 +9190,10 @@ snapshots:
 
   '@types/json5@0.0.29': {}
 
-  '@types/linkify-it@5.0.0': {}
-
   '@types/lodash@4.17.13': {}
 
-  '@types/markdown-it@14.1.2':
-    dependencies:
-      '@types/linkify-it': 5.0.0
-      '@types/mdurl': 2.0.0
-
   '@types/marked@4.3.2': {}
 
-  '@types/mdurl@2.0.0': {}
-
   '@types/mime@1.3.5': {}
 
   '@types/minimist@1.2.5': {}
@@ -9798,8 +9264,6 @@ snapshots:
 
   '@types/trusted-types@2.0.7': {}
 
-  '@types/use-sync-external-store@0.0.6': {}
-
   '@types/warning@3.0.3': {}
 
   '@types/ws@8.5.13':
@@ -11233,8 +10697,6 @@ snapshots:
 
   entities@2.2.0: {}
 
-  entities@4.5.0: {}
-
   environment@1.1.0: {}
 
   error-ex@1.3.2:
@@ -11831,8 +11293,6 @@ snapshots:
 
   fast-diff@1.3.0: {}
 
-  fast-equals@5.4.0: {}
-
   fast-glob@3.3.2:
     dependencies:
       '@nodelib/fs.stat': 2.0.5
@@ -13126,12 +12586,6 @@ snapshots:
 
   lines-and-columns@1.2.4: {}
 
-  linkify-it@5.0.0:
-    dependencies:
-      uc.micro: 2.1.0
-
-  linkifyjs@4.3.2: {}
-
   lint-staged@15.5.0:
     dependencies:
       chalk: 5.4.1
@@ -13259,25 +12713,12 @@ snapshots:
 
   map-obj@4.3.0: {}
 
-  markdown-it@14.1.0:
-    dependencies:
-      argparse: 2.0.1
-      entities: 4.5.0
-      linkify-it: 5.0.0
-      mdurl: 2.0.0
-      punycode.js: 2.3.1
-      uc.micro: 2.1.0
-
-  marked@15.0.12: {}
-
   marked@4.3.0: {}
 
   mdn-data@2.0.14: {}
 
   mdn-data@2.0.4: {}
 
-  mdurl@2.0.0: {}
-
   media-typer@0.3.0: {}
 
   memfs@3.5.3:
@@ -13558,8 +12999,6 @@ snapshots:
       type-check: 0.4.0
       word-wrap: 1.2.5
 
-  orderedmap@2.1.1: {}
-
   p-limit@2.3.0:
     dependencies:
       p-try: 2.2.0
@@ -14151,109 +13590,6 @@ snapshots:
       object-assign: 4.1.1
       react-is: 16.13.1
 
-  prosemirror-changeset@2.3.1:
-    dependencies:
-      prosemirror-transform: 1.10.5
-
-  prosemirror-collab@1.3.1:
-    dependencies:
-      prosemirror-state: 1.4.4
-
-  prosemirror-commands@1.7.1:
-    dependencies:
-      prosemirror-model: 1.25.4
-      prosemirror-state: 1.4.4
-      prosemirror-transform: 1.10.5
-
-  prosemirror-dropcursor@1.8.2:
-    dependencies:
-      prosemirror-state: 1.4.4
-      prosemirror-transform: 1.10.5
-      prosemirror-view: 1.41.3
-
-  prosemirror-gapcursor@1.4.0:
-    dependencies:
-      prosemirror-keymap: 1.2.3
-      prosemirror-model: 1.25.4
-      prosemirror-state: 1.4.4
-      prosemirror-view: 1.41.3
-
-  prosemirror-history@1.5.0:
-    dependencies:
-      prosemirror-state: 1.4.4
-      prosemirror-transform: 1.10.5
-      prosemirror-view: 1.41.3
-      rope-sequence: 1.3.4
-
-  prosemirror-inputrules@1.5.1:
-    dependencies:
-      prosemirror-state: 1.4.4
-      prosemirror-transform: 1.10.5
-
-  prosemirror-keymap@1.2.3:
-    dependencies:
-      prosemirror-state: 1.4.4
-      w3c-keyname: 2.2.8
-
-  prosemirror-markdown@1.13.2:
-    dependencies:
-      '@types/markdown-it': 14.1.2
-      markdown-it: 14.1.0
-      prosemirror-model: 1.25.4
-
-  prosemirror-menu@1.2.5:
-    dependencies:
-      crelt: 1.0.6
-      prosemirror-commands: 1.7.1
-      prosemirror-history: 1.5.0
-      prosemirror-state: 1.4.4
-
-  prosemirror-model@1.25.4:
-    dependencies:
-      orderedmap: 2.1.1
-
-  prosemirror-schema-basic@1.2.4:
-    dependencies:
-      prosemirror-model: 1.25.4
-
-  prosemirror-schema-list@1.5.1:
-    dependencies:
-      prosemirror-model: 1.25.4
-      prosemirror-state: 1.4.4
-      prosemirror-transform: 1.10.5
-
-  prosemirror-state@1.4.4:
-    dependencies:
-      prosemirror-model: 1.25.4
-      prosemirror-transform: 1.10.5
-      prosemirror-view: 1.41.3
-
-  prosemirror-tables@1.8.1:
-    dependencies:
-      prosemirror-keymap: 1.2.3
-      prosemirror-model: 1.25.4
-      prosemirror-state: 1.4.4
-      prosemirror-transform: 1.10.5
-      prosemirror-view: 1.41.3
-
-  prosemirror-trailing-node@3.0.0(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.3):
-    dependencies:
-      '@remirror/core-constants': 3.0.0
-      escape-string-regexp: 4.0.0
-      prosemirror-model: 1.25.4
-      prosemirror-state: 1.4.4
-      prosemirror-view: 1.41.3
-
-  prosemirror-transform@1.10.5:
-    dependencies:
-      prosemirror-model: 1.25.4
-
-  prosemirror-view@1.41.3:
-    dependencies:
-      prosemirror-model: 1.25.4
-      prosemirror-state: 1.4.4
-      prosemirror-transform: 1.10.5
-
   proxy-addr@2.0.7:
     dependencies:
       forwarded: 0.2.0
@@ -14265,8 +13601,6 @@ snapshots:
     dependencies:
       punycode: 2.3.1
 
-  punycode.js@2.3.1: {}
-
   punycode@2.3.1: {}
 
   purgecss-webpack-plugin@4.1.3(webpack@5.97.1(@swc/core@1.15.3)):
@@ -14725,8 +14059,6 @@ snapshots:
     optionalDependencies:
       fsevents: 2.3.3
 
-  rope-sequence@1.3.4: {}
-
   run-parallel@1.2.0:
     dependencies:
       queue-microtask: 1.2.3
@@ -15481,8 +14813,6 @@ snapshots:
 
   typescript@4.9.5: {}
 
-  uc.micro@2.1.0: {}
-
   unbox-primitive@1.0.2:
     dependencies:
       call-bind: 1.0.8
@@ -15549,6 +14879,7 @@ snapshots:
   use-sync-external-store@1.6.0(react@18.3.1):
     dependencies:
       react: 18.3.1
+    optional: true
 
   util-deprecate@1.0.2: {}
 
diff --git a/ui/src/components/Editor/RichEditor.tsx b/ui/src/components/Editor/RichEditor.tsx
deleted file mode 100644
index 55fca5a9..00000000
--- a/ui/src/components/Editor/RichEditor.tsx
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { useEffect, useRef, useCallback } from 'react';
-
-import {
-  useEditor,
-  EditorContent,
-  Editor as TipTapEditor,
-} from '@tiptap/react';
-import StarterKit from '@tiptap/starter-kit';
-import Placeholder from '@tiptap/extension-placeholder';
-import { Markdown } from '@tiptap/markdown';
-import Image from '@tiptap/extension-image';
-import { TableRow, TableCell, TableHeader } from '@tiptap/extension-table';
-
-import { Editor, BaseEditorProps } from './types';
-import { createTipTapAdapter } from './utils/tiptap/adapter';
-import { TableWithWrapper } from './utils/tiptap/tableExtension';
-
-interface RichEditorProps extends BaseEditorProps {}
-
-const RichEditor: React.FC<RichEditorProps> = ({
-  value,
-  onChange,
-  onFocus,
-  onBlur,
-  placeholder = '',
-  autoFocus = false,
-  onEditorReady,
-}) => {
-  const lastSyncedValueRef = useRef<string>(value);
-  const adaptedEditorRef = useRef<Editor | null>(null);
-  const isInitializedRef = useRef<boolean>(false);
-  const isUpdatingFromPropsRef = useRef<boolean>(false);
-  const onEditorReadyRef = useRef(onEditorReady);
-  const autoFocusRef = useRef(autoFocus);
-  const initialValueRef = useRef<string>(value);
-
-  useEffect(() => {
-    onEditorReadyRef.current = onEditorReady;
-    autoFocusRef.current = autoFocus;
-  }, [onEditorReady, autoFocus]);
-
-  const isViewAvailable = (editorInstance: TipTapEditor | null): boolean => {
-    if (!editorInstance) {
-      return false;
-    }
-    if (editorInstance.isDestroyed) {
-      return false;
-    }
-    return !!(editorInstance.view && editorInstance.state);
-  };
-
-  const handleCreate = useCallback(
-    ({ editor: editorInstance }: { editor: TipTapEditor }) => {
-      if (isInitializedRef.current || !isViewAvailable(editorInstance)) {
-        return;
-      }
-
-      isInitializedRef.current = true;
-
-      const initialValue = initialValueRef.current;
-      if (initialValue && initialValue.trim() !== '') {
-        editorInstance.commands.setContent(initialValue, {
-          contentType: 'markdown',
-        });
-        lastSyncedValueRef.current = initialValue;
-      }
-
-      adaptedEditorRef.current = createTipTapAdapter(editorInstance);
-      onEditorReadyRef.current?.(adaptedEditorRef.current);
-
-      if (autoFocusRef.current) {
-        editorInstance.commands.focus();
-      }
-    },
-    [],
-  );
-
-  const handleUpdate = useCallback(
-    ({ editor: editorInstance }: { editor: TipTapEditor }) => {
-      if (onChange && !isUpdatingFromPropsRef.current) {
-        const markdown = editorInstance.getMarkdown();
-        onChange(markdown);
-        lastSyncedValueRef.current = markdown;
-      }
-    },
-    [onChange],
-  );
-
-  const handleFocus = useCallback(() => {
-    onFocus?.();
-  }, [onFocus]);
-
-  const handleBlur = useCallback(() => {
-    onBlur?.();
-  }, [onBlur]);
-
-  const editor = useEditor({
-    extensions: [
-      StarterKit,
-      Markdown,
-      Image,
-      TableWithWrapper.configure({
-        HTMLAttributes: {
-          class: 'table table-bordered',
-          style: {
-            width: '100%',
-          },
-        },
-        resizable: true,
-        wrapperClass: 'table-responsive',
-      }),
-      TableRow.configure({
-        HTMLAttributes: {
-          class: 'table-row',
-        },
-      }),
-      TableCell,
-      TableHeader,
-      Placeholder.configure({
-        placeholder,
-      }),
-    ],
-    onCreate: handleCreate,
-    onUpdate: handleUpdate,
-    onFocus: handleFocus,
-    onBlur: handleBlur,
-    editorProps: {
-      attributes: {
-        class: 'tiptap-editor fmt',
-      },
-    },
-  });
-
-  useEffect(() => {
-    if (
-      !editor ||
-      !isInitializedRef.current ||
-      !isViewAvailable(editor) ||
-      value === lastSyncedValueRef.current
-    ) {
-      return;
-    }
-
-    try {
-      const currentMarkdown = editor.getMarkdown();
-      if (currentMarkdown !== value) {
-        isUpdatingFromPropsRef.current = true;
-        if (value && value.trim() !== '') {
-          editor.commands.setContent(value, { contentType: 'markdown' });
-        } else {
-          editor.commands.clearContent();
-        }
-        lastSyncedValueRef.current = value || '';
-        setTimeout(() => {
-          isUpdatingFromPropsRef.current = false;
-        }, 0);
-      }
-    } catch (error) {
-      console.warn('Editor view not available when syncing value:', error);
-    }
-  }, [editor, value]);
-
-  useEffect(() => {
-    initialValueRef.current = value;
-    lastSyncedValueRef.current = value;
-    isInitializedRef.current = false;
-    adaptedEditorRef.current = null;
-    isUpdatingFromPropsRef.current = false;
-
-    return () => {
-      if (editor) {
-        editor.destroy();
-      }
-      isInitializedRef.current = false;
-      adaptedEditorRef.current = null;
-      isUpdatingFromPropsRef.current = false;
-    };
-  }, [editor]);
-
-  if (!editor) {
-    return <div className="editor-loading">Loading editor...</div>;
-  }
-
-  return <EditorContent className="rich-editor-wrap" editor={editor} />;
-};
-
-export default RichEditor;
diff --git a/ui/src/components/Editor/index.tsx b/ui/src/components/Editor/index.tsx
index ebe04876..c6136c3c 100644
--- a/ui/src/components/Editor/index.tsx
+++ b/ui/src/components/Editor/index.tsx
@@ -51,7 +51,6 @@ import {
 import { htmlRender } from './utils';
 import Viewer from './Viewer';
 import { EditorContext } from './EditorContext';
-import RichEditor from './RichEditor';
 import MarkdownEditor from './MarkdownEditor';
 import { Editor } from './types';
 
@@ -86,24 +85,11 @@ const MDEditor: ForwardRefRenderFunction<EditorRef, Props> = (
   },
   ref,
 ) => {
-  const [mode, setMode] = useState<'markdown' | 'rich'>('markdown');
   const [currentEditor, setCurrentEditor] = useState<Editor | null>(null);
   const previewRef = useRef<{ getHtml; element } | null>(null);
 
   useRenderPlugin(previewRef.current?.element);
 
-  const handleModeChange = useCallback(
-    (newMode: 'markdown' | 'rich') => {
-      if (newMode === mode) {
-        return;
-      }
-
-      setCurrentEditor(null);
-      setMode(newMode);
-    },
-    [mode],
-  );
-
   const getHtml = useCallback(() => {
     return previewRef.current?.getHtml();
   }, []);
@@ -116,7 +102,7 @@ const MDEditor: ForwardRefRenderFunction<EditorRef, Props> = (
     [getHtml],
   );
 
-  const EditorComponent = mode === 'markdown' ? MarkdownEditor : RichEditor;
+  const EditorComponent = MarkdownEditor;
 
   return (
     <>
@@ -149,30 +135,10 @@ const MDEditor: ForwardRefRenderFunction<EditorRef, Props> = (
               <Help />
             </PluginRender>
           </EditorContext.Provider>
-          <div className="btn-group ms-auto" role="group">
-            <button
-              type="button"
-              className={`btn btn-sm ${
-                mode === 'markdown' ? 'btn-primary' : 'btn-outline-secondary'
-              }`}
-              title="Markdown Mode"
-              onClick={() => handleModeChange('markdown')}>
-              <i className="bi bi-filetype-md" />
-            </button>
-            <button
-              type="button"
-              className={`btn btn-sm ${
-                mode === 'rich' ? 'btn-primary' : 'btn-outline-secondary'
-              }`}
-              title="Rich Mode"
-              onClick={() => handleModeChange('rich')}>
-              <i className="bi bi-type" />
-            </button>
-          </div>
         </div>
 
         <EditorComponent
-          key={mode}
+          key="markdown-editor"
           value={value}
           onChange={(markdown) => {
             onChange?.(markdown);
@@ -186,7 +152,7 @@ const MDEditor: ForwardRefRenderFunction<EditorRef, Props> = (
           }}
         />
       </div>
-      {mode === 'markdown' && <Viewer ref={previewRef} value={value} />}
+      <Viewer ref={previewRef} value={value} />
     </>
   );
 };
diff --git a/ui/src/components/Editor/utils/tiptap/adapter.ts b/ui/src/components/Editor/utils/tiptap/adapter.ts
deleted file mode 100644
index 415edb17..00000000
--- a/ui/src/components/Editor/utils/tiptap/adapter.ts
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { Editor as TipTapEditor } from '@tiptap/react';
-
-import { Editor, ExtendEditor } from '../../types';
-
-import { createBaseMethods } from './base';
-import { createEventMethods } from './events';
-import { createCommandMethods } from './commands';
-
-/**
- * Adapts TipTap editor to CodeMirror editor interface
- *
- * This adapter function converts TipTap editor's API to a CodeMirror-compatible interface,
- * enabling toolbar components to work properly in Rich mode. The adapter implements
- * the complete `ExtendEditor` interface, including base methods, event handling, and command methods.
- *
- * @param editor - TipTap editor instance
- * @returns Adapted editor instance that implements the unified Editor interface
- *
- * @example
- * ```typescript
- * const tipTapEditor = useEditor({ ... });
- * const adaptedEditor = createTipTapAdapter(tipTapEditor);
- * // Now you can use the unified API
- * adaptedEditor.insertBold('text');
- * adaptedEditor.insertHeading(1, 'Title');
- * ```
- */
-export function createTipTapAdapter(editor: TipTapEditor): Editor {
-  const baseMethods = createBaseMethods(editor);
-  const eventMethods = createEventMethods(editor);
-  const commandMethods = createCommandMethods(editor);
-
-  const editorAdapter: ExtendEditor = {
-    ...baseMethods,
-    ...eventMethods,
-    ...commandMethods,
-  };
-
-  return editorAdapter as unknown as Editor;
-}
diff --git a/ui/src/components/Editor/utils/tiptap/base.ts b/ui/src/components/Editor/utils/tiptap/base.ts
deleted file mode 100644
index e088a9f5..00000000
--- a/ui/src/components/Editor/utils/tiptap/base.ts
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { Editor as TipTapEditor } from '@tiptap/react';
-
-import { Position } from '../../types';
-
-import {
-  safeExecuteCommand,
-  EditorErrorType,
-  handleEditorError,
-} from './errorHandler';
-import {
-  convertTipTapPositionToCodeMirror,
-  convertCodeMirrorPositionToTipTap,
-} from './position';
-import { MARKDOWN_PATTERNS } from './constants';
-
-/**
- * Creates base methods module
- *
- * Provides core base methods for the editor, including:
- * - Content getter and setter (getValue, setValue)
- * - Selection operations (getSelection, replaceSelection)
- * - Cursor and selection position (getCursor, setSelection)
- * - Read-only state control (setReadOnly)
- *
- * @param editor - TipTap editor instance
- * @returns Object containing base methods
- */
-export function createBaseMethods(editor: TipTapEditor) {
-  return {
-    getValue: () => {
-      return (
-        safeExecuteCommand(
-          () => editor.getMarkdown(),
-          () => '',
-          EditorErrorType.COMMAND_EXECUTION_FAILED,
-          { function: 'getValue' },
-        ) || ''
-      );
-    },
-
-    setValue: (value: string) => {
-      safeExecuteCommand(
-        () => {
-          editor.commands.setContent(value, { contentType: 'markdown' });
-        },
-        undefined,
-        EditorErrorType.COMMAND_EXECUTION_FAILED,
-        { function: 'setValue', valueLength: value.length },
-      );
-    },
-
-    getSelection: () => {
-      const { from, to } = editor.state.selection;
-      return editor.state.doc.textBetween(from, to);
-    },
-
-    replaceSelection: (value: string) => {
-      const inlineCodeMatch = value.match(MARKDOWN_PATTERNS.INLINE_CODE);
-      if (inlineCodeMatch && value.length > 2) {
-        const codeText = inlineCodeMatch[1];
-        safeExecuteCommand(
-          () => {
-            editor.commands.insertContent({
-              type: 'text',
-              text: codeText,
-              marks: [{ type: 'code' }],
-            });
-          },
-          () => {
-            editor.commands.insertContent(value, { contentType: 'markdown' });
-          },
-        );
-        return;
-      }
-
-      const codeBlockMatch = value.match(MARKDOWN_PATTERNS.CODE_BLOCK);
-      if (codeBlockMatch) {
-        const [, , lang, codeText] = codeBlockMatch;
-        safeExecuteCommand(
-          () => {
-            editor.commands.insertContent({
-              type: 'codeBlock',
-              attrs: lang ? { language: lang } : {},
-              content: [
-                {
-                  type: 'text',
-                  text: codeText,
-                },
-              ],
-            });
-          },
-          () => {
-            editor.commands.insertContent(value, { contentType: 'markdown' });
-          },
-        );
-        return;
-      }
-
-      const imageMatch = value.match(MARKDOWN_PATTERNS.IMAGE);
-      if (imageMatch) {
-        const [, alt, url] = imageMatch;
-        safeExecuteCommand(
-          () => {
-            editor.commands.insertContent({
-              type: 'image',
-              attrs: {
-                src: url,
-                alt: alt || '',
-              },
-            });
-          },
-          () => {
-            editor.commands.insertContent(value, { contentType: 'markdown' });
-          },
-        );
-        return;
-      }
-
-      const linkMatch = value.match(MARKDOWN_PATTERNS.LINK);
-      if (linkMatch) {
-        const [, text, url] = linkMatch;
-        safeExecuteCommand(
-          () => {
-            editor.commands.insertContent({
-              type: 'text',
-              text: text || url,
-              marks: [
-                {
-                  type: 'link',
-                  attrs: {
-                    href: url,
-                  },
-                },
-              ],
-            });
-          },
-          () => {
-            editor.commands.insertContent(value, { contentType: 'markdown' });
-          },
-        );
-        return;
-      }
-
-      const autoLinkMatch = value.match(MARKDOWN_PATTERNS.AUTO_LINK);
-      if (autoLinkMatch && value.length > 2) {
-        const url = autoLinkMatch[1];
-        safeExecuteCommand(
-          () => {
-            editor.commands.insertContent({
-              type: 'text',
-              text: url,
-              marks: [
-                {
-                  type: 'link',
-                  attrs: {
-                    href: url,
-                  },
-                },
-              ],
-            });
-          },
-          () => {
-            editor.commands.insertContent(value, { contentType: 'markdown' });
-          },
-        );
-        return;
-      }
-
-      if (MARKDOWN_PATTERNS.HORIZONTAL_RULE.test(value.trim())) {
-        safeExecuteCommand(
-          () => {
-            editor.commands.insertContent({
-              type: 'horizontalRule',
-            });
-          },
-          () => {
-            editor.commands.insertContent(value, { contentType: 'markdown' });
-          },
-        );
-        return;
-      }
-
-      safeExecuteCommand(() => {
-        editor.commands.insertContent(value, { contentType: 'markdown' });
-      });
-    },
-
-    focus: () => {
-      editor.commands.focus();
-    },
-
-    getCursor: () => {
-      try {
-        const { from } = editor.state.selection;
-        return convertTipTapPositionToCodeMirror(editor, from);
-      } catch (error) {
-        handleEditorError(
-          error as Error,
-          EditorErrorType.POSITION_CONVERSION_FAILED,
-          {
-            function: 'getCursor',
-          },
-        );
-        return { line: 0, ch: 0 };
-      }
-    },
-
-    setSelection: (anchor?: unknown, head?: unknown) => {
-      try {
-        if (
-          anchor &&
-          typeof anchor === 'object' &&
-          'line' in anchor &&
-          'ch' in anchor
-        ) {
-          const anchorPos = convertCodeMirrorPositionToTipTap(
-            editor,
-            anchor as Position,
-          );
-          let headPos = anchorPos;
-
-          if (
-            head &&
-            typeof head === 'object' &&
-            'line' in head &&
-            'ch' in head
-          ) {
-            headPos = convertCodeMirrorPositionToTipTap(
-              editor,
-              head as Position,
-            );
-          }
-
-          safeExecuteCommand(
-            () => {
-              editor.commands.setTextSelection({
-                from: anchorPos,
-                to: headPos,
-              });
-            },
-            undefined,
-            EditorErrorType.COMMAND_EXECUTION_FAILED,
-            { function: 'setSelection', anchorPos, headPos },
-          );
-        } else {
-          editor.commands.focus();
-        }
-      } catch (error) {
-        handleEditorError(
-          error as Error,
-          EditorErrorType.COMMAND_EXECUTION_FAILED,
-          {
-            function: 'setSelection',
-            anchor,
-            head,
-          },
-        );
-        safeExecuteCommand(
-          () => {
-            editor.commands.focus();
-          },
-          undefined,
-          EditorErrorType.COMMAND_EXECUTION_FAILED,
-          { function: 'setSelection', isFallback: true },
-        );
-      }
-    },
-
-    setReadOnly: (readOnly: boolean) => {
-      editor.setEditable(!readOnly);
-    },
-
-    replaceRange: (value: string, from?: unknown, to?: unknown) => {
-      if (from && to && typeof from === 'object' && typeof to === 'object') {
-        const { from: currentFrom, to: currentTo } = editor.state.selection;
-        const imageMatch = value.match(MARKDOWN_PATTERNS.IMAGE);
-        if (imageMatch) {
-          const [, alt, url] = imageMatch;
-          safeExecuteCommand(
-            () => {
-              editor.commands.insertContentAt(
-                { from: currentFrom, to: currentTo },
-                {
-                  type: 'image',
-                  attrs: {
-                    src: url,
-                    alt: alt || '',
-                  },
-                },
-              );
-            },
-            () => {
-              editor.commands.insertContentAt(
-                { from: currentFrom, to: currentTo },
-                value,
-                { contentType: 'markdown' },
-              );
-            },
-          );
-          return;
-        }
-
-        safeExecuteCommand(() => {
-          editor.commands.insertContentAt(
-            { from: currentFrom, to: currentTo },
-            value,
-            { contentType: 'markdown' },
-          );
-        });
-      } else {
-        const imageMatch = value.match(MARKDOWN_PATTERNS.IMAGE);
-        if (imageMatch) {
-          const [, alt, url] = imageMatch;
-          safeExecuteCommand(
-            () => {
-              editor.commands.insertContent({
-                type: 'image',
-                attrs: {
-                  src: url,
-                  alt: alt || '',
-                },
-              });
-            },
-            () => {
-              editor.commands.insertContent(value, {
-                contentType: 'markdown',
-              });
-            },
-          );
-          return;
-        }
-
-        safeExecuteCommand(() => {
-          editor.commands.insertContent(value, { contentType: 'markdown' });
-        });
-      }
-    },
-  };
-}
diff --git a/ui/src/components/Editor/utils/tiptap/commands.ts b/ui/src/components/Editor/utils/tiptap/commands.ts
deleted file mode 100644
index 08e2defc..00000000
--- a/ui/src/components/Editor/utils/tiptap/commands.ts
+++ /dev/null
@@ -1,720 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { Editor as TipTapEditor } from '@tiptap/react';
-import { Command } from '@codemirror/view';
-
-import { Level } from '../../types';
-
-import { safeExecuteCommand, logWarning } from './errorHandler';
-import { MARKDOWN_PATTERNS } from './constants';
-
-/**
- * Creates command methods module
- *
- * Provides command methods for the editor, including:
- * - Low-level methods: wrapText, replaceLines, appendBlock (for internal editor use)
- * - Semantic methods: insertBold, insertHeading, insertImage, etc. (for toolbar use)
- * - State query methods: isBold, isHeading, etc.
- *
- * @param editor - TipTap editor instance
- * @returns Object containing all command methods
- */
-export function createCommandMethods(editor: TipTapEditor) {
-  return {
-    wrapText: (before: string, after?: string, defaultText?: string) => {
-      const { from, to } = editor.state.selection;
-      const actualAfter = after || before;
-
-      if (before === '**' && actualAfter === '**') {
-        if (from === to) {
-          if (defaultText) {
-            const insertPos = from;
-            editor.commands.insertContent(defaultText);
-            editor.commands.setTextSelection({
-              from: insertPos,
-              to: insertPos + defaultText.length,
-            });
-            editor.commands.toggleBold();
-          } else {
-            editor.commands.toggleBold();
-          }
-        } else {
-          editor.commands.toggleBold();
-        }
-        return;
-      }
-
-      if (before === '*' && actualAfter === '*') {
-        if (from === to) {
-          if (defaultText) {
-            const insertPos = from;
-            editor.commands.insertContent(defaultText);
-            editor.commands.setTextSelection({
-              from: insertPos,
-              to: insertPos + defaultText.length,
-            });
-            editor.commands.toggleItalic();
-          } else {
-            editor.commands.toggleItalic();
-          }
-        } else {
-          editor.commands.toggleItalic();
-        }
-        return;
-      }
-
-      if (before === '`' && actualAfter === '`') {
-        if (from === to) {
-          if (defaultText) {
-            const insertPos = from;
-            editor.commands.insertContent(defaultText);
-            editor.commands.setTextSelection({
-              from: insertPos,
-              to: insertPos + defaultText.length,
-            });
-            editor.commands.toggleCode();
-          } else {
-            editor.commands.toggleCode();
-          }
-        } else {
-          editor.commands.toggleCode();
-        }
-        return;
-      }
-
-      if (before === '```\n' && actualAfter === '\n```') {
-        if (from === to) {
-          const codeBlockText = defaultText
-            ? `\`\`\`\n${defaultText}\n\`\`\``
-            : '```\n\n```';
-          safeExecuteCommand(
-            () => {
-              editor.commands.insertContent(codeBlockText, {
-                contentType: 'markdown',
-              });
-            },
-            () => {
-              editor.commands.insertContent({
-                type: 'codeBlock',
-                content: defaultText
-                  ? [
-                      {
-                        type: 'text',
-                        text: defaultText,
-                      },
-                    ]
-                  : [],
-              });
-            },
-          );
-        } else {
-          const selectedText = editor.state.doc.textBetween(from, to);
-          safeExecuteCommand(
-            () => {
-              editor.commands.insertContentAt(
-                { from, to },
-                {
-                  type: 'codeBlock',
-                  content: [
-                    {
-                      type: 'text',
-                      text: selectedText,
-                    },
-                  ],
-                },
-              );
-            },
-            () => {
-              const codeBlockText = `\`\`\`\n${selectedText}\n\`\`\``;
-              editor.commands.insertContentAt({ from, to }, codeBlockText, {
-                contentType: 'markdown',
-              });
-            },
-          );
-        }
-        return;
-      }
-
-      if (from === to) {
-        const text = before + (defaultText || '') + actualAfter;
-        editor.commands.insertContent(text, { contentType: 'markdown' });
-      } else {
-        const selectedText = editor.state.doc.textBetween(from, to);
-        const wrappedText = before + selectedText + actualAfter;
-        editor.commands.insertContentAt({ from, to }, wrappedText, {
-          contentType: 'markdown',
-        });
-      }
-    },
-
-    replaceLines: (replace: Parameters<Array<string>['map']>[0]) => {
-      const { from } = editor.state.selection;
-      const $pos = editor.state.doc.resolve(from);
-      const block = $pos.parent;
-      const lineText = block.textContent;
-      const newText = replace(lineText, 0, [lineText]) as string;
-
-      const finalText = newText || ' ';
-      const headingMatch = finalText.match(MARKDOWN_PATTERNS.HEADING);
-      if (headingMatch) {
-        const [, hashes, text] = headingMatch;
-        const level = hashes.length;
-        const start = $pos.start($pos.depth);
-        const end = $pos.end($pos.depth);
-
-        if (start < 0 || end < 0 || start > end) {
-          logWarning('Invalid position range for heading', { start, end });
-          return;
-        }
-
-        const headingText = text.trim() || 'Heading';
-        safeExecuteCommand(
-          () => {
-            if (start === end) {
-              editor.commands.insertContent({
-                type: 'heading',
-                attrs: { level },
-                content: [
-                  {
-                    type: 'text',
-                    text: headingText,
-                  },
-                ],
-              });
-            } else {
-              editor.commands.insertContentAt(
-                { from: start, to: end },
-                {
-                  type: 'heading',
-                  attrs: { level },
-                  content: [
-                    {
-                      type: 'text',
-                      text: headingText,
-                    },
-                  ],
-                },
-              );
-            }
-          },
-          () => {
-            const markdownText = finalText.trim() || `# Heading`;
-            if (start === end) {
-              editor.commands.insertContent(markdownText, {
-                contentType: 'markdown',
-              });
-            } else {
-              editor.commands.insertContentAt(
-                { from: start, to: end },
-                markdownText,
-                { contentType: 'markdown' },
-              );
-            }
-          },
-        );
-        return;
-      }
-
-      if (finalText.startsWith('> ')) {
-        const quoteText = finalText.slice(2).trim();
-        const start = $pos.start($pos.depth);
-        const end = $pos.end($pos.depth);
-
-        if (start < 0 || end < 0 || start > end) {
-          logWarning('Invalid position range for heading', { start, end });
-          return;
-        }
-
-        const quoteMarkdown = quoteText ? `> ${quoteText}` : '> ';
-        safeExecuteCommand(
-          () => {
-            if (start === end) {
-              editor.commands.insertContent(quoteMarkdown, {
-                contentType: 'markdown',
-              });
-            } else {
-              editor.commands.insertContentAt(
-                { from: start, to: end },
-                quoteMarkdown,
-                { contentType: 'markdown' },
-              );
-            }
-          },
-          () => {
-            if (start === end) {
-              editor.commands.insertContent({
-                type: 'paragraph',
-                content: quoteText ? [{ type: 'text', text: quoteText }] : [],
-              });
-            } else {
-              editor.commands.insertContentAt(
-                { from: start, to: end },
-                {
-                  type: 'paragraph',
-                  content: quoteText ? [{ type: 'text', text: quoteText }] : [],
-                },
-              );
-            }
-          },
-        );
-        return;
-      }
-
-      const olMatchOriginal = lineText.match(
-        MARKDOWN_PATTERNS.ORDERED_LIST_ORIGINAL,
-      );
-      const olMatchNew = finalText.match(MARKDOWN_PATTERNS.ORDERED_LIST_NEW);
-
-      if (olMatchOriginal || olMatchNew) {
-        const isInOrderedList = editor.isActive('orderedList');
-        const start = $pos.start($pos.depth);
-        const end = $pos.end($pos.depth);
-
-        if (start < 0 || end < 0 || start > end) {
-          logWarning('Invalid position range for ordered list', {
-            start,
-            end,
-          });
-          return;
-        }
-
-        if (olMatchOriginal && !olMatchNew) {
-          const textContent = finalText.trim();
-          const contentToInsert = textContent || 'Paragraph';
-
-          safeExecuteCommand(
-            () => {
-              if (start === end) {
-                editor.commands.insertContent(contentToInsert, {
-                  contentType: 'markdown',
-                });
-              } else {
-                editor.commands.insertContentAt(
-                  { from: start, to: end },
-                  contentToInsert,
-                  { contentType: 'markdown' },
-                );
-              }
-            },
-            () => {
-              if (start === end) {
-                editor.commands.insertContent({
-                  type: 'paragraph',
-                  content: [{ type: 'text', text: contentToInsert }],
-                });
-              } else {
-                editor.commands.insertContentAt(
-                  { from: start, to: end },
-                  {
-                    type: 'paragraph',
-                    content: [{ type: 'text', text: contentToInsert }],
-                  },
-                );
-              }
-            },
-          );
-          if (isInOrderedList) {
-            safeExecuteCommand(() => {
-              editor.chain().focus().toggleOrderedList().run();
-            });
-          }
-        } else if (!olMatchOriginal && olMatchNew) {
-          const [, , text] = olMatchNew;
-          const textContent = text.trim();
-          const contentToInsert = textContent || 'List item';
-
-          safeExecuteCommand(
-            () => {
-              if (start === end) {
-                editor.commands.insertContent(contentToInsert, {
-                  contentType: 'markdown',
-                });
-              } else {
-                editor.commands.insertContentAt(
-                  { from: start, to: end },
-                  contentToInsert,
-                  { contentType: 'markdown' },
-                );
-              }
-            },
-            () => {
-              if (start === end) {
-                editor.commands.insertContent({
-                  type: 'paragraph',
-                  content: [{ type: 'text', text: contentToInsert }],
-                });
-              } else {
-                editor.commands.insertContentAt(
-                  { from: start, to: end },
-                  {
-                    type: 'paragraph',
-                    content: [{ type: 'text', text: contentToInsert }],
-                  },
-                );
-              }
-            },
-          );
-          if (!isInOrderedList) {
-            safeExecuteCommand(() => {
-              editor.chain().focus().toggleOrderedList().run();
-            });
-          }
-        }
-        return;
-      }
-      const ulMatchOriginal = lineText.match(
-        MARKDOWN_PATTERNS.UNORDERED_LIST_ORIGINAL,
-      );
-      const ulMatchNew = finalText.match(MARKDOWN_PATTERNS.UNORDERED_LIST_NEW);
-
-      if (ulMatchOriginal || ulMatchNew) {
-        const isInBulletList = editor.isActive('bulletList');
-        const start = $pos.start($pos.depth);
-        const end = $pos.end($pos.depth);
-
-        if (start < 0 || end < 0 || start > end) {
-          logWarning('Invalid position range for unordered list', {
-            start,
-            end,
-          });
-          return;
-        }
-
-        if (ulMatchOriginal && !ulMatchNew) {
-          const textContent = finalText.trim();
-          const contentToInsert = textContent || 'Paragraph';
-
-          safeExecuteCommand(
-            () => {
-              if (start === end) {
-                editor.commands.insertContent(contentToInsert, {
-                  contentType: 'markdown',
-                });
-              } else {
-                editor.commands.insertContentAt(
-                  { from: start, to: end },
-                  contentToInsert,
-                  { contentType: 'markdown' },
-                );
-              }
-            },
-            () => {
-              if (start === end) {
-                editor.commands.insertContent({
-                  type: 'paragraph',
-                  content: [{ type: 'text', text: contentToInsert }],
-                });
-              } else {
-                editor.commands.insertContentAt(
-                  { from: start, to: end },
-                  {
-                    type: 'paragraph',
-                    content: [{ type: 'text', text: contentToInsert }],
-                  },
-                );
-              }
-            },
-          );
-          if (isInBulletList) {
-            safeExecuteCommand(() => {
-              editor.chain().focus().toggleBulletList().run();
-            });
-          }
-        } else if (!ulMatchOriginal && ulMatchNew) {
-          const [, text] = ulMatchNew;
-          const textContent = text.trim();
-          const contentToInsert = textContent || 'List item';
-
-          safeExecuteCommand(
-            () => {
-              if (start === end) {
-                editor.commands.insertContent(contentToInsert, {
-                  contentType: 'markdown',
-                });
-              } else {
-                editor.commands.insertContentAt(
-                  { from: start, to: end },
-                  contentToInsert,
-                  { contentType: 'markdown' },
-                );
-              }
-            },
-            () => {
-              if (start === end) {
-                editor.commands.insertContent({
-                  type: 'paragraph',
-                  content: [{ type: 'text', text: contentToInsert }],
-                });
-              } else {
-                editor.commands.insertContentAt(
-                  { from: start, to: end },
-                  {
-                    type: 'paragraph',
-                    content: [{ type: 'text', text: contentToInsert }],
-                  },
-                );
-              }
-            },
-          );
-          if (!isInBulletList) {
-            safeExecuteCommand(() => {
-              editor.chain().focus().toggleBulletList().run();
-            });
-          }
-        }
-        return;
-      }
-
-      const start = $pos.start($pos.depth);
-      const end = $pos.end($pos.depth);
-
-      if (start < 0 || end < 0 || start > end) {
-        logWarning('Invalid position range', {
-          start,
-          end,
-          function: 'replaceLines',
-        });
-        return;
-      }
-
-      const contentToInsert = finalText.trim() || ' ';
-
-      safeExecuteCommand(
-        () => {
-          if (start === end) {
-            editor.commands.insertContent(contentToInsert, {
-              contentType: 'markdown',
-            });
-          } else {
-            editor.commands.insertContentAt(
-              { from: start, to: end },
-              contentToInsert,
-              { contentType: 'markdown' },
-            );
-          }
-        },
-        () => {
-          if (start === end) {
-            editor.commands.insertContent({
-              type: 'paragraph',
-              content: [{ type: 'text', text: contentToInsert }],
-            });
-          } else {
-            editor.commands.insertContentAt(
-              { from: start, to: end },
-              {
-                type: 'paragraph',
-                content: [{ type: 'text', text: contentToInsert }],
-              },
-            );
-          }
-        },
-      );
-    },
-
-    appendBlock: (content: string) => {
-      if (MARKDOWN_PATTERNS.HORIZONTAL_RULE.test(content.trim())) {
-        safeExecuteCommand(
-          () => {
-            editor.commands.insertContent({
-              type: 'horizontalRule',
-            });
-          },
-          () => {
-            editor.commands.insertContent(content, {
-              contentType: 'markdown',
-            });
-          },
-        );
-        return;
-      }
-
-      safeExecuteCommand(() => {
-        editor.commands.insertContent(`\n\n${content}`, {
-          contentType: 'markdown',
-        });
-      });
-    },
-
-    addKeyMap: (keyMap: Record<string, Command>) => {
-      Object.keys(keyMap).forEach(() => {});
-    },
-    insertBold: (text?: string) => {
-      if (text) {
-        const { from } = editor.state.selection;
-        editor.commands.insertContent(text);
-        editor.commands.setTextSelection({ from, to: from + text.length });
-      }
-      editor.commands.toggleBold();
-    },
-
-    insertItalic: (text?: string) => {
-      if (text) {
-        const { from } = editor.state.selection;
-        editor.commands.insertContent(text);
-        editor.commands.setTextSelection({ from, to: from + text.length });
-      }
-      editor.commands.toggleItalic();
-    },
-
-    insertCode: (text?: string) => {
-      if (text) {
-        const { from } = editor.state.selection;
-        editor.commands.insertContent(text);
-        editor.commands.setTextSelection({ from, to: from + text.length });
-      }
-      editor.commands.toggleCode();
-    },
-
-    insertStrikethrough: (text?: string) => {
-      if (text) {
-        const { from } = editor.state.selection;
-        editor.commands.insertContent(text);
-        editor.commands.setTextSelection({ from, to: from + text.length });
-      }
-      editor.commands.toggleStrike();
-    },
-
-    insertHeading: (level: Level, text?: string) => {
-      if (text) {
-        // Insert heading using TipTap's native API to ensure proper structure
-        safeExecuteCommand(
-          () => {
-            editor.commands.insertContent({
-              type: 'heading',
-              attrs: { level },
-              content: [
-                {
-                  type: 'text',
-                  text,
-                },
-              ],
-            });
-            // Select only the text part (excluding the heading node structure)
-            // After insertion, the cursor is at the end of the heading
-            // We need to select backwards from the current position
-            const { to } = editor.state.selection;
-            editor.commands.setTextSelection({
-              from: to - text.length,
-              to,
-            });
-          },
-          () => {
-            // Fallback: use markdown format
-            const headingText = `${'#'.repeat(level)} ${text}`;
-            editor.commands.insertContent(headingText, {
-              contentType: 'markdown',
-            });
-          },
-        );
-      } else {
-        editor.commands.toggleHeading({ level });
-      }
-    },
-
-    insertBlockquote: (text?: string) => {
-      if (text) {
-        const { from } = editor.state.selection;
-        const blockquoteText = `> ${text}`;
-
-        // Use chain to ensure selection happens after insertion
-        editor
-          .chain()
-          .focus()
-          .insertContent(blockquoteText, { contentType: 'markdown' })
-          .setTextSelection({
-            from: from + 1,
-            to: from + 1 + text.length,
-          })
-          .run();
-      } else {
-        editor.commands.toggleBlockquote();
-      }
-    },
-
-    insertCodeBlock: (language?: string, code?: string) => {
-      const lang = language || '';
-      const codeText = code || 'code here';
-      editor.commands.insertContent(`\`\`\`${lang}\n${codeText}\n\`\`\``, {
-        contentType: 'markdown',
-      });
-    },
-
-    insertHorizontalRule: () => {
-      editor.commands.setHorizontalRule();
-    },
-
-    insertOrderedList: () => {
-      editor.commands.toggleOrderedList();
-    },
-
-    insertUnorderedList: () => {
-      editor.commands.toggleBulletList();
-    },
-
-    toggleOrderedList: () => {
-      editor.commands.toggleOrderedList();
-    },
-
-    toggleUnorderedList: () => {
-      editor.commands.toggleBulletList();
-    },
-
-    insertLink: (url: string, text?: string) => {
-      const linkText = text || url;
-      editor.commands.insertContent(`[${linkText}](${url})`, {
-        contentType: 'markdown',
-      });
-    },
-
-    insertImage: (url: string, alt?: string) => {
-      editor.commands.setImage({ src: url, alt: alt || 'image' });
-    },
-
-    insertTable: (rows = 3, cols = 3) => {
-      editor.commands.insertTable({
-        rows,
-        cols,
-        withHeaderRow: true,
-      });
-    },
-
-    indent: () => {
-      editor.commands.sinkListItem('listItem');
-    },
-
-    outdent: () => {
-      editor.commands.liftListItem('listItem');
-    },
-
-    isBold: () => editor.isActive('bold'),
-    isItalic: () => editor.isActive('italic'),
-    isHeading: (level?: number) => {
-      if (level) {
-        return editor.isActive('heading', { level });
-      }
-      return editor.isActive('heading');
-    },
-    isBlockquote: () => editor.isActive('blockquote'),
-    isCodeBlock: () => editor.isActive('codeBlock'),
-    isOrderedList: () => editor.isActive('orderedList'),
-    isUnorderedList: () => editor.isActive('bulletList'),
-  };
-}
diff --git a/ui/src/components/Editor/utils/tiptap/constants.ts b/ui/src/components/Editor/utils/tiptap/constants.ts
deleted file mode 100644
index a4ff7de4..00000000
--- a/ui/src/components/Editor/utils/tiptap/constants.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * Markdown pattern matching regular expression constants
- *
- * Defines regular expression patterns for parsing and matching Markdown syntax.
- * These patterns are used to convert Markdown syntax to TipTap nodes, or from TipTap nodes
- * to Markdown format.
- *
- * @example
- * ```typescript
- * const headingMatch = text.match(MARKDOWN_PATTERNS.HEADING);
- * if (headingMatch) {
- *   const level = headingMatch[1].length; // Number of #
- *   const text = headingMatch[2]; // Heading text
- * }
- * ```
- */
-export const MARKDOWN_PATTERNS = {
-  HEADING: /^(#{1,6})\s+(.+)$/,
-  ORDERED_LIST_ORIGINAL: /^(\s{0,})(\d+)\.\s/,
-  ORDERED_LIST_NEW: /^(\d+)\.\s*(.*)$/,
-  UNORDERED_LIST_ORIGINAL: /^(\s{0,})(-|\*)\s/,
-  UNORDERED_LIST_NEW: /^[-*]\s*(.*)$/,
-  INLINE_CODE: /^`(.+?)`$/,
-  CODE_BLOCK: /^(\n)?```(\w+)?\n([\s\S]*?)\n```(\n)?$/,
-  IMAGE: /^!\[([^\]]*)\]\(([^)]+)\)$/,
-  LINK: /^\[([^\]]*)\]\(([^)]+)\)$/,
-  AUTO_LINK: /^<(.+?)>$/,
-  HORIZONTAL_RULE: /^-{3,}$/,
-} as const;
diff --git a/ui/src/components/Editor/utils/tiptap/errorHandler.ts b/ui/src/components/Editor/utils/tiptap/errorHandler.ts
deleted file mode 100644
index c8f4e7a3..00000000
--- a/ui/src/components/Editor/utils/tiptap/errorHandler.ts
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * Editor error type enumeration
- *
- * Defines various error types that may occur in the editor, used for error classification and handling.
- */
-export enum EditorErrorType {
-  COMMAND_EXECUTION_FAILED = 'COMMAND_EXECUTION_FAILED',
-  POSITION_CONVERSION_FAILED = 'POSITION_CONVERSION_FAILED',
-  CONTENT_PARSING_FAILED = 'CONTENT_PARSING_FAILED',
-  EVENT_LISTENER_FAILED = 'EVENT_LISTENER_FAILED',
-}
-
-/**
- * Editor error interface
- */
-export interface EditorError {
-  type: EditorErrorType;
-  message: string;
-  originalError?: Error;
-  context?: Record<string, unknown>;
-  timestamp: number;
-}
-
-/**
- * Handles editor errors with unified log format
- *
- * Unified error handling for the editor, recording error information, context, and stack traces
- * for easier problem identification and debugging.
- *
- * @param error - Original error object
- * @param type - Error type
- * @param context - Optional context information (function name, parameters, etc.)
- * @returns Processed error object
- *
- * @example
- * ```typescript
- * try {
- *   editor.commands.insertContent(content);
- * } catch (error) {
- *   handleEditorError(error, EditorErrorType.COMMAND_EXECUTION_FAILED, {
- *     function: 'insertContent',
- *     content: content.substring(0, 50),
- *   });
- * }
- * ```
- */
-export function handleEditorError(
-  error: Error,
-  type: EditorErrorType,
-  context?: Record<string, unknown>,
-): EditorError {
-  const editorError: EditorError = {
-    type,
-    message: error.message,
-    originalError: error,
-    context,
-    timestamp: Date.now(),
-  };
-
-  console.error(`[Editor Error] ${type}:`, {
-    message: editorError.message,
-    context: editorError.context,
-    stack: error.stack,
-  });
-
-  return editorError;
-}
-
-/**
- * Safely executes TipTap command with error handling and fallback strategy
- *
- * Automatically catches errors when executing TipTap commands. If a fallback function is provided,
- * it attempts to execute the fallback operation when the main command fails. All errors are uniformly recorded.
- *
- * @param command - Main command function to execute
- * @param fallback - Optional fallback function to execute when main command fails
- * @param errorType - Error type, defaults to COMMAND_EXECUTION_FAILED
- * @param context - Optional context information
- * @returns Command execution result, returns undefined if failed and no fallback
- *
- * @example
- * ```typescript
- * const result = safeExecuteCommand(
- *   () => editor.commands.insertContent(content),
- *   () => editor.commands.insertContent(content, { contentType: 'markdown' }),
- *   EditorErrorType.COMMAND_EXECUTION_FAILED,
- *   { function: 'insertContent', contentLength: content.length }
- * );
- * ```
- */
-export function safeExecuteCommand<T>(
-  command: () => T,
-  fallback?: () => T,
-  errorType: EditorErrorType = EditorErrorType.COMMAND_EXECUTION_FAILED,
-  context?: Record<string, unknown>,
-): T | undefined {
-  try {
-    return command();
-  } catch (error) {
-    handleEditorError(error as Error, errorType, context);
-    if (fallback) {
-      try {
-        return fallback();
-      } catch (fallbackError) {
-        handleEditorError(fallbackError as Error, errorType, {
-          ...context,
-          isFallback: true,
-        });
-      }
-    }
-    return undefined;
-  }
-}
-
-/**
- * Logs warning information (for non-fatal errors)
- *
- * Records non-fatal warning information to alert potential issues without affecting functionality.
- *
- * @param message - Warning message
- * @param context - Optional context information
- *
- * @example
- * ```typescript
- * if (start < 0 || end < 0) {
- *   logWarning('Invalid position range', { start, end, function: 'setSelection' });
- *   return;
- * }
- * ```
- */
-export function logWarning(
-  message: string,
-  context?: Record<string, unknown>,
-): void {
-  console.warn(`[Editor Warning] ${message}`, context || {});
-}
diff --git a/ui/src/components/Editor/utils/tiptap/events.ts b/ui/src/components/Editor/utils/tiptap/events.ts
deleted file mode 100644
index 2a86440d..00000000
--- a/ui/src/components/Editor/utils/tiptap/events.ts
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { Editor as TipTapEditor } from '@tiptap/react';
-
-import { logWarning } from './errorHandler';
-
-/**
- * Checks if editor view is available
- */
-function isViewAvailable(editor: TipTapEditor): boolean {
-  if (!editor) {
-    return false;
-  }
-  if (editor.isDestroyed) {
-    return false;
-  }
-  return !!(editor.view && editor.state);
-}
-
-/**
- * Creates event handling methods module
- *
- * Provides event handling methods for the editor, including:
- * - on: Register event listeners (change, focus, blur, dragenter, dragover, drop, paste)
- * - off: Remove event listeners
- *
- * Note: For DOM events (dragenter, dragover, drop, paste),
- * the editor view must be mounted before binding events.
- *
- * @param editor - TipTap editor instance
- * @returns Object containing event handling methods
- */
-export function createEventMethods(editor: TipTapEditor) {
-  return {
-    on: (event: string, callback: (e?: unknown) => void) => {
-      if (event === 'change') {
-        editor.on('update', callback);
-      } else if (event === 'focus') {
-        editor.on('focus', callback);
-      } else if (event === 'blur') {
-        editor.on('blur', callback);
-      } else if (
-        event === 'dragenter' ||
-        event === 'dragover' ||
-        event === 'drop' ||
-        event === 'paste'
-      ) {
-        if (!isViewAvailable(editor)) {
-          logWarning(
-            'TipTap editor view is not available yet. Event listener not attached.',
-            {
-              event,
-            },
-          );
-          return;
-        }
-        editor.view.dom.addEventListener(event, callback as EventListener);
-      }
-    },
-
-    off: (event: string, callback: (e?: unknown) => void) => {
-      if (
-        (event === 'dragenter' ||
-          event === 'dragover' ||
-          event === 'drop' ||
-          event === 'paste') &&
-        !isViewAvailable(editor)
-      ) {
-        return;
-      }
-      if (event === 'change') {
-        editor.off('update', callback);
-      } else if (event === 'focus') {
-        editor.off('focus', callback);
-      } else if (event === 'blur') {
-        editor.off('blur', callback);
-      } else if (
-        event === 'dragenter' ||
-        event === 'dragover' ||
-        event === 'drop' ||
-        event === 'paste'
-      ) {
-        editor.view.dom.removeEventListener(event, callback as EventListener);
-      }
-    },
-  };
-}
diff --git a/ui/src/components/Editor/utils/tiptap/position.ts b/ui/src/components/Editor/utils/tiptap/position.ts
deleted file mode 100644
index 378908b8..00000000
--- a/ui/src/components/Editor/utils/tiptap/position.ts
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { Editor as TipTapEditor } from '@tiptap/react';
-
-import { Position } from '../../types';
-
-import { handleEditorError, EditorErrorType } from './errorHandler';
-
-/**
- * Converts TipTap position to CodeMirror Position
- *
- * TipTap uses document tree-based node positions (character index), while CodeMirror uses
- * line-based positions (line number and column number). This function converts between them.
- *
- * @param editor - TipTap editor instance
- * @param pos - TipTap position index (character position)
- * @returns CodeMirror position object with line and ch properties
- *
- * @example
- * ```typescript
- * const tipTapPos = 100; // Character position
- * const codeMirrorPos = convertTipTapPositionToCodeMirror(editor, tipTapPos);
- * // { line: 5, ch: 10 }
- * ```
- */
-export function convertTipTapPositionToCodeMirror(
-  editor: TipTapEditor,
-  pos: number,
-): Position {
-  try {
-    const { doc } = editor.state;
-    let line = 0;
-    let ch = 0;
-    let currentPos = 0;
-
-    for (let i = 0; i < doc.content.childCount; i += 1) {
-      const child = doc.content.child(i);
-      const childSize = child.nodeSize;
-
-      if (currentPos + childSize > pos) {
-        const text = child.textContent;
-        const relativePos = pos - currentPos;
-
-        const textBeforePos = text.substring(0, relativePos);
-        const newlineMatches = textBeforePos.match(/\n/g);
-        line += newlineMatches ? newlineMatches.length : 0;
-        ch = relativePos - textBeforePos.lastIndexOf('\n') - 1;
-        break;
-      }
-
-      const text = child.textContent;
-      const newlineMatches = text.match(/\n/g);
-      line += newlineMatches ? newlineMatches.length : 0;
-      currentPos += childSize;
-    }
-
-    return { line, ch };
-  } catch (error) {
-    handleEditorError(
-      error as Error,
-      EditorErrorType.POSITION_CONVERSION_FAILED,
-      {
-        function: 'convertTipTapPositionToCodeMirror',
-        position: pos,
-      },
-    );
-    return { line: 0, ch: 0 };
-  }
-}
-
-/**
- * Converts CodeMirror Position to TipTap position index
- *
- * Converts CodeMirror's line-based position to TipTap's character index position.
- *
- * @param editor - TipTap editor instance
- * @param position - CodeMirror position object with line and ch properties
- * @returns TipTap position index (character position)
- *
- * @example
- * ```typescript
- * const codeMirrorPos = { line: 5, ch: 10 };
- * const tipTapPos = convertCodeMirrorPositionToTipTap(editor, codeMirrorPos);
- * // 100 (character position)
- * ```
- */
-export function convertCodeMirrorPositionToTipTap(
-  editor: TipTapEditor,
-  position: Position,
-): number {
-  try {
-    const { doc } = editor.state;
-    let currentLine = 0;
-    let currentPos = 0;
-
-    for (let i = 0; i < doc.content.childCount; i += 1) {
-      const child = doc.content.child(i);
-      const text = child.textContent;
-      const lines = text.split('\n');
-
-      if (currentLine + lines.length - 1 >= position.line) {
-        const lineInNode = position.line - currentLine;
-        const { ch: posInLine } = position;
-
-        let pos = 0;
-        for (let j = 0; j < lineInNode; j += 1) {
-          pos += lines[j].length + 1; // +1 for newline
-        }
-        pos += posInLine;
-
-        return currentPos + pos;
-      }
-
-      currentLine += lines.length - 1;
-      currentPos += child.nodeSize;
-    }
-
-    return doc.content.size;
-  } catch (error) {
-    handleEditorError(
-      error as Error,
-      EditorErrorType.POSITION_CONVERSION_FAILED,
-      {
-        function: 'convertCodeMirrorPositionToTipTap',
-        position,
-      },
-    );
-    return editor.state.doc.content.size;
-  }
-}
diff --git a/ui/src/components/Editor/utils/tiptap/tableExtension.ts b/ui/src/components/Editor/utils/tiptap/tableExtension.ts
deleted file mode 100644
index 70e68f77..00000000
--- a/ui/src/components/Editor/utils/tiptap/tableExtension.ts
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { Table, TableOptions } from '@tiptap/extension-table';
-import type { NodeViewRendererProps } from '@tiptap/core';
-
-interface TableWrapperOptions extends TableOptions {
-  wrapperClass?: string;
-}
-
-export const TableWithWrapper = Table.extend<TableWrapperOptions>({
-  addOptions() {
-    const parentOptions = (this.parent?.() || {}) as Partial<TableOptions>;
-    return {
-      ...parentOptions,
-      HTMLAttributes: parentOptions.HTMLAttributes || {},
-      wrapperClass: 'table-responsive',
-    } as TableWrapperOptions;
-  },
-
-  addNodeView() {
-    return (props: NodeViewRendererProps) => {
-      const { node } = props;
-      const wrapperClass = this.options.wrapperClass || 'table-responsive';
-
-      const dom = document.createElement('div');
-      dom.className = wrapperClass;
-
-      const table = document.createElement('table');
-
-      const htmlAttrs = this.options.HTMLAttributes || {};
-      if (htmlAttrs.class) {
-        table.className = htmlAttrs.class as string;
-      }
-      if (htmlAttrs.style && typeof htmlAttrs.style === 'object') {
-        Object.assign(table.style, htmlAttrs.style);
-      }
-
-      const colgroup = document.createElement('colgroup');
-      if (node.firstChild) {
-        const { childCount } = node.firstChild;
-        for (let i = 0; i < childCount; i += 1) {
-          const col = document.createElement('col');
-          colgroup.appendChild(col);
-        }
-      }
-      table.appendChild(colgroup);
-
-      const tbody = document.createElement('tbody');
-      table.appendChild(tbody);
-      dom.appendChild(table);
-
-      return {
-        dom,
-        contentDOM: tbody,
-        update: (updatedNode) => {
-          if (updatedNode.type !== node.type) {
-            return false;
-          }
-          return true;
-        },
-      };
-    };
-  },
-});