Conversation
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthroughGuards session auto-tag generation and fixes a missing brace; overrides TipTap Enter handling and increases chat input height; adds ResponsivePanelsManager to auto-collapse/restore side panels on resize; fixes transcript panel tooltip and updates en/ko locales; adds Turndown rules for Markdown task lists. No public API changes. Changes
Sequence Diagram(s)sequenceDiagram
participant U as User
participant CI as ChatInput
participant TE as TipTap Editor
participant SH as Submit Handler
U->>TE: Press Enter
TE->>CI: handleKeyDown override
alt input empty
CI-->>TE: Consume Enter (no submit)
else input non-empty
CI->>TE: preventDefault()
CI->>SH: submit(inputValue)
end
sequenceDiagram
participant W as Window
participant RPM as ResponsivePanelsManager
participant L as LeftPanel Store
participant R as RightPanel Store
W->>RPM: resize (width < 670)
alt first auto-collapse
RPM->>RPM: save original L/R
RPM->>L: set expanded=false
RPM->>R: set expanded=false
end
W->>RPM: resize (width >= 670)
alt was auto-collapsed
RPM->>L: restore expanded (if not user-overridden)
RPM->>R: restore expanded (if not user-overridden)
RPM->>RPM: clear auto-collapse state
end
sequenceDiagram
participant EC as Editor Content (HTML)
participant TD as Turndown (html2md)
participant R as Task List Rules
EC->>TD: Convert HTML to Markdown
TD->>R: Match UL[data-type="taskList"]
R-->>TD: passthrough children
TD->>R: Match LI with checkbox
R-->>TD: "- [x] text"/"- [ ] text\n"
TD-->>EC: Markdown output
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. 📜 Recent review detailsConfiguration used: .coderabbit.yaml 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
⏰ 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. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
Status, Documentation and Community
|
There was a problem hiding this comment.
Actionable comments posted: 1
🔭 Outside diff range comments (1)
apps/desktop/src/components/right-panel/components/chat/chat-input.tsx (1)
243-250: Prevent duplicate handling and remove debug loggingGuard the DOM keydown handler to ignore events already handled upstream, and remove the console.log to avoid leaking user input into logs.
Apply this diff:
- if (event.key === "Enter" && !event.shiftKey) { - console.log("Enter pressed, inputValue:", inputValue); - event.preventDefault(); + if (event.key === "Enter" && !event.shiftKey) { + if (event.defaultPrevented) return; + event.preventDefault(); if (inputValue.trim()) { handleSubmit(); } }
🧹 Nitpick comments (3)
apps/desktop/src/components/editor-area/index.tsx (1)
73-80: Consider allowing single-tag suggestionsCurrent condition requires more than one tag. If a single tag is suggested, it’s skipped.
Apply this diff to accept one or more suggested tags:
- if (suggestedTags.length > 1) { + if (suggestedTags.length >= 1) {apps/desktop/src/routes/app.tsx (1)
41-103: ResponsivePanelsManager logic is solid; tighten override detection and fix a comment typo
- The “track manual” comment has a typo.
- Using
!== falsemay mark overrides when state is undefined; prefer strict=== true.Apply this diff:
-// still experimental +// still experimental function ResponsivePanelsManager() { @@ - // trackmanual changes during auto-collapse + // track manual changes during auto-collapse useEffect(() => { if (wasAutoCollapsed && originalStates.current) { - if (leftExpanded !== false) { + if (leftExpanded === true) { userOverrodeLeft.current = true; } - if (rightExpanded !== false) { + if (rightExpanded === true) { userOverrodeRight.current = true; } } }, [leftExpanded, rightExpanded, wasAutoCollapsed]);apps/desktop/src/locales/ko/messages.po (1)
1548-1554: Provide a KO translation for the new tooltip (currently empty, will fall back to EN)Suggest adding a natural Korean translation for the tooltip.
Apply this diff:
msgid "Toggle transcript panel" -msgstr "" +msgstr "대화록 패널 전환"
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (7)
apps/desktop/src/components/editor-area/index.tsx(1 hunks)apps/desktop/src/components/right-panel/components/chat/chat-input.tsx(3 hunks)apps/desktop/src/components/toolbar/buttons/transcript-panel-button.tsx(1 hunks)apps/desktop/src/locales/en/messages.po(1 hunks)apps/desktop/src/locales/ko/messages.po(1 hunks)apps/desktop/src/routes/app.tsx(3 hunks)packages/tiptap/src/shared/utils.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,ts,tsx,rs}
⚙️ CodeRabbit Configuration File
**/*.{js,ts,tsx,rs}: 1. No error handling.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".
Files:
apps/desktop/src/components/toolbar/buttons/transcript-panel-button.tsxapps/desktop/src/routes/app.tsxapps/desktop/src/components/right-panel/components/chat/chat-input.tsxpackages/tiptap/src/shared/utils.tsapps/desktop/src/components/editor-area/index.tsx
⏰ 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). (3)
- GitHub Check: cubic · AI code reviewer
- GitHub Check: ci (macos, macos-latest)
- GitHub Check: ci (windows, windows-latest)
🔇 Additional comments (10)
apps/desktop/src/components/toolbar/buttons/transcript-panel-button.tsx (1)
36-36: Fixes typo in tooltip copy — LGTMCopy reads correctly as “Toggle transcript panel.” No other behavior changes.
apps/desktop/src/components/editor-area/index.tsx (2)
67-67: Properly closes the conditional block — LGTMResolves the missing brace in the title update path.
69-99: Guarding auto-tagging withgetStateprevents runtime errors — LGTMThe additional guard avoids calling into an uninitialized session store.
packages/tiptap/src/shared/utils.ts (2)
20-27: Adds UL taskList passthrough rule — LGTMPassing through the list wrapper and delegating item formatting to the LI rule is appropriate.
29-46: Obsidian-style task item Markdown rendering — LGTMThe LI rule correctly emits “- [ ] …” / “- [x] …” and strips pre-existing checkbox notation. Good interaction with the existing “p” rule.
apps/desktop/src/components/right-panel/components/chat/chat-input.tsx (1)
295-295: Max height bump to 90px — LGTMMinor UX improvement; no side effects.
apps/desktop/src/routes/app.tsx (2)
6-6: Importing useRef — LGTMNeeded for the new responsive manager.
154-154: Injecting ResponsivePanelsManager into the tree — LGTMRight placement (within providers, outside layout content) and returns null.
apps/desktop/src/locales/en/messages.po (2)
1548-1554: Tooltip key spacing/style fixed — LGTM"Toggle transcript panel" now matches sentence case and spacing used by other toggles (e.g., "Toggle chat panel"). Obsolete keys retained correctly.
1548-1554: No remaining references to "Toggle transcriptpanel" — resolving.Searched the repo (excluding locales and node_modules) with exact, regex, and case-insensitive ripgrep queries; no occurrences of the old msgid were found. Only code references are component filenames/imports (expected):
- apps/desktop/src/components/toolbar/buttons/transcript-panel-button.tsx
- apps/desktop/src/components/toolbar/bars/main-toolbar.tsx
locales/en/messages.po contains the updated entry (msgid "Toggle transcript panel") and the old key is commented out.
| useEffect(() => { | ||
| const editor = editorRef.current?.editor; | ||
| if (editor) { | ||
| // override TipTap's Enter behavior completely | ||
| editor.setOptions({ | ||
| editorProps: { | ||
| ...editor.options.editorProps, | ||
| handleKeyDown: (view, event) => { | ||
| if (event.key === "Enter" && !event.shiftKey) { | ||
| const isEmpty = view.state.doc.textContent.trim() === ""; | ||
| if (isEmpty) { | ||
| return true; | ||
| } | ||
| if (inputValue.trim()) { | ||
| event.preventDefault(); | ||
| handleSubmit(); | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| }, | ||
| }, | ||
| }); | ||
| } | ||
| }, [editorRef.current?.editor, inputValue, handleSubmit]); | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Enter is handled twice (ProseMirror handler + DOM listener) — risk of double submission
You now override TipTap’s handleKeyDown and still attach a DOM keydown listener below. Both intercept Enter and call handleSubmit, causing duplicate sends. Also, the PM handler doesn’t stop propagation; and the effect resets editor options on every keystroke via inputValue dependency.
- Fix: stop propagation in the PM handler and make the DOM handler ignore defaultPrevented.
- Optional: avoid resetting editor options on every input change by reading inputValue from a ref.
Apply this diff to the PM handler to stop propagation:
if (isEmpty) {
- return true;
+ event.preventDefault();
+ event.stopPropagation();
+ return true;
}
if (inputValue.trim()) {
event.preventDefault();
+ event.stopPropagation();
handleSubmit();
return true;
}And update the DOM keydown handler to skip when already handled (see the next comment’s diff).
Optional (outside the selected lines): use a ref to avoid re-calling setOptions on every inputValue change.
// outside: before effects
const inputValueRef = useRef(inputValue);
useEffect(() => { inputValueRef.current = inputValue; }, [inputValue]);
// inside PM handler, replace inputValue.trim() with:
if (inputValueRef.current.trim()) { ... }
// and make the setOptions effect depend only on editorRef.current?.editor🤖 Prompt for AI Agents
In apps/desktop/src/components/right-panel/components/chat/chat-input.tsx around
lines 206-231, the ProseMirror (TipTap) handleKeyDown currently triggers
handleSubmit but doesn't stop propagation and the effect re-applies editor
options on every input change; update the PM handler to call
event.preventDefault(); event.stopPropagation(); and return true when handling
Enter so it won't bubble, replace direct inputValue usage with a ref (e.g.,
inputValueRef.current) so setOptions doesn't need to run on every keystroke, and
change the useEffect dependency to only depend on editorRef.current?.editor;
additionally ensure the separate DOM keydown listener (elsewhere) checks
event.defaultPrevented and skips if true so submissions aren't duplicated.
There was a problem hiding this comment.
cubic analysis
6 issues found across 7 files • Review in cubic
React with 👍 or 👎 to teach cubic. You can also tag @cubic-dev-ai to give feedback, ask questions, or re-run the review.
| } | ||
|
|
||
| if (event.key === "Enter" && !event.shiftKey) { | ||
| console.log("Enter pressed, inputValue:", inputValue); |
There was a problem hiding this comment.
Replace console.log with the logging framework or remove it to avoid leaking user input and noisy logs.
(This reflects your team's feedback about avoiding console statements in production code.)
Prompt for AI agents
Address the following comment on apps/desktop/src/components/right-panel/components/chat/chat-input.tsx at line 244:
<comment>Replace console.log with the logging framework or remove it to avoid leaking user input and noisy logs.
(This reflects your team's feedback about avoiding console statements in production code.)</comment>
<file context>
@@ -215,6 +241,7 @@ export function ChatInput(
}
if (event.key === "Enter" && !event.shiftKey) {
+ console.log("Enter pressed, inputValue:", inputValue);
event.preventDefault();
</file context>
| console.log("Enter pressed, inputValue:", inputValue); | |
| // Enter pressed; removed console.log in production |
| } | ||
|
|
||
| if (event.key === "Enter" && !event.shiftKey) { | ||
| console.log("Enter pressed, inputValue:", inputValue); |
There was a problem hiding this comment.
The chat-input.tsx file exhibits redundant and potentially confusing event handling for the 'Enter' key. One useEffect block directly sets editorProps.handleKeyDown to override behavior, while another useEffect block uses editor.on("keydown"). The handleKeyDown property in ProseMirror (which TipTap uses) typically executes before general event listeners. This means the newly added handleKeyDown might prevent the older editor.on("keydown") listener from firing, leading to ambiguous control flow and making it difficult to understand which logic will be executed. This violates the principle of clear and singular responsibility for event handling.
Prompt for AI agents
Address the following comment on apps/desktop/src/components/right-panel/components/chat/chat-input.tsx at line 244:
<comment>The `chat-input.tsx` file exhibits redundant and potentially confusing event handling for the 'Enter' key. One `useEffect` block directly sets `editorProps.handleKeyDown` to override behavior, while another `useEffect` block uses `editor.on("keydown")`. The `handleKeyDown` property in ProseMirror (which TipTap uses) typically executes before general event listeners. This means the newly added `handleKeyDown` might prevent the older `editor.on("keydown")` listener from firing, leading to ambiguous control flow and making it difficult to understand which logic will be executed. This violates the principle of clear and singular responsibility for event handling.</comment>
<file context>
@@ -215,6 +241,7 @@ export function ChatInput(
}
if (event.key === "Enter" && !event.shiftKey) {
+ console.log("Enter pressed, inputValue:", inputValue);
event.preventDefault();
</file context>
| const editor = editorRef.current?.editor; | ||
| if (editor) { | ||
| // override TipTap's Enter behavior completely | ||
| editor.setOptions({ |
There was a problem hiding this comment.
Directly overriding a third-party library's core behavior (TipTap editor's handleKeyDown via editorProps) can lead to brittle and unmaintainable code. This approach tightly couples the component to TipTap's internal implementation details, making future upgrades and bug fixes challenging. It circumvents TipTap's intended extension mechanisms and can introduce unexpected side effects or breakages when the library updates. A more robust solution would be to use TipTap's official extension API or event listeners, if available, for custom key handling.
Prompt for AI agents
Address the following comment on apps/desktop/src/components/right-panel/components/chat/chat-input.tsx at line 210:
<comment>Directly overriding a third-party library's core behavior (`TipTap` editor's `handleKeyDown` via `editorProps`) can lead to brittle and unmaintainable code. This approach tightly couples the component to `TipTap`'s internal implementation details, making future upgrades and bug fixes challenging. It circumvents `TipTap`'s intended extension mechanisms and can introduce unexpected side effects or breakages when the library updates. A more robust solution would be to use TipTap's official extension API or event listeners, if available, for custom key handling.</comment>
<file context>
@@ -203,6 +203,32 @@ export function ChatInput(
}
}, [chatInputRef]);
+ useEffect(() => {
+ const editor = editorRef.current?.editor;
+ if (editor) {
+ // override TipTap's Enter behavior completely
+ editor.setOptions({
+ editorProps: {
</file context>
packages/tiptap/src/shared/utils.ts
Outdated
| const isChecked = checkbox ? checkbox.checked : false; | ||
| const checkboxSymbol = isChecked ? "[x]" : "[ ]"; | ||
|
|
||
| const cleanContent = content.replace(/^\s*\[[\sx]\]\s*/, "").trim(); |
There was a problem hiding this comment.
Regex only removes lowercase [x]. Include uppercase X to avoid duplicate checkbox markers when content starts with [X].
Prompt for AI agents
Address the following comment on packages/tiptap/src/shared/utils.ts at line 42:
<comment>Regex only removes lowercase [x]. Include uppercase X to avoid duplicate checkbox markers when content starts with [X].</comment>
<file context>
@@ -17,6 +17,34 @@ turndown.addRule("p", {
},
});
+turndown.addRule("taskList", {
+ filter: function(node) {
+ return node.nodeName === "UL" && node.getAttribute("data-type") === "taskList";
+ },
+ replacement: function(content) {
+ return content;
</file context>
| const cleanContent = content.replace(/^\s*\[[\sx]\]\s*/, "").trim(); | |
| const cleanContent = content.replace(/^\s*\[[\sxX]\]\s*/, "").trim(); |
| }, | ||
| }); | ||
| } | ||
| }, [editorRef.current?.editor, inputValue, handleSubmit]); |
There was a problem hiding this comment.
Avoid re-applying editor.setOptions on every keystroke; remove inputValue from the effect dependencies or use a ref to access the latest value inside the handler
Prompt for AI agents
Address the following comment on apps/desktop/src/components/right-panel/components/chat/chat-input.tsx at line 230:
<comment>Avoid re-applying editor.setOptions on every keystroke; remove inputValue from the effect dependencies or use a ref to access the latest value inside the handler</comment>
<file context>
@@ -203,6 +203,32 @@ export function ChatInput(
}
}, [chatInputRef]);
+ useEffect(() => {
+ const editor = editorRef.current?.editor;
+ if (editor) {
+ // override TipTap's Enter behavior completely
+ editor.setOptions({
+ editorProps: {
</file context>
| } | ||
| if (inputValue.trim()) { | ||
| event.preventDefault(); | ||
| handleSubmit(); |
There was a problem hiding this comment.
Stop propagation in the TipTap handleKeyDown handler before submitting to avoid duplicate Enter handling with the DOM keydown listener (which also triggers submit)
Prompt for AI agents
Address the following comment on apps/desktop/src/components/right-panel/components/chat/chat-input.tsx at line 221:
<comment>Stop propagation in the TipTap handleKeyDown handler before submitting to avoid duplicate Enter handling with the DOM keydown listener (which also triggers submit)</comment>
<file context>
@@ -203,6 +203,32 @@ export function ChatInput(
}
}, [chatInputRef]);
+ useEffect(() => {
+ const editor = editorRef.current?.editor;
+ if (editor) {
+ // override TipTap's Enter behavior completely
+ editor.setOptions({
+ editorProps: {
</file context>
| handleSubmit(); | |
| event.stopPropagation(); handleSubmit(); |
Summary by cubic
Improved chat input behavior, added Obsidian-style task markdown export, and auto-collapsed side panels when the app window is small.