[WIKI-537] [WIKI-539] refactor: document editor#7384
[WIKI-537] [WIKI-539] refactor: document editor#7384sriramveeraghanta merged 11 commits intopreviewfrom
Conversation
WalkthroughThis change unifies the document editor components by introducing a new Changes
Sequence Diagram(s)sequenceDiagram
participant ParentComponent
participant DocumentEditor
participant Hooks
participant EditorInstance
participant PageRenderer
ParentComponent->>DocumentEditor: Render with props (editable/read-only)
DocumentEditor->>Hooks: Fetch user, config, handlers, flags
DocumentEditor->>EditorInstance: Initialize with extensions, handlers, value
EditorInstance-->>DocumentEditor: Return editor instance
DocumentEditor->>PageRenderer: Render with editor instance and config
Possibly related PRs
Suggested labels
Suggested reviewers
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~15 minutes Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
|
Pull Request Linked with Plane Work Items
Comment Automatically Generated by Plane |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
packages/editor/src/core/helpers/scroll-to-node.ts (1)
35-35: Consider adding proper type imports instead of disabling ESLint.The
no-undefESLint rule is being disabled, likely due to theScrollBehaviortype not being recognized. Consider importing the type explicitly or ensuring proper TypeScript DOM types are available.+/// <reference lib="dom" /> + -// eslint-disable-next-line no-undef export function scrollToNodeViaDOMCoordinates(editor: Editor, pos: number, behavior?: ScrollBehavior): void {Alternatively, if the type is still not recognized, you can define it explicitly:
+type ScrollBehavior = "auto" | "smooth" | "instant"; + -// eslint-disable-next-line no-undef export function scrollToNodeViaDOMCoordinates(editor: Editor, pos: number, behavior?: ScrollBehavior): void {
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (17)
apps/web/core/components/editor/document/editor.tsx(1 hunks)apps/web/core/components/editor/index.ts(1 hunks)apps/web/core/components/editor/lite-text-editor/index.ts(0 hunks)apps/web/core/components/editor/lite-text/index.ts(1 hunks)apps/web/core/components/editor/rich-text-editor/index.ts(0 hunks)apps/web/core/components/editor/rich-text/index.ts(1 hunks)apps/web/core/components/inbox/modals/create-modal/issue-description.tsx(1 hunks)apps/web/core/components/pages/version/editor.tsx(2 hunks)packages/editor/src/ce/extensions/document-extensions.tsx(1 hunks)packages/editor/src/core/components/editors/document/editor.tsx(1 hunks)packages/editor/src/core/components/editors/document/index.ts(1 hunks)packages/editor/src/core/components/editors/document/read-only-editor.tsx(0 hunks)packages/editor/src/core/helpers/scroll-to-node.ts(1 hunks)packages/editor/src/core/hooks/use-editor.ts(1 hunks)packages/editor/src/core/types/editor.ts(3 hunks)packages/editor/src/core/types/hook.ts(2 hunks)packages/editor/src/index.ts(1 hunks)
💤 Files with no reviewable changes (3)
- apps/web/core/components/editor/lite-text-editor/index.ts
- apps/web/core/components/editor/rich-text-editor/index.ts
- packages/editor/src/core/components/editors/document/read-only-editor.tsx
🧰 Additional context used
🧠 Learnings (3)
apps/web/core/components/inbox/modals/create-modal/issue-description.tsx (3)
Learnt from: mathalav55
PR: makeplane/plane#6107
File: web/ce/components/workspace-notifications/sidebar/notification-card/options/archive.tsx:11-14
Timestamp: 2024-11-28T07:02:54.664Z
Learning: When components are still located in `core`, it's appropriate for files to import them using `@/components/...`, and the migration to the new import paths is not necessary in such cases.
Learnt from: mathalav55
PR: makeplane/plane#6107
File: web/ce/components/workspace-notifications/sidebar/notification-card/options/read.tsx:11-12
Timestamp: 2024-11-28T07:02:15.514Z
Learning: Some components are still in core and have not been moved yet, so their import paths remain the same.
Learnt from: vamsikrishnamathala
PR: makeplane/plane#7061
File: web/core/components/workspace-notifications/root.tsx:18-18
Timestamp: 2025-05-14T13:16:23.323Z
Learning: In the Plane project codebase, the path alias `@/plane-web` resolves to the `ce` directory, making imports like `@/plane-web/hooks/use-notification-preview` correctly resolve to files in `web/ce/hooks/`.
apps/web/core/components/editor/index.ts (2)
Learnt from: mathalav55
PR: makeplane/plane#6107
File: web/ce/components/workspace-notifications/sidebar/notification-card/options/read.tsx:11-12
Timestamp: 2024-11-28T07:02:15.514Z
Learning: Some components are still in core and have not been moved yet, so their import paths remain the same.
Learnt from: mathalav55
PR: makeplane/plane#6107
File: web/ce/components/workspace-notifications/sidebar/notification-card/options/archive.tsx:11-14
Timestamp: 2024-11-28T07:02:54.664Z
Learning: When components are still located in `core`, it's appropriate for files to import them using `@/components/...`, and the migration to the new import paths is not necessary in such cases.
apps/web/core/components/pages/version/editor.tsx (1)
Learnt from: vamsikrishnamathala
PR: makeplane/plane#7061
File: web/core/components/workspace-notifications/root.tsx:18-18
Timestamp: 2025-05-14T13:16:23.323Z
Learning: In the Plane project codebase, the path alias `@/plane-web` resolves to the `ce` directory, making imports like `@/plane-web/hooks/use-notification-preview` correctly resolve to files in `web/ce/hooks/`.
🧬 Code Graph Analysis (3)
apps/web/core/components/pages/version/editor.tsx (1)
apps/web/core/components/editor/document/editor.tsx (1)
DocumentEditor(34-90)
packages/editor/src/core/types/editor.ts (2)
packages/editor/src/core/types/ai.ts (1)
TAIHandler(6-8)packages/editor/src/core/types/config.ts (1)
TUserDetails(38-43)
apps/web/core/components/editor/document/editor.tsx (3)
packages/editor/src/core/types/editor.ts (2)
IDocumentEditorProps(163-169)EditorRefApi(101-119)packages/editor/src/core/types/config.ts (1)
TFileHandler(11-23)packages/utils/src/common.ts (1)
cn(8-8)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Analyze (javascript)
🔇 Additional comments (21)
apps/web/core/components/editor/lite-text/index.ts (1)
1-3: LGTM! Clean aggregator pattern.The re-export structure follows good practices for creating a single entry point for the lite-text editor components.
apps/web/core/components/inbox/modals/create-modal/issue-description.tsx (1)
13-13: Import path validatedThe import
"@/components/editor/rich-text/editor"correctly resolves toapps/web/core/components/editor/rich-text/editor.tsx, which exportsRichTextEditor. No further changes are needed.apps/web/core/components/editor/rich-text/index.ts (1)
1-1: LGTM! Simple and clean export aggregator.The export structure is clean and follows the refactoring pattern described in the PR objectives.
packages/editor/src/ce/extensions/document-extensions.tsx (1)
14-14: Good addition to support unified editor approach.The
isEditableproperty addition aligns well with the refactoring to use a singleDocumentEditorcomponent that supports both editable and read-only modes via props.packages/editor/src/core/components/editors/document/index.ts (1)
2-2: DocumentEditor export verifiedThe
editor.tsxfile definesDocumentEditorWithRefand exports it as a named export. Theindex.tsfile’sexport * from "./editor"now correctly re-exports this component.No further changes required.
packages/editor/src/core/types/hook.ts (1)
2-2: Good import addition for Content type.The import of
Contenttype from@tiptap/coreis appropriate for the type system updates.packages/editor/src/core/hooks/use-editor.ts (1)
73-73: TipTap handles undefinedinitialValuesafely by defaultWe’ve confirmed that when
contentisundefined, TipTap initializes as an empty document without throwing errors. Removing the old fallback logic inpackages/editor/src/core/hooks/use-editor.ts(line 73) is safe under the default configuration.• No changes required in
use-editor.tsfor handlingundefined
• If you need strict schema validation, consider enablingenableContentCheckand handling thecontentErrorevent in your Editor configapps/web/core/components/editor/index.ts (1)
2-2: Confirmed export paths and contents
Bothlite-textandrich-textdirectories exist underapps/web/core/components/editor/and theirindex.tsfiles correctly re-export the expected modules:
- apps/web/core/components/editor/lite-text/index.ts exports:
./editor./read-only-editor./toolbar- apps/web/core/components/editor/rich-text/index.ts exports:
./editorNo further changes are needed.
packages/editor/src/core/types/editor.ts (2)
1-2: Good optimization with type-only imports.Converting to
import typefor Extensions, JSONContent, and Selection is a good practice that can help with bundle optimization by ensuring these imports are only used for type checking and not included in the runtime bundle.
163-169: Well-designed interface for the new unified document editor.The
IDocumentEditorPropsinterface is well-structured, extending fromIEditorPropswhile omitting properties that are not needed (initialValue,onEnterKeyPress) and adding new capabilities (aiHandler,embedHandler,user). The requirededitableprop enables the unified editor to work in both read-only and editable modes.The change from
stringtoContenttype for the value prop aligns with TipTap's type system and should provide better type safety.apps/web/core/components/pages/version/editor.tsx (4)
4-4: Import optimization aligns with type changes.Good change to only import
TDisplayConfigfrom@plane/editorsince the component no longer needs direct access to the editor implementation types.
8-8: Correct import path for the new document editor.The import path change to use the local wrapper component is correct and follows the refactoring pattern where complex editor logic is encapsulated in the wrapper.
81-92: Proper component usage with simplified props.The refactoring correctly:
- Uses
DocumentEditorinstead ofDocumentReadOnlyEditorWithRef- Sets
editable={false}for read-only mode- Passes
valueas JSON content instead of HTML- Includes
keyprop for proper re-rendering when version changes- Maintains essential props like
displayConfigand stylingThe simplified prop structure delegates complex configuration to the wrapper component, which is a good separation of concerns.
77-78: Verifydescription_jsonhandling and structureThe
TPageVersion.description_jsonfield is typed asobject | null | undefined, so the checkconst description = versionDetails?.description_json; if (!description) return null;correctly guards against missing or null content. Please verify that the JSON payload conforms to the expected schema—consider defining a more specific TypeScript interface or adding runtime validation to enforce its structure.
– packages/types/src/page/core.ts (TPageVersion
description_json?: object)
– apps/web/core/components/pages/version/editor.tsx (null check at lines 77–78)packages/editor/src/core/components/editors/document/editor.tsx (2)
70-84: Proper editor initialization with updated hook usage.The
useEditorhook is called with appropriate parameters, including the newContenttype forinitialValue. The parameter mapping is correct and maintains backward compatibility.
103-105: Correct forwardRef implementation.The forwardRef wrapper properly forwards the ref to the internal component while maintaining type safety with
EditorRefApi.apps/web/core/components/editor/document/editor.tsx (5)
15-32: Excellent type design with discriminated union.The
DocumentEditorWrapperPropstype is well-designed using a discriminated union to ensure that editable editors requiresearchMentionCallbackanduploadFileprops, while read-only editors don't. This provides compile-time safety and prevents runtime errors.
50-52: Proper conditional logic for mention search.The conditional setup for
searchEntitycorrectly handles both editable and read-only modes, providing an empty object for read-only mode and the actual search callback for editable mode.
67-72: Good conditional file handler configuration.The file handler setup properly handles the editable vs read-only distinction by providing either the actual upload function or an empty async function. This prevents errors while maintaining the expected interface.
74-77: Appropriate error handling for mention search.The error handling in the mention search callback is good - it throws an error when
fetchMentionsfails, which will be caught by the editor's error boundary or handled appropriately by the consuming code.
82-84: Proper embed handler merging.The embed handler configuration correctly merges the issue embed props with any additional embed handlers passed via props, providing a flexible extension mechanism.
There was a problem hiding this comment.
Actionable comments posted: 4
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (17)
apps/web/core/components/editor/document/editor.tsx(1 hunks)apps/web/core/components/editor/index.ts(1 hunks)apps/web/core/components/editor/lite-text-editor/index.ts(0 hunks)apps/web/core/components/editor/lite-text/index.ts(1 hunks)apps/web/core/components/editor/rich-text-editor/index.ts(0 hunks)apps/web/core/components/editor/rich-text/index.ts(1 hunks)apps/web/core/components/inbox/modals/create-modal/issue-description.tsx(1 hunks)apps/web/core/components/pages/version/editor.tsx(2 hunks)packages/editor/src/ce/extensions/document-extensions.tsx(1 hunks)packages/editor/src/core/components/editors/document/editor.tsx(1 hunks)packages/editor/src/core/components/editors/document/index.ts(1 hunks)packages/editor/src/core/components/editors/document/read-only-editor.tsx(0 hunks)packages/editor/src/core/helpers/scroll-to-node.ts(1 hunks)packages/editor/src/core/hooks/use-editor.ts(1 hunks)packages/editor/src/core/types/editor.ts(3 hunks)packages/editor/src/core/types/hook.ts(2 hunks)packages/editor/src/index.ts(1 hunks)
💤 Files with no reviewable changes (3)
- apps/web/core/components/editor/rich-text-editor/index.ts
- apps/web/core/components/editor/lite-text-editor/index.ts
- packages/editor/src/core/components/editors/document/read-only-editor.tsx
🧰 Additional context used
🧠 Learnings (3)
apps/web/core/components/inbox/modals/create-modal/issue-description.tsx (3)
Learnt from: mathalav55
PR: makeplane/plane#6107
File: web/ce/components/workspace-notifications/sidebar/notification-card/options/archive.tsx:11-14
Timestamp: 2024-11-28T07:02:54.664Z
Learning: When components are still located in `core`, it's appropriate for files to import them using `@/components/...`, and the migration to the new import paths is not necessary in such cases.
Learnt from: mathalav55
PR: makeplane/plane#6107
File: web/ce/components/workspace-notifications/sidebar/notification-card/options/read.tsx:11-12
Timestamp: 2024-11-28T07:02:15.514Z
Learning: Some components are still in core and have not been moved yet, so their import paths remain the same.
Learnt from: vamsikrishnamathala
PR: makeplane/plane#7061
File: web/core/components/workspace-notifications/root.tsx:18-18
Timestamp: 2025-05-14T13:16:23.323Z
Learning: In the Plane project codebase, the path alias `@/plane-web` resolves to the `ce` directory, making imports like `@/plane-web/hooks/use-notification-preview` correctly resolve to files in `web/ce/hooks/`.
apps/web/core/components/editor/index.ts (3)
Learnt from: mathalav55
PR: makeplane/plane#6107
File: web/ce/components/workspace-notifications/sidebar/notification-card/options/read.tsx:11-12
Timestamp: 2024-11-28T07:02:15.514Z
Learning: Some components are still in core and have not been moved yet, so their import paths remain the same.
Learnt from: mathalav55
PR: makeplane/plane#6107
File: web/ce/components/workspace-notifications/sidebar/notification-card/options/archive.tsx:11-14
Timestamp: 2024-11-28T07:02:54.664Z
Learning: When components are still located in `core`, it's appropriate for files to import them using `@/components/...`, and the migration to the new import paths is not necessary in such cases.
Learnt from: lifeiscontent
PR: makeplane/plane#7164
File: packages/ui/.storybook/main.ts:24-47
Timestamp: 2025-06-04T16:22:44.344Z
Learning: In packages/ui/.storybook/main.ts, the webpackFinal function intentionally overrides the CSS loader strategy by finding and replacing existing CSS rules. This is a temporary workaround for a known upstream issue in Storybook's CSS handling that has been communicated to the Storybook maintainers. The current implementation should not be changed until the upstream issue is resolved.
apps/web/core/components/pages/version/editor.tsx (1)
Learnt from: vamsikrishnamathala
PR: makeplane/plane#7061
File: web/core/components/workspace-notifications/root.tsx:18-18
Timestamp: 2025-05-14T13:16:23.323Z
Learning: In the Plane project codebase, the path alias `@/plane-web` resolves to the `ce` directory, making imports like `@/plane-web/hooks/use-notification-preview` correctly resolve to files in `web/ce/hooks/`.
🧬 Code Graph Analysis (3)
apps/web/core/components/editor/document/editor.tsx (3)
packages/editor/src/core/types/editor.ts (2)
IDocumentEditorProps(163-169)EditorRefApi(101-119)packages/editor/src/core/types/config.ts (1)
TFileHandler(11-23)packages/utils/src/common.ts (1)
cn(8-8)
packages/editor/src/core/components/editors/document/editor.tsx (10)
apps/web/core/components/editor/document/editor.tsx (1)
DocumentEditor(34-90)packages/editor/src/core/types/editor.ts (2)
IDocumentEditorProps(163-169)EditorRefApi(101-119)packages/editor/src/core/constants/config.ts (1)
DEFAULT_DISPLAY_CONFIG(4-9)packages/editor/src/core/extensions/work-item-embed/extension.tsx (1)
WorkItemEmbedExtension(17-30)packages/editor/src/core/extensions/side-menu.ts (1)
SideMenuExtension(34-52)packages/editor/src/ce/extensions/document-extensions.tsx (1)
DocumentEditorAdditionalExtensions(32-40)packages/editor/src/core/hooks/use-editor.ts (1)
useEditor(22-282)packages/editor/src/core/helpers/common.ts (1)
getEditorClassNames(13-21)packages/editor/src/core/components/editors/document/page-renderer.tsx (1)
PageRenderer(21-52)packages/utils/src/common.ts (1)
cn(8-8)
packages/editor/src/core/types/editor.ts (2)
packages/editor/src/core/types/ai.ts (1)
TAIHandler(6-8)packages/editor/src/core/types/config.ts (1)
TUserDetails(38-43)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Analyze (javascript)
🔇 Additional comments (19)
apps/web/core/components/inbox/modals/create-modal/issue-description.tsx (1)
13-13: LGTM: Import path correctly updated.The import path change from
rich-text-editor/rich-text-editortorich-text/editoraligns with the document editor refactoring objectives and maintains the same functionality.apps/web/core/components/editor/rich-text/index.ts (1)
1-1: LGTM: Clean aggregation module.The re-export pattern creates a clean entry point for the rich-text editor module, supporting the refactoring objectives to simplify the module structure.
packages/editor/src/core/helpers/scroll-to-node.ts (1)
35-35: LGTM: Appropriate ESLint suppression.The ESLint disable comment is necessary to suppress warnings about the
ScrollBehaviortype, which is a valid DOM API type that ESLint may not recognize.packages/editor/src/index.ts (1)
12-12: ✅ No remaining references toDocumentReadOnlyEditorWithRef; all imports now useDocumentEditorWithRefVerified that the old
DocumentReadOnlyEditorWithRefis entirely gone and replaced byDocumentEditorWithRefin all usage sites:
- packages/editor/src/index.ts
- packages/editor/src/core/components/editors/document/editor.tsx
- apps/web/core/components/editor/document/editor.tsx
- apps/web/core/components/pages/editor/editor-body.tsx
All looks good to merge.
apps/web/core/components/editor/lite-text/index.ts (1)
1-3: LGTM: Well-structured module aggregation.The re-export pattern creates a clean entry point for the lite-text editor modules, maintaining separation between editor and read-only variants while simplifying the overall module structure.
packages/editor/src/core/types/hook.ts (2)
2-2: Import addition for Content type is appropriate.Adding the
Contenttype import from@tiptap/coresupports the more structured content handling approach.
31-31: No external consumers ofTEditorHookProps—change is safe to mergeA search for
TEditorHookPropsonly returned its import inpackages/editor/src/core/hooks/use-editor.ts, and there are no other direct imports of this type elsewhere in the repo. All calls touseEditor(…)live within thepackages/editorpackage and already pass the updatedContent-typedinitialValue.• packages/editor/src/core/hooks/use-editor.ts – only definition/import of
TEditorHookProps
• Internal calls inpackages/editor/src/core/components/editors/*all use the newinitialValue?: ContentshapeNo further updates are required.
packages/editor/src/core/hooks/use-editor.ts (1)
73-73: AlluseEditorinvocations supplyinitialValue—no undefined content risk
- Ripgrep scan found every call to
useEditor({ … })includes aninitialValueprop.- The read-only editor hook still guards against undefined/falsy values with its own fallback.
No further action required.
apps/web/core/components/pages/version/editor.tsx (3)
4-11: Good refactoring of imports!The changes properly align with the new DocumentEditor architecture, moving editor-specific hooks into the component wrapper for better encapsulation.
77-78: Correct migration to JSON content format.The change aligns with the PR objective of establishing JSON as the source of truth for document editors.
81-92: Proper implementation of the new DocumentEditor component.The component is correctly configured for read-only mode with all necessary workspace and project identifiers.
packages/editor/src/core/types/editor.ts (3)
1-2: Good use of type-only imports.Using
import typefor TypeScript types improves bundle size and prevents potential circular dependency issues.
114-115: ESLint disable comment is appropriate.The
ScrollBehaviortype from the DOM API may not be recognized by ESLint in certain configurations, making this disable comment necessary.
163-169: Well-designed interface for the new DocumentEditor.The interface properly extends
IEditorPropswhile updating thevaluetype toContentfor ProseMirror compatibility, aligning with the PR objectives.apps/web/core/components/editor/document/editor.tsx (3)
15-32: Excellent type-safe prop definitions.The discriminated union pattern ensures that
searchMentionCallbackanduploadFileare only required when the editor is editable, providing strong type safety.
46-59: Well-organized hook integration.The hooks are properly composed to gather all necessary editor configuration, with appropriate conditional logic for the editable state.
61-90: Clean and well-structured component implementation.The component properly composes all hooks and handlers, with appropriate error handling for mention searches and conditional file upload based on editability.
packages/editor/src/core/components/editors/document/editor.tsx (2)
70-84: Proper editor initialization.The editor is correctly initialized with all necessary configuration props.
86-109: Well-structured component with proper ref forwarding.The component correctly handles the editor lifecycle with null checking and implements forwardRef pattern appropriately.
| projectId={projectId?.toString() ?? ""} | ||
| workspaceId={workspaceDetails?.id ?? ""} | ||
| workspaceSlug={workspaceSlug?.toString() ?? ""} |
There was a problem hiding this comment.
just a preference, but personally, I think this reads better.
e.g. data -> transforms to a string.
| projectId={projectId?.toString() ?? ""} | |
| workspaceId={workspaceDetails?.id ?? ""} | |
| workspaceSlug={workspaceSlug?.toString() ?? ""} | |
| projectId={String(projectId ?? "")} | |
| workspaceId={String(workspaceDetails ?? "")} | |
| workspaceSlug={String(workspaceSlug ?? "")} |
There was a problem hiding this comment.
I prefer not using String() as it even converts values like null and undefined to "null" and "undefined" respectively.
* refactor: document editor * chore: update user prop * fix: type warning * chore: update value prop name * chore: remove unnecessary exports * hore: update initialValue type * chore: revert initialValue type * refactor: unnecessary string handlers
Description
This PR refactors the document editor and its implementation in the web app in following ways-
editorprop.initialValuein anyProseMirroracceptable content format.Type of Change
Summary by CodeRabbit
New Features
Refactor
Chores