Skip to content

Conversation

@CH1111
Copy link
Contributor

@CH1111 CH1111 commented Dec 18, 2025

Summary by CodeRabbit

  • New Features

    • Multi-image batch upload support
    • Copy/paste now includes memo nodes
  • Improvements

    • Unified upload notifications with spinner, status icons, and single persistent lifecycle; simplified translations
    • Memo defaults updated (background color) and editor focus behavior refined
    • Hover and z‑index behavior simplified for more predictable layering
  • UI

    • Slight front-page settings position adjustment
    • Success toast consolidated to "all uploaded" messaging

✏️ Tip: You can customize this high-level summary in your review settings.

- Changed image upload function from `handleUploadImage` to `handleUploadMultipleImages` for batch processing.
- Improved notification system by utilizing Ant Design's message component for better user feedback during uploads.
- Updated translation strings for clarity and consistency in both English and Chinese.
- Ensured compliance with coding standards, including optional chaining and nullish coalescing for safer property access.
- Simplified position retrieval in MemoNode by directly accessing event?.dragCreateInfo?.position.
- Updated background color default in MemoNode metadata for better visual consistency.
- Enhanced copy-paste functionality to include 'memo' nodes alongside 'skillResponse' nodes.
- Implemented node duplication logic for 'memo' nodes using event emitters for better event handling.
- Ensured compliance with coding standards, including optional chaining and nullish coalescing for safer property access.
@coderabbitai
Copy link

coderabbitai bot commented Dec 18, 2025

Walkthrough

Refactors single-image upload to batch uploads; updates drag-drop to process returned driveFiles; replaces per-update notifications with a singleton message lifecycle and simplified i18n; extends copy/paste to include memo nodes and emits duplication events; simplifies node hover/z-index logic and adjusts memo focus/bgColor and front-page positioning.

Changes

Cohort / File(s) Summary
Multi-file upload refactor
packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
Replaced per-file upload with batch API: useUploadImage now exposes handleUploadMultipleImages; drag-drop handles returned driveFiles array, skips entries without fileId, maps to context items, and updated callback deps.
Upload notification migration
packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
Replaced Ant Design notification with singleton message (dedicated key); added Spin and new icons; simplified status computation and i18n usage; ensured persistent lifecycle cleanup on unmount/clear.
Copy–paste node behavior
packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
Extended copy/paste to include memo nodes; memo paste emits a duplication event via nodeActionEmitter (Y offset +300); skillResponse still duplicates via duplicateNode; added guards for missing originals and updated deps.
Memo node creation & focus handling
packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
Read position from event.dragCreateInfo.position (removed getConnectionInfo), pass empty connectTo for new inserts/duplicates, changed default metadata.bgColor to #FEF2CF, and moved editor onClick focus handler to the inner wrapper.
Import resource upload message change
packages/ai-workspace-common/src/components/import-resource/index.tsx
Use unified upload success translation t('common.upload.notification.allUploaded') instead of t('common.putSuccess') after batchCreateDriveFiles.
i18n: upload notification simplification
packages/i18n/src/en-US/ui.ts, packages/i18n/src/zh-Hans/ui.ts
Removed granular keys (progress, complete, failed, partialSuccess); added partialSuccessDesc; simplified uploading string to generic "Uploading files" and adjusted Chinese equivalents.
Node hover / z-index simplification
packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx, packages/ai-workspace-common/src/hooks/canvas/use-node-hover.ts, packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
Hover handlers now pass selected flag; z-index logic simplified to single-target updates (1001 hovered, 1000 selected, else 1/0); removed group/edge propagation and complex multi-path logic.
Front page layout tweak
packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
Adjusted Settings area offset from right-[1px]/top-4 to right-5/top-5.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas needing extra attention:
    • configure-tab.tsx: batch upload error handling, null checks, and mapping of driveFile.fileId/name.
    • use-copy-paste-skill-response-node.ts: correctness of nodeActionEmitter usage and paste vs duplicate branching.
    • upload-notification/index.tsx: singleton message lifecycle, cleanup timing, and translation key changes.
    • use-selected-node-zIndex.tsx / use-node-hover.ts: ensure removed group/edge handling doesn't regress stacking behavior.

Possibly related PRs

Suggested reviewers

  • mrcfps

Poem

🐰 I swapped one file for many, quick and bright,
I nudged memos down and warmed their light,
Messages now hum as one through the night,
Hover and focus find simpler ways to play,
A little rabbit hops and celebrates today 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title mentions multi-image batch upload and copy-pasting for memos, but the actual changes include significant modifications to upload notifications, z-index handling, hover effects, and UI positioning that are not reflected in the title. Update the title to reflect the broader scope: consider 'refactor: simplify upload notifications and optimize node z-index/hover handling' or similar to accurately represent all substantial changes in the changeset.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/file-upload-notify-style

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

- Changed the success notification message for uploads to provide clearer user feedback.
- Ensured compliance with coding standards, including proper string literal usage.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx (1)

351-380: Stale dependency: getConnectionInfo is no longer used in handleDuplicate.

The handleDuplicate function no longer calls getConnectionInfo, but it's still included in the dependency array on line 379. This creates a stale dependency that could cause unnecessary re-renders.

Additionally, passing an empty array [] for connectTo removes the automatic node connection behavior. Please verify this is the intended behavior.

🔎 Remove unused dependency:
   },
-    [data, addNode, editor, t, getConnectionInfo],
+    [data, addNode, editor, t],
   );
packages/ai-workspace-common/src/components/common/upload-notification/index.tsx (1)

2-30: Singleton upload message flow is correct; consider minor safety & clarity tweaks

The switch to a keyed, singleton antMessage with unmount cleanup and upload-based destroy looks correct and should prevent orphaned notifications. A few small follow-ups:

  1. Apply optional chaining when accessing upload status (per guidelines)
    To guard against any unexpected null/undefined entries in uploads and align with the “always use optional chaining” rule, you can make the filters a bit more defensive:
Diff: use optional chaining in filters
-      const successCount = safeUploads.filter((upload) => upload.status === 'success').length;
-      const errorCount = safeUploads.filter((upload) => upload.status === 'error').length;
+      const successCount = safeUploads.filter((upload) => upload?.status === 'success').length;
+      const errorCount = safeUploads.filter((upload) => upload?.status === 'error').length;
  1. Confirm intended display duration vs early destroy
    Right now, success/warning/error messages are configured with duration = 3/5, but clearUploads() runs after 1s, which immediately triggers antMessage.destroy(UPLOAD_NOTIFICATION_MESSAGE_KEY) when uploads becomes empty. This means users will typically see the final state for ~1s, not the full 3–5s. If the intent is to keep the message visible longer, consider either:

    • Delaying clearUploads() to match duration, or
    • Keeping clearUploads() at 1s but removing the unconditional destroy when safeUploads.length === 0.
  2. Optional: remove unused className from effect deps
    className is included in the useEffect dependency array but not read inside the effect. Unless you plan to use it for message styling, you could safely drop it from the deps to avoid unnecessary re-runs and reduce confusion.

Diff: trim effect dependencies
-  }, [uploads, isUploading, completedFiles, totalFiles, t, clearUploads, className]);
+  }, [uploads, isUploading, completedFiles, totalFiles, t, clearUploads]);

Also applies to: 34-115

packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx (1)

77-85: Add defensive null check for driveFile.name.

While driveFile.fileId is validated on line 78, driveFile.name is used on line 84 without a null check. For defensive programming, consider validating both properties before creating context items.

🔎 Apply this diff to add defensive validation:
 const driveFiles = await handleUploadMultipleImages(files, canvasId ?? '');
 for (const driveFile of driveFiles ?? []) {
-  if (!driveFile.fileId) {
+  if (!driveFile.fileId || !driveFile.name) {
     continue;
   }
   newContextItems.push({
     type: 'file',
     entityId: driveFile.fileId,
     title: driveFile.name,
   });
 }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e68a790 and 5bf632a.

📒 Files selected for processing (6)
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx (2 hunks)
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx (3 hunks)
  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx (3 hunks)
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts (3 hunks)
  • packages/i18n/src/en-US/ui.ts (1 hunks)
  • packages/i18n/src/zh-Hans/ui.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (23)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{js,ts,jsx,tsx}: Always use optional chaining (?.) when accessing object properties
Always use nullish coalescing (??) or default values for potentially undefined values
Always check array existence before using array methods
Always validate object properties before destructuring
Always use single quotes for string literals in JavaScript/TypeScript code

**/*.{js,ts,jsx,tsx}: Use semicolons at the end of statements
Include spaces around operators (e.g., a + b instead of a+b)
Always use curly braces for control statements
Place opening braces on the same line as their statement

**/*.{js,ts,jsx,tsx}: Group import statements in order: React/framework libraries, third-party libraries, internal modules, relative path imports, type imports, style imports
Sort imports alphabetically within each import group
Leave a blank line between import groups
Extract complex logic into custom hooks
Use functional updates for state (e.g., setCount(prev => prev + 1))
Split complex state into multiple state variables rather than single large objects
Use useReducer for complex state logic instead of multiple useState calls

Files:

  • packages/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
  • packages/i18n/src/en-US/ui.ts
**/*.{js,ts,tsx,jsx,py,java,cpp,c,cs,rb,go,rs,php,swift,kt,scala,r,m,mm,sql}

📄 CodeRabbit inference engine (.cursor/rules/00-language-priority.mdc)

**/*.{js,ts,tsx,jsx,py,java,cpp,c,cs,rb,go,rs,php,swift,kt,scala,r,m,mm,sql}: All code comments MUST be written in English
All variable names, function names, class names, and other identifiers MUST use English words
Comments should be concise and explain 'why' rather than 'what'
Use proper grammar and punctuation in comments
Keep comments up-to-date when code changes
Document complex logic, edge cases, and important implementation details
Use clear, descriptive names that indicate purpose
Avoid abbreviations unless they are universally understood

Files:

  • packages/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
  • packages/i18n/src/en-US/ui.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/00-language-priority.mdc)

Use JSDoc style comments for functions and classes in JavaScript/TypeScript

Files:

  • packages/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
  • packages/i18n/src/en-US/ui.ts
**/{i18n,locales,translations,lang}/**/*.{json,ts,tsx,js,jsx,properties}

📄 CodeRabbit inference engine (.cursor/rules/00-language-priority.mdc)

Use Chinese for all user-facing communication

Files:

  • packages/i18n/src/zh-Hans/ui.ts
  • packages/i18n/src/en-US/ui.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/01-code-style.mdc)

**/*.{js,jsx,ts,tsx}: Use single quotes for string literals in TypeScript/JavaScript
Always use optional chaining (?.) when accessing object properties in TypeScript/JavaScript
Always use nullish coalescing (??) or default values for potentially undefined values in TypeScript/JavaScript
Always check array existence before using array methods in TypeScript/JavaScript
Validate object properties before destructuring in TypeScript/JavaScript
Use ES6+ features like arrow functions, destructuring, and spread operators in TypeScript/JavaScript
Avoid magic numbers and strings - use named constants in TypeScript/JavaScript
Use async/await instead of raw promises for asynchronous code in TypeScript/JavaScript

Files:

  • packages/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
  • packages/i18n/src/en-US/ui.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/03-typescript-guidelines.mdc)

**/*.{ts,tsx}: Avoid using any type whenever possible - use unknown type instead with proper type guards
Always define explicit return types for functions, especially for public APIs
Prefer extending existing types over creating entirely new types
Use TypeScript utility types (Partial<T>, Pick<T, K>, Omit<T, K>, Readonly<T>, Record<K, T>) to derive new types
Use union types and intersection types to combine existing types
Always import types explicitly using the import type syntax
Group type imports separately from value imports
Minimize creating local type aliases for imported types

Files:

  • packages/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
  • packages/i18n/src/en-US/ui.ts
**/*.{js,ts,jsx,tsx,css,json}

📄 CodeRabbit inference engine (.cursor/rules/04-code-formatting.mdc)

Maximum line length of 100 characters

Files:

  • packages/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
  • packages/i18n/src/en-US/ui.ts
**/*.{js,ts,jsx,tsx,css,json,yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/04-code-formatting.mdc)

Use 2 spaces for indentation, no tabs

Files:

  • packages/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
  • packages/i18n/src/en-US/ui.ts
**/*.{js,ts,jsx,tsx,css,json,yml,yaml,md}

📄 CodeRabbit inference engine (.cursor/rules/04-code-formatting.mdc)

No trailing whitespace at the end of lines

Files:

  • packages/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
  • packages/i18n/src/en-US/ui.ts
**/*.{css,scss,sass,less,js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/09-design-system.mdc)

**/*.{css,scss,sass,less,js,jsx,ts,tsx}: Primary color (#155EEF) should be used for main brand color in buttons, links, and accents
Error color (#F04438) should be used for error states and destructive actions
Success color (#12B76A) should be used for success states and confirmations
Warning color (#F79009) should be used for warnings and important notifications
Info color (#0BA5EC) should be used for informational elements

Files:

  • packages/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
  • packages/i18n/src/en-US/ui.ts
packages/i18n/src/{en-US,zh-Hans}/**

📄 CodeRabbit inference engine (.cursor/rules/09-i18n-guidelines.mdc)

Add new translation keys to both language files (en-US and zh-Hans)

Files:

  • packages/i18n/src/zh-Hans/ui.ts
  • packages/i18n/src/en-US/ui.ts
packages/i18n/src/**

📄 CodeRabbit inference engine (.cursor/rules/09-i18n-guidelines.mdc)

packages/i18n/src/**: Maintain consistency in translation key naming conventions
Use descriptive translation keys that reflect the content
Group related translation keys together in the translation file structure
Use namespaces for different sections of the application in translation keys
Follow a hierarchical structure for nested components in translation key organization

Files:

  • packages/i18n/src/zh-Hans/ui.ts
  • packages/i18n/src/en-US/ui.ts
**/*.{tsx,ts}

📄 CodeRabbit inference engine (.cursor/rules/09-i18n-guidelines.mdc)

**/*.{tsx,ts}: Use the translation wrapper component and useTranslation hook in components
Ensure all user-facing text is translatable

Files:

  • packages/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
  • packages/i18n/src/en-US/ui.ts
**/*.{tsx,ts,json}

📄 CodeRabbit inference engine (.cursor/rules/09-i18n-guidelines.mdc)

Support dynamic content with placeholders in translations

Files:

  • packages/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
  • packages/i18n/src/en-US/ui.ts
**/*.{tsx,ts,jsx,js,vue,css,scss,less}

📄 CodeRabbit inference engine (.cursor/rules/11-ui-design-patterns.mdc)

**/*.{tsx,ts,jsx,js,vue,css,scss,less}: Use the primary blue (#155EEF) for main UI elements, CTAs, and active states
Use red (#F04438) only for errors, warnings, and destructive actions
Use green (#12B76A) for success states and confirmations
Use orange (#F79009) for warning states and important notifications
Use blue (#0BA5EC) for informational elements
Primary buttons should be solid with the primary color
Secondary buttons should have a border with transparent or light background
Danger buttons should use the error color
Use consistent padding, border radius, and hover states for all buttons
Follow fixed button sizes based on their importance and context
Use consistent border radius (rounded-lg) for all cards
Apply light shadows (shadow-sm) for card elevation
Maintain consistent padding inside cards (p-4 or p-6)
Use subtle borders for card separation
Ensure proper spacing between card elements
Apply consistent styling to all form inputs
Use clear visual indicators for focus, hover, and error states in form elements
Apply proper spacing between elements using 8px, 16px, 24px increments
Ensure proper alignment of elements (left, center, or right)
Use responsive layouts that work across different device sizes
Maintain a minimum contrast ratio of 4.5:1 for text

Files:

  • packages/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
  • packages/i18n/src/en-US/ui.ts
**/*.{tsx,ts,jsx,js,vue}

📄 CodeRabbit inference engine (.cursor/rules/11-ui-design-patterns.mdc)

**/*.{tsx,ts,jsx,js,vue}: Include appropriate loading states for async actions in buttons
Group related form elements with appropriate spacing
Provide clear validation feedback for forms
Ensure proper labeling and accessibility for form elements
Ensure all interactive elements are keyboard accessible
Include appropriate ARIA attributes for complex components
Provide alternative text for images and icons
Support screen readers with semantic HTML elements

Files:

  • packages/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
  • packages/i18n/src/en-US/ui.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/08-contributing-guidelines.mdc)

**/*.{ts,tsx,js,jsx}: Follow the TypeScript/JavaScript style guidelines
Ensure code is well-tested and documented

Files:

  • packages/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
  • packages/i18n/src/en-US/ui.ts
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{jsx,tsx}: Always use tailwind css to style the component
Always wrap pure components with React.memo to prevent unnecessary re-renders
Always use useMemo for expensive computations or complex object creation
Always use useCallback for function props to maintain referential equality
Always specify proper dependency arrays in useEffect to prevent infinite loops
Always avoid inline object/array creation in render to prevent unnecessary re-renders
Always use proper key props when rendering lists
Always split nested components with closures into separate components to avoid performance issues and improve code maintainability

**/*.{jsx,tsx}: Always wrap pure components with React.memo to prevent unnecessary re-renders
Always use useMemo for expensive computations or complex object creation in React
Always use useCallback for function props to maintain referential equality in React
Always specify proper dependency arrays in useEffect to prevent infinite loops in React
Always avoid inline object/array creation in render to prevent unnecessary re-renders in React
Always use proper key props when rendering lists in React (avoid using index when possible)
Always split nested components with closures into separate components in React
Use lazy loading for components that are not immediately needed in React
Debounce handlers for events that might fire rapidly (resize, scroll, input) in React
Implement fallback UI for components that might fail in React
Use error boundaries to catch and handle runtime errors in React

**/*.{jsx,tsx}: Place each attribute on a new line when a component has multiple attributes in JSX
Use self-closing tags for elements without children in JSX
Keep JSX expressions simple, extract complex logic to variables
Put closing brackets for multi-line JSX on a new line

**/*.{jsx,tsx}: Component file names should match the component name
Organize function components in order: imports, type definitions, constants, component function, hook calls, e...

Files:

  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{jsx,tsx,css}

📄 CodeRabbit inference engine (.cursor/rules/01-code-style.mdc)

**/*.{jsx,tsx,css}: Use Tailwind CSS for styling components
Follow the utility-first approach with Tailwind CSS
Group related utility classes together in Tailwind CSS
Prefer Tailwind utilities over custom CSS when possible

Files:

  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{jsx,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/05-code-organization.mdc)

Each component file should contain only one main component

Files:

  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/index.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/05-code-organization.mdc)

Use index files to export multiple components from a directory

Files:

  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/05-code-organization.mdc)

Explicitly type props with interfaces or types in React components

Files:

  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/08-contributing-guidelines.mdc)

Use React best practices for frontend code

Files:

  • packages/ai-workspace-common/src/components/common/upload-notification/index.tsx
  • packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
🧠 Learnings (4)
📚 Learning: 2025-11-25T03:04:41.334Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/09-i18n-guidelines.mdc:0-0
Timestamp: 2025-11-25T03:04:41.334Z
Learning: Applies to packages/i18n/src/{en-US,zh-Hans}/** : Add new translation keys to both language files (en-US and zh-Hans)

Applied to files:

  • packages/i18n/src/zh-Hans/ui.ts
  • packages/i18n/src/en-US/ui.ts
📚 Learning: 2025-11-25T03:03:19.158Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/00-language-priority.mdc:0-0
Timestamp: 2025-11-25T03:03:19.158Z
Learning: Applies to **/{i18n,locales,translations,lang}/**/*.{json,ts,tsx,js,jsx,properties} : Use Chinese for all user-facing communication

Applied to files:

  • packages/i18n/src/zh-Hans/ui.ts
📚 Learning: 2025-11-25T03:04:41.334Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/09-i18n-guidelines.mdc:0-0
Timestamp: 2025-11-25T03:04:41.334Z
Learning: Applies to packages/i18n/src/** : Use descriptive translation keys that reflect the content

Applied to files:

  • packages/i18n/src/zh-Hans/ui.ts
📚 Learning: 2025-11-25T03:04:41.334Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/09-i18n-guidelines.mdc:0-0
Timestamp: 2025-11-25T03:04:41.334Z
Learning: Applies to packages/i18n/src/** : Maintain consistency in translation key naming conventions

Applied to files:

  • packages/i18n/src/zh-Hans/ui.ts
🧬 Code graph analysis (2)
packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx (1)
packages/ai-workspace-common/src/hooks/use-upload-image.ts (1)
  • useUploadImage (10-193)
packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts (2)
apps/api/src/modules/tool/sandbox/wrapper/base.ts (1)
  • canvasId (200-202)
packages/ai-workspace-common/src/events/nodeActions.ts (2)
  • nodeActionEmitter (34-34)
  • createNodeEventName (36-37)
⏰ 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: build / Build
🔇 Additional comments (14)
packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx (2)

448-463: LGTM!

The onClick handler placement on the outer wrapper div allows users to click anywhere in the editor area to focus the editor, improving usability. The optional chaining on editor?.commands.focus('end') properly handles the case where the editor might not be initialized.


367-370: LGTM!

The default bgColor value is now consistent with panelColors[0] defined on line 277, ensuring duplicated memo nodes have the same default color as newly created ones.

packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts (4)

10-13: LGTM!

The imports for nodeActionEmitter and createNodeEventName are correctly added to support the new memo node duplication via event emission.


52-54: LGTM!

The copy selection correctly extended to include memo nodes alongside skillResponse nodes.


106-127: Verify: Inconsistent paste offsets between node types.

The paste offset differs between node types:

  • skillResponse: y + 200 (line 106)
  • memo: y + 300 (line 123)

This may be intentional due to different default node heights, but could result in inconsistent user experience. Please verify this is the intended behavior.


109-113: LGTM!

Good defensive coding — the guard prevents potential runtime errors when a copied node ID no longer exists on the canvas (e.g., if the original was deleted after copying).

packages/i18n/src/zh-Hans/ui.ts (1)

438-441: Upload notification translations match new summary behavior

The updated Chinese strings for uploading, partialSuccessDesc, and allFailed correctly reflect the new batch upload summary and use the same {{success}} / {{error}} placeholders as the component logic and en-US locale. Looks good.

packages/i18n/src/en-US/ui.ts (1)

106-109: English upload notification strings are consistent and placeholder-safe

The simplified “Uploading files” label and new partialSuccessDesc correctly match the zh-Hans locale and the component’s use of {{success}} / {{error}}. No issues from an i18n standpoint.

packages/ai-workspace-common/src/components/canvas/node-preview/skill-response/configure-tab.tsx (6)

1-13: LGTM!

Imports are well-organized following the coding guidelines: React/framework libraries first, then third-party libraries, followed by internal modules. The hook import on line 10 correctly references useUploadImage which now provides handleUploadMultipleImages for batch processing.


15-23: LGTM!

Interface is well-defined with explicit types. All props are properly typed following TypeScript best practices.


35-35: LGTM!

The change from handleUploadImage to handleUploadMultipleImages correctly aligns with the batch upload refactoring. This enables efficient processing of multiple files simultaneously rather than handling them one by one.


92-92: LGTM!

The dependency array correctly includes all external values used within the callback (canvasId, handleUploadMultipleImages, setContextItems), following React best practices for useCallback.


95-116: LGTM!

Drag event handlers are properly implemented with correct event handling (preventDefault, stopPropagation) and drag counter logic to handle nested drag events. All callbacks correctly use useCallback with appropriate dependency arrays.


118-219: LGTM!

The component structure follows React best practices:

  • Properly wrapped with React.memo to prevent unnecessary re-renders
  • Uses Tailwind CSS for styling as per guidelines
  • Implements proper conditional rendering for readonly mode
  • Provides good UX with the drag-and-drop overlay
  • Display name is set correctly for debugging

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/ai-workspace-common/src/components/import-resource/index.tsx (1)

95-117: Remove unused metadata creation loop.

The loop filters media files and creates metadata objects, but the metadata variable is never used after being created. This dead code should either be completed if part of an unfinished feature or removed to improve code clarity and avoid unnecessary processing.

🔎 Consider removing the unused code:
-      const mediaFiles = waitingList.filter(
-        (item) =>
-          item.file?.type === 'image' || item.file?.type === 'video' || item.file?.type === 'audio',
-      );
-      for (const item of mediaFiles) {
-        // Create metadata based on file type
-        const metadata: Record<string, any> = {
-          storageKey: item.file?.storageKey,
-        };
-
-        // Set the appropriate URL field based on file type
-        switch (item.file?.type) {
-          case 'image':
-            metadata.imageUrl = item.file?.url;
-            break;
-          case 'video':
-            metadata.videoUrl = item.file?.url;
-            break;
-          case 'audio':
-            metadata.audioUrl = item.file?.url;
-            break;
-        }
-      }
-

If this is part of an unfinished feature, would you like me to help complete the implementation or open an issue to track this?

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5bf632a and 31c959b.

📒 Files selected for processing (1)
  • packages/ai-workspace-common/src/components/import-resource/index.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (20)
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{jsx,tsx}: Always use tailwind css to style the component
Always wrap pure components with React.memo to prevent unnecessary re-renders
Always use useMemo for expensive computations or complex object creation
Always use useCallback for function props to maintain referential equality
Always specify proper dependency arrays in useEffect to prevent infinite loops
Always avoid inline object/array creation in render to prevent unnecessary re-renders
Always use proper key props when rendering lists
Always split nested components with closures into separate components to avoid performance issues and improve code maintainability

**/*.{jsx,tsx}: Always wrap pure components with React.memo to prevent unnecessary re-renders
Always use useMemo for expensive computations or complex object creation in React
Always use useCallback for function props to maintain referential equality in React
Always specify proper dependency arrays in useEffect to prevent infinite loops in React
Always avoid inline object/array creation in render to prevent unnecessary re-renders in React
Always use proper key props when rendering lists in React (avoid using index when possible)
Always split nested components with closures into separate components in React
Use lazy loading for components that are not immediately needed in React
Debounce handlers for events that might fire rapidly (resize, scroll, input) in React
Implement fallback UI for components that might fail in React
Use error boundaries to catch and handle runtime errors in React

**/*.{jsx,tsx}: Place each attribute on a new line when a component has multiple attributes in JSX
Use self-closing tags for elements without children in JSX
Keep JSX expressions simple, extract complex logic to variables
Put closing brackets for multi-line JSX on a new line

**/*.{jsx,tsx}: Component file names should match the component name
Organize function components in order: imports, type definitions, constants, component function, hook calls, e...

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{js,ts,jsx,tsx}: Always use optional chaining (?.) when accessing object properties
Always use nullish coalescing (??) or default values for potentially undefined values
Always check array existence before using array methods
Always validate object properties before destructuring
Always use single quotes for string literals in JavaScript/TypeScript code

**/*.{js,ts,jsx,tsx}: Use semicolons at the end of statements
Include spaces around operators (e.g., a + b instead of a+b)
Always use curly braces for control statements
Place opening braces on the same line as their statement

**/*.{js,ts,jsx,tsx}: Group import statements in order: React/framework libraries, third-party libraries, internal modules, relative path imports, type imports, style imports
Sort imports alphabetically within each import group
Leave a blank line between import groups
Extract complex logic into custom hooks
Use functional updates for state (e.g., setCount(prev => prev + 1))
Split complex state into multiple state variables rather than single large objects
Use useReducer for complex state logic instead of multiple useState calls

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/*.{js,ts,tsx,jsx,py,java,cpp,c,cs,rb,go,rs,php,swift,kt,scala,r,m,mm,sql}

📄 CodeRabbit inference engine (.cursor/rules/00-language-priority.mdc)

**/*.{js,ts,tsx,jsx,py,java,cpp,c,cs,rb,go,rs,php,swift,kt,scala,r,m,mm,sql}: All code comments MUST be written in English
All variable names, function names, class names, and other identifiers MUST use English words
Comments should be concise and explain 'why' rather than 'what'
Use proper grammar and punctuation in comments
Keep comments up-to-date when code changes
Document complex logic, edge cases, and important implementation details
Use clear, descriptive names that indicate purpose
Avoid abbreviations unless they are universally understood

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/00-language-priority.mdc)

Use JSDoc style comments for functions and classes in JavaScript/TypeScript

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/01-code-style.mdc)

**/*.{js,jsx,ts,tsx}: Use single quotes for string literals in TypeScript/JavaScript
Always use optional chaining (?.) when accessing object properties in TypeScript/JavaScript
Always use nullish coalescing (??) or default values for potentially undefined values in TypeScript/JavaScript
Always check array existence before using array methods in TypeScript/JavaScript
Validate object properties before destructuring in TypeScript/JavaScript
Use ES6+ features like arrow functions, destructuring, and spread operators in TypeScript/JavaScript
Avoid magic numbers and strings - use named constants in TypeScript/JavaScript
Use async/await instead of raw promises for asynchronous code in TypeScript/JavaScript

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/*.{jsx,tsx,css}

📄 CodeRabbit inference engine (.cursor/rules/01-code-style.mdc)

**/*.{jsx,tsx,css}: Use Tailwind CSS for styling components
Follow the utility-first approach with Tailwind CSS
Group related utility classes together in Tailwind CSS
Prefer Tailwind utilities over custom CSS when possible

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/03-typescript-guidelines.mdc)

**/*.{ts,tsx}: Avoid using any type whenever possible - use unknown type instead with proper type guards
Always define explicit return types for functions, especially for public APIs
Prefer extending existing types over creating entirely new types
Use TypeScript utility types (Partial<T>, Pick<T, K>, Omit<T, K>, Readonly<T>, Record<K, T>) to derive new types
Use union types and intersection types to combine existing types
Always import types explicitly using the import type syntax
Group type imports separately from value imports
Minimize creating local type aliases for imported types

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/*.{js,ts,jsx,tsx,css,json}

📄 CodeRabbit inference engine (.cursor/rules/04-code-formatting.mdc)

Maximum line length of 100 characters

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/*.{js,ts,jsx,tsx,css,json,yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/04-code-formatting.mdc)

Use 2 spaces for indentation, no tabs

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/*.{js,ts,jsx,tsx,css,json,yml,yaml,md}

📄 CodeRabbit inference engine (.cursor/rules/04-code-formatting.mdc)

No trailing whitespace at the end of lines

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/*.{jsx,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/05-code-organization.mdc)

Each component file should contain only one main component

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/index.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/05-code-organization.mdc)

Use index files to export multiple components from a directory

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/05-code-organization.mdc)

Explicitly type props with interfaces or types in React components

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/*.{css,scss,sass,less,js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/09-design-system.mdc)

**/*.{css,scss,sass,less,js,jsx,ts,tsx}: Primary color (#155EEF) should be used for main brand color in buttons, links, and accents
Error color (#F04438) should be used for error states and destructive actions
Success color (#12B76A) should be used for success states and confirmations
Warning color (#F79009) should be used for warnings and important notifications
Info color (#0BA5EC) should be used for informational elements

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (.cursor/rules/09-i18n-guidelines.mdc)

**/*.{tsx,ts}: Use the translation wrapper component and useTranslation hook in components
Ensure all user-facing text is translatable

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/*.{tsx,ts,json}

📄 CodeRabbit inference engine (.cursor/rules/09-i18n-guidelines.mdc)

Support dynamic content with placeholders in translations

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/*.{tsx,ts,jsx,js,vue,css,scss,less}

📄 CodeRabbit inference engine (.cursor/rules/11-ui-design-patterns.mdc)

**/*.{tsx,ts,jsx,js,vue,css,scss,less}: Use the primary blue (#155EEF) for main UI elements, CTAs, and active states
Use red (#F04438) only for errors, warnings, and destructive actions
Use green (#12B76A) for success states and confirmations
Use orange (#F79009) for warning states and important notifications
Use blue (#0BA5EC) for informational elements
Primary buttons should be solid with the primary color
Secondary buttons should have a border with transparent or light background
Danger buttons should use the error color
Use consistent padding, border radius, and hover states for all buttons
Follow fixed button sizes based on their importance and context
Use consistent border radius (rounded-lg) for all cards
Apply light shadows (shadow-sm) for card elevation
Maintain consistent padding inside cards (p-4 or p-6)
Use subtle borders for card separation
Ensure proper spacing between card elements
Apply consistent styling to all form inputs
Use clear visual indicators for focus, hover, and error states in form elements
Apply proper spacing between elements using 8px, 16px, 24px increments
Ensure proper alignment of elements (left, center, or right)
Use responsive layouts that work across different device sizes
Maintain a minimum contrast ratio of 4.5:1 for text

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/*.{tsx,ts,jsx,js,vue}

📄 CodeRabbit inference engine (.cursor/rules/11-ui-design-patterns.mdc)

**/*.{tsx,ts,jsx,js,vue}: Include appropriate loading states for async actions in buttons
Group related form elements with appropriate spacing
Provide clear validation feedback for forms
Ensure proper labeling and accessibility for form elements
Ensure all interactive elements are keyboard accessible
Include appropriate ARIA attributes for complex components
Provide alternative text for images and icons
Support screen readers with semantic HTML elements

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/08-contributing-guidelines.mdc)

**/*.{ts,tsx,js,jsx}: Follow the TypeScript/JavaScript style guidelines
Ensure code is well-tested and documented

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/08-contributing-guidelines.mdc)

Use React best practices for frontend code

Files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
🧠 Learnings (2)
📚 Learning: 2025-11-25T03:04:41.334Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/09-i18n-guidelines.mdc:0-0
Timestamp: 2025-11-25T03:04:41.334Z
Learning: Applies to **/*.{tsx,ts} : Ensure all user-facing text is translatable

Applied to files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
📚 Learning: 2025-11-25T03:03:19.158Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/00-language-priority.mdc:0-0
Timestamp: 2025-11-25T03:03:19.158Z
Learning: Applies to **/{i18n,locales,translations,lang}/**/*.{json,ts,tsx,js,jsx,properties} : Use Chinese for all user-facing communication

Applied to files:

  • packages/ai-workspace-common/src/components/import-resource/index.tsx
🔇 Additional comments (1)
packages/ai-workspace-common/src/components/import-resource/index.tsx (1)

93-93: LGTM! More descriptive success message key.

The updated i18n key common.upload.notification.allUploaded is more specific and appropriate for batch upload completion than the generic common.putSuccess.

- Updated the right positioning of the settings item from `right-[1px]` to `right-5` for improved layout consistency.
- Ensured compliance with coding standards, including proper use of Tailwind CSS for styling.
- Updated hover event handlers in SkillResponseNode to pass the selected state to onHoverStart and onHoverEnd for improved hover behavior.
- Removed unnecessary use of useSelectedNodeZIndex in MemoNode to streamline component logic.
- Simplified z-index management in useNodeHoverEffect and useSelectedNodeZIndex for better performance and clarity.
- Ensured compliance with coding standards, including proper use of optional chaining and nullish coalescing.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx (1)

126-162: Inconsistent connection handling between handleAskAI and handleDuplicate.

In handleAskAI (lines 130-133), you properly call getConnectionInfo and extract both position and connectTo, then pass connectTo to addNode (line 156).

However, in handleDuplicate (lines 356, 372), you only extract position directly from dragCreateInfo and pass an empty array [] to addNode, bypassing connection logic entirely.

This inconsistency may cause duplicated memo nodes to not be connected to their source nodes as expected.

🔎 Apply this diff to align handleDuplicate with handleAskAI connection logic:
-    const position = event?.dragCreateInfo?.position;
+    const { position, connectTo } = getConnectionInfo(
+      { entityId: data.entityId, type: 'memo' },
+      event?.dragCreateInfo,
+    );
 
     addNode(
       {
         type: 'memo',
         data: {
           title: t('canvas.nodeTypes.memo'),
           contentPreview: content,
           entityId: memoId,
           metadata: {
             bgColor: data?.metadata?.bgColor || '#FEF2CF',
             jsonContent,
           },
         },
         position,
       },
-      [],
+      connectTo,
       false,
       true,
     );
🧹 Nitpick comments (1)
packages/ai-workspace-common/src/hooks/canvas/use-node-hover.ts (1)

7-20: Simplified z-index logic looks good, but remove unused dependency.

The streamlined approach with a single z-index calculation (1001 for hovered, 1000 for selected, 1 otherwise) and the memo node exclusion is clean and maintainable.

However, getNodes is included in the dependency array at line 19 but is never used in the updateNodeAndEdges callback body. This creates unnecessary re-renders when getNodes reference changes.

🔎 Apply this diff to remove the unused dependency:
-  }, [nodeId, setNodes, getNodes]);
+  }, [nodeId, setNodes]);
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a446429 and 64e2ee8.

📒 Files selected for processing (4)
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx (3 hunks)
  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx (1 hunks)
  • packages/ai-workspace-common/src/hooks/canvas/use-node-hover.ts (1 hunks)
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx (1 hunks)
🧰 Additional context used
📓 Path-based instructions (19)
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{jsx,tsx}: Always use tailwind css to style the component
Always wrap pure components with React.memo to prevent unnecessary re-renders
Always use useMemo for expensive computations or complex object creation
Always use useCallback for function props to maintain referential equality
Always specify proper dependency arrays in useEffect to prevent infinite loops
Always avoid inline object/array creation in render to prevent unnecessary re-renders
Always use proper key props when rendering lists
Always split nested components with closures into separate components to avoid performance issues and improve code maintainability

**/*.{jsx,tsx}: Always wrap pure components with React.memo to prevent unnecessary re-renders
Always use useMemo for expensive computations or complex object creation in React
Always use useCallback for function props to maintain referential equality in React
Always specify proper dependency arrays in useEffect to prevent infinite loops in React
Always avoid inline object/array creation in render to prevent unnecessary re-renders in React
Always use proper key props when rendering lists in React (avoid using index when possible)
Always split nested components with closures into separate components in React
Use lazy loading for components that are not immediately needed in React
Debounce handlers for events that might fire rapidly (resize, scroll, input) in React
Implement fallback UI for components that might fail in React
Use error boundaries to catch and handle runtime errors in React

**/*.{jsx,tsx}: Place each attribute on a new line when a component has multiple attributes in JSX
Use self-closing tags for elements without children in JSX
Keep JSX expressions simple, extract complex logic to variables
Put closing brackets for multi-line JSX on a new line

**/*.{jsx,tsx}: Component file names should match the component name
Organize function components in order: imports, type definitions, constants, component function, hook calls, e...

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{js,ts,jsx,tsx}: Always use optional chaining (?.) when accessing object properties
Always use nullish coalescing (??) or default values for potentially undefined values
Always check array existence before using array methods
Always validate object properties before destructuring
Always use single quotes for string literals in JavaScript/TypeScript code

**/*.{js,ts,jsx,tsx}: Use semicolons at the end of statements
Include spaces around operators (e.g., a + b instead of a+b)
Always use curly braces for control statements
Place opening braces on the same line as their statement

**/*.{js,ts,jsx,tsx}: Group import statements in order: React/framework libraries, third-party libraries, internal modules, relative path imports, type imports, style imports
Sort imports alphabetically within each import group
Leave a blank line between import groups
Extract complex logic into custom hooks
Use functional updates for state (e.g., setCount(prev => prev + 1))
Split complex state into multiple state variables rather than single large objects
Use useReducer for complex state logic instead of multiple useState calls

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-node-hover.ts
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{js,ts,tsx,jsx,py,java,cpp,c,cs,rb,go,rs,php,swift,kt,scala,r,m,mm,sql}

📄 CodeRabbit inference engine (.cursor/rules/00-language-priority.mdc)

**/*.{js,ts,tsx,jsx,py,java,cpp,c,cs,rb,go,rs,php,swift,kt,scala,r,m,mm,sql}: All code comments MUST be written in English
All variable names, function names, class names, and other identifiers MUST use English words
Comments should be concise and explain 'why' rather than 'what'
Use proper grammar and punctuation in comments
Keep comments up-to-date when code changes
Document complex logic, edge cases, and important implementation details
Use clear, descriptive names that indicate purpose
Avoid abbreviations unless they are universally understood

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-node-hover.ts
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/00-language-priority.mdc)

Use JSDoc style comments for functions and classes in JavaScript/TypeScript

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-node-hover.ts
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/01-code-style.mdc)

**/*.{js,jsx,ts,tsx}: Use single quotes for string literals in TypeScript/JavaScript
Always use optional chaining (?.) when accessing object properties in TypeScript/JavaScript
Always use nullish coalescing (??) or default values for potentially undefined values in TypeScript/JavaScript
Always check array existence before using array methods in TypeScript/JavaScript
Validate object properties before destructuring in TypeScript/JavaScript
Use ES6+ features like arrow functions, destructuring, and spread operators in TypeScript/JavaScript
Avoid magic numbers and strings - use named constants in TypeScript/JavaScript
Use async/await instead of raw promises for asynchronous code in TypeScript/JavaScript

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-node-hover.ts
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{jsx,tsx,css}

📄 CodeRabbit inference engine (.cursor/rules/01-code-style.mdc)

**/*.{jsx,tsx,css}: Use Tailwind CSS for styling components
Follow the utility-first approach with Tailwind CSS
Group related utility classes together in Tailwind CSS
Prefer Tailwind utilities over custom CSS when possible

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/03-typescript-guidelines.mdc)

**/*.{ts,tsx}: Avoid using any type whenever possible - use unknown type instead with proper type guards
Always define explicit return types for functions, especially for public APIs
Prefer extending existing types over creating entirely new types
Use TypeScript utility types (Partial<T>, Pick<T, K>, Omit<T, K>, Readonly<T>, Record<K, T>) to derive new types
Use union types and intersection types to combine existing types
Always import types explicitly using the import type syntax
Group type imports separately from value imports
Minimize creating local type aliases for imported types

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-node-hover.ts
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{js,ts,jsx,tsx,css,json}

📄 CodeRabbit inference engine (.cursor/rules/04-code-formatting.mdc)

Maximum line length of 100 characters

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-node-hover.ts
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{js,ts,jsx,tsx,css,json,yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/04-code-formatting.mdc)

Use 2 spaces for indentation, no tabs

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-node-hover.ts
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{js,ts,jsx,tsx,css,json,yml,yaml,md}

📄 CodeRabbit inference engine (.cursor/rules/04-code-formatting.mdc)

No trailing whitespace at the end of lines

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-node-hover.ts
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{jsx,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/05-code-organization.mdc)

Each component file should contain only one main component

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/05-code-organization.mdc)

Explicitly type props with interfaces or types in React components

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{css,scss,sass,less,js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/09-design-system.mdc)

**/*.{css,scss,sass,less,js,jsx,ts,tsx}: Primary color (#155EEF) should be used for main brand color in buttons, links, and accents
Error color (#F04438) should be used for error states and destructive actions
Success color (#12B76A) should be used for success states and confirmations
Warning color (#F79009) should be used for warnings and important notifications
Info color (#0BA5EC) should be used for informational elements

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-node-hover.ts
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (.cursor/rules/09-i18n-guidelines.mdc)

**/*.{tsx,ts}: Use the translation wrapper component and useTranslation hook in components
Ensure all user-facing text is translatable

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-node-hover.ts
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{tsx,ts,json}

📄 CodeRabbit inference engine (.cursor/rules/09-i18n-guidelines.mdc)

Support dynamic content with placeholders in translations

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-node-hover.ts
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{tsx,ts,jsx,js,vue,css,scss,less}

📄 CodeRabbit inference engine (.cursor/rules/11-ui-design-patterns.mdc)

**/*.{tsx,ts,jsx,js,vue,css,scss,less}: Use the primary blue (#155EEF) for main UI elements, CTAs, and active states
Use red (#F04438) only for errors, warnings, and destructive actions
Use green (#12B76A) for success states and confirmations
Use orange (#F79009) for warning states and important notifications
Use blue (#0BA5EC) for informational elements
Primary buttons should be solid with the primary color
Secondary buttons should have a border with transparent or light background
Danger buttons should use the error color
Use consistent padding, border radius, and hover states for all buttons
Follow fixed button sizes based on their importance and context
Use consistent border radius (rounded-lg) for all cards
Apply light shadows (shadow-sm) for card elevation
Maintain consistent padding inside cards (p-4 or p-6)
Use subtle borders for card separation
Ensure proper spacing between card elements
Apply consistent styling to all form inputs
Use clear visual indicators for focus, hover, and error states in form elements
Apply proper spacing between elements using 8px, 16px, 24px increments
Ensure proper alignment of elements (left, center, or right)
Use responsive layouts that work across different device sizes
Maintain a minimum contrast ratio of 4.5:1 for text

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-node-hover.ts
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{tsx,ts,jsx,js,vue}

📄 CodeRabbit inference engine (.cursor/rules/11-ui-design-patterns.mdc)

**/*.{tsx,ts,jsx,js,vue}: Include appropriate loading states for async actions in buttons
Group related form elements with appropriate spacing
Provide clear validation feedback for forms
Ensure proper labeling and accessibility for form elements
Ensure all interactive elements are keyboard accessible
Include appropriate ARIA attributes for complex components
Provide alternative text for images and icons
Support screen readers with semantic HTML elements

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-node-hover.ts
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/08-contributing-guidelines.mdc)

**/*.{ts,tsx,js,jsx}: Follow the TypeScript/JavaScript style guidelines
Ensure code is well-tested and documented

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-node-hover.ts
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/08-contributing-guidelines.mdc)

Use React best practices for frontend code

Files:

  • packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx
  • packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.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). (1)
  • GitHub Check: build / Build
🔇 Additional comments (3)
packages/ai-workspace-common/src/components/canvas/nodes/skill-response.tsx (1)

253-259: LGTM! Hover callbacks correctly updated.

The hover callbacks now properly pass the selected state to the hover effect hook, and the dependency arrays are correctly updated to include selected. This aligns with the simplified z-index management strategy.

packages/ai-workspace-common/src/hooks/canvas/use-selected-node-zIndex.tsx (1)

7-22: LGTM! Clean simplification of z-index management.

The refactored logic is much simpler and easier to understand. The z-index values are clear: 1000 for selected nodes, 0 for memo nodes when not selected, and 1 for all other nodes. The dependency array is correctly specified.

packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx (1)

366-366: Approve the bgColor default change.

The new default color '#FEF2CF' provides a softer, warmer tone compared to the previous '#FFFEE7'. The change is consistent with the panelColors defined at line 275.

Comment on lines +446 to +451
<div
className="relative flex-grow overflow-y-auto"
onClick={() => {
editor?.commands.focus('end');
}}
>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, find the exact file and examine lines around 422 and 446-451
fd "memo.tsx" --type f | head -5

# Show the structure of the directory
ls -la packages/ai-workspace-common/src/components/canvas/nodes/memo/

Repository: refly-ai/refly

Length of output: 494


🏁 Script executed:

#!/bin/bash
# Find and examine the memo.tsx file
find . -name "memo.tsx" -type f 2>/dev/null | grep -E "canvas|nodes" | head -1 > /tmp/memo_path.txt

# If found, examine the critical lines
if [ -s /tmp/memo_path.txt ]; then
  MEMO_FILE=$(cat /tmp/memo_path.txt)
  echo "=== File: $MEMO_FILE ==="
  echo ""
  echo "=== Lines 410-460 (context around lines 422 and 446-451) ==="
  sed -n '410,460p' "$MEMO_FILE" | cat -n
else
  echo "File not found"
fi

# Also search for other editor.commands.focus usages
echo ""
echo "=== Other editor.commands.focus usages ==="
rg -n "editor\?\.commands\.focus" --type=ts --type=tsx -C 2 2>/dev/null || echo "No matches found or rg not available"

Repository: refly-ai/refly

Length of output: 2171


🏁 Script executed:

# Find the file and check its existence
find . -path "*/packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx" -type f 2>/dev/null | head -1

Repository: refly-ai/refly

Length of output: 130


🏁 Script executed:

#!/bin/bash
# Search for memo.tsx files
fd "memo.tsx" 2>/dev/null | head -10

# Also search for editor focus patterns to answer the original verification questions
echo "=== Searching for editor.commands.focus patterns ==="
rg "editor.*commands.focus" --type ts --type tsx 2>/dev/null || echo "Pattern search failed"

Repository: refly-ai/refly

Length of output: 203


Add event.stopPropagation() and use useCallback for the focus handler.

The inner editor container's onClick handler doesn't stop propagation, allowing clicks to trigger both the editor focus and the parent onNodeClick handler. Additionally, focus('end') unconditionally moves the cursor to the document end rather than the click position, which doesn't match typical editor UX.

Fix:

  1. Call event.stopPropagation() to prevent bubbling to the parent handler
  2. Wrap the focus handler with useCallback to avoid creating a new function on every render
  3. Consider using focus() without 'end' to restore the last cursor position, or use a position-aware implementation if click positioning is needed
🤖 Prompt for AI Agents
In packages/ai-workspace-common/src/components/canvas/nodes/memo/memo.tsx around
lines 446 to 451, the inner editor container's onClick both bubbles to the
parent onNodeClick and recreates the handler each render; update it so the click
handler is memoized with useCallback and calls event.stopPropagation() first to
prevent parent handlers from firing, and replace editor?.commands.focus('end')
with editor?.commands.focus() (or implement a position-aware focus if you need
the cursor at the click point) so clicking restores the last cursor position
instead of forcing the document end.

- Adjusted the dependency array in the useCopyPasteSkillResponseNode hook to include getNode for improved functionality.
- Ensured compliance with coding standards, including proper use of optional chaining and nullish coalescing.
- Updated the top positioning of the settings item from `top-4` to `top-5` for improved layout consistency.
- Ensured compliance with coding standards, including proper use of Tailwind CSS for styling.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/ai-workspace-common/src/components/canvas/front-page/index.tsx (1)

167-170: Missing dependency in useMemo.

The avatarAlign prop is used inside the memoized component but is not included in the dependency array. This could cause the component to display stale values if avatarAlign changes.

🔎 Apply this diff to fix the dependency array:
   const renderUserAvatar = useMemo(
     () => <UserAvatar showName={showName} userProfile={userProfile} avatarAlign={avatarAlign} />,
-    [showName, userProfile],
+    [showName, userProfile, avatarAlign],
   );
🧹 Nitpick comments (1)
packages/ai-workspace-common/src/components/canvas/front-page/index.tsx (1)

27-58: Consider replacing any type with proper typing.

The userProfile parameter uses any type in both UserAvatar and SubscriptionInfo components. According to TypeScript guidelines, avoid any type and define explicit types instead.

Consider defining a proper type interface for userProfile:

interface UserProfile {
  nickname?: string;
  avatar?: string;
  subscription?: {
    planType?: string;
  };
}

Then update the component props to use this type instead of any.

Also applies to: 61-104

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 64e2ee8 and 64ca886.

📒 Files selected for processing (2)
  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx (1 hunks)
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (20)
**/*.{jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{jsx,tsx}: Always use tailwind css to style the component
Always wrap pure components with React.memo to prevent unnecessary re-renders
Always use useMemo for expensive computations or complex object creation
Always use useCallback for function props to maintain referential equality
Always specify proper dependency arrays in useEffect to prevent infinite loops
Always avoid inline object/array creation in render to prevent unnecessary re-renders
Always use proper key props when rendering lists
Always split nested components with closures into separate components to avoid performance issues and improve code maintainability

**/*.{jsx,tsx}: Always wrap pure components with React.memo to prevent unnecessary re-renders
Always use useMemo for expensive computations or complex object creation in React
Always use useCallback for function props to maintain referential equality in React
Always specify proper dependency arrays in useEffect to prevent infinite loops in React
Always avoid inline object/array creation in render to prevent unnecessary re-renders in React
Always use proper key props when rendering lists in React (avoid using index when possible)
Always split nested components with closures into separate components in React
Use lazy loading for components that are not immediately needed in React
Debounce handlers for events that might fire rapidly (resize, scroll, input) in React
Implement fallback UI for components that might fail in React
Use error boundaries to catch and handle runtime errors in React

**/*.{jsx,tsx}: Place each attribute on a new line when a component has multiple attributes in JSX
Use self-closing tags for elements without children in JSX
Keep JSX expressions simple, extract complex logic to variables
Put closing brackets for multi-line JSX on a new line

**/*.{jsx,tsx}: Component file names should match the component name
Organize function components in order: imports, type definitions, constants, component function, hook calls, e...

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{js,ts,jsx,tsx}: Always use optional chaining (?.) when accessing object properties
Always use nullish coalescing (??) or default values for potentially undefined values
Always check array existence before using array methods
Always validate object properties before destructuring
Always use single quotes for string literals in JavaScript/TypeScript code

**/*.{js,ts,jsx,tsx}: Use semicolons at the end of statements
Include spaces around operators (e.g., a + b instead of a+b)
Always use curly braces for control statements
Place opening braces on the same line as their statement

**/*.{js,ts,jsx,tsx}: Group import statements in order: React/framework libraries, third-party libraries, internal modules, relative path imports, type imports, style imports
Sort imports alphabetically within each import group
Leave a blank line between import groups
Extract complex logic into custom hooks
Use functional updates for state (e.g., setCount(prev => prev + 1))
Split complex state into multiple state variables rather than single large objects
Use useReducer for complex state logic instead of multiple useState calls

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
**/*.{js,ts,tsx,jsx,py,java,cpp,c,cs,rb,go,rs,php,swift,kt,scala,r,m,mm,sql}

📄 CodeRabbit inference engine (.cursor/rules/00-language-priority.mdc)

**/*.{js,ts,tsx,jsx,py,java,cpp,c,cs,rb,go,rs,php,swift,kt,scala,r,m,mm,sql}: All code comments MUST be written in English
All variable names, function names, class names, and other identifiers MUST use English words
Comments should be concise and explain 'why' rather than 'what'
Use proper grammar and punctuation in comments
Keep comments up-to-date when code changes
Document complex logic, edge cases, and important implementation details
Use clear, descriptive names that indicate purpose
Avoid abbreviations unless they are universally understood

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/00-language-priority.mdc)

Use JSDoc style comments for functions and classes in JavaScript/TypeScript

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/01-code-style.mdc)

**/*.{js,jsx,ts,tsx}: Use single quotes for string literals in TypeScript/JavaScript
Always use optional chaining (?.) when accessing object properties in TypeScript/JavaScript
Always use nullish coalescing (??) or default values for potentially undefined values in TypeScript/JavaScript
Always check array existence before using array methods in TypeScript/JavaScript
Validate object properties before destructuring in TypeScript/JavaScript
Use ES6+ features like arrow functions, destructuring, and spread operators in TypeScript/JavaScript
Avoid magic numbers and strings - use named constants in TypeScript/JavaScript
Use async/await instead of raw promises for asynchronous code in TypeScript/JavaScript

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
**/*.{jsx,tsx,css}

📄 CodeRabbit inference engine (.cursor/rules/01-code-style.mdc)

**/*.{jsx,tsx,css}: Use Tailwind CSS for styling components
Follow the utility-first approach with Tailwind CSS
Group related utility classes together in Tailwind CSS
Prefer Tailwind utilities over custom CSS when possible

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/03-typescript-guidelines.mdc)

**/*.{ts,tsx}: Avoid using any type whenever possible - use unknown type instead with proper type guards
Always define explicit return types for functions, especially for public APIs
Prefer extending existing types over creating entirely new types
Use TypeScript utility types (Partial<T>, Pick<T, K>, Omit<T, K>, Readonly<T>, Record<K, T>) to derive new types
Use union types and intersection types to combine existing types
Always import types explicitly using the import type syntax
Group type imports separately from value imports
Minimize creating local type aliases for imported types

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
**/*.{js,ts,jsx,tsx,css,json}

📄 CodeRabbit inference engine (.cursor/rules/04-code-formatting.mdc)

Maximum line length of 100 characters

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
**/*.{js,ts,jsx,tsx,css,json,yml,yaml}

📄 CodeRabbit inference engine (.cursor/rules/04-code-formatting.mdc)

Use 2 spaces for indentation, no tabs

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
**/*.{js,ts,jsx,tsx,css,json,yml,yaml,md}

📄 CodeRabbit inference engine (.cursor/rules/04-code-formatting.mdc)

No trailing whitespace at the end of lines

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
**/*.{jsx,tsx,js}

📄 CodeRabbit inference engine (.cursor/rules/05-code-organization.mdc)

Each component file should contain only one main component

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
**/index.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/05-code-organization.mdc)

Use index files to export multiple components from a directory

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/05-code-organization.mdc)

Explicitly type props with interfaces or types in React components

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
**/*.{css,scss,sass,less,js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/09-design-system.mdc)

**/*.{css,scss,sass,less,js,jsx,ts,tsx}: Primary color (#155EEF) should be used for main brand color in buttons, links, and accents
Error color (#F04438) should be used for error states and destructive actions
Success color (#12B76A) should be used for success states and confirmations
Warning color (#F79009) should be used for warnings and important notifications
Info color (#0BA5EC) should be used for informational elements

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
**/*.{tsx,ts}

📄 CodeRabbit inference engine (.cursor/rules/09-i18n-guidelines.mdc)

**/*.{tsx,ts}: Use the translation wrapper component and useTranslation hook in components
Ensure all user-facing text is translatable

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
**/*.{tsx,ts,json}

📄 CodeRabbit inference engine (.cursor/rules/09-i18n-guidelines.mdc)

Support dynamic content with placeholders in translations

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
**/*.{tsx,ts,jsx,js,vue,css,scss,less}

📄 CodeRabbit inference engine (.cursor/rules/11-ui-design-patterns.mdc)

**/*.{tsx,ts,jsx,js,vue,css,scss,less}: Use the primary blue (#155EEF) for main UI elements, CTAs, and active states
Use red (#F04438) only for errors, warnings, and destructive actions
Use green (#12B76A) for success states and confirmations
Use orange (#F79009) for warning states and important notifications
Use blue (#0BA5EC) for informational elements
Primary buttons should be solid with the primary color
Secondary buttons should have a border with transparent or light background
Danger buttons should use the error color
Use consistent padding, border radius, and hover states for all buttons
Follow fixed button sizes based on their importance and context
Use consistent border radius (rounded-lg) for all cards
Apply light shadows (shadow-sm) for card elevation
Maintain consistent padding inside cards (p-4 or p-6)
Use subtle borders for card separation
Ensure proper spacing between card elements
Apply consistent styling to all form inputs
Use clear visual indicators for focus, hover, and error states in form elements
Apply proper spacing between elements using 8px, 16px, 24px increments
Ensure proper alignment of elements (left, center, or right)
Use responsive layouts that work across different device sizes
Maintain a minimum contrast ratio of 4.5:1 for text

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
**/*.{tsx,ts,jsx,js,vue}

📄 CodeRabbit inference engine (.cursor/rules/11-ui-design-patterns.mdc)

**/*.{tsx,ts,jsx,js,vue}: Include appropriate loading states for async actions in buttons
Group related form elements with appropriate spacing
Provide clear validation feedback for forms
Ensure proper labeling and accessibility for form elements
Ensure all interactive elements are keyboard accessible
Include appropriate ARIA attributes for complex components
Provide alternative text for images and icons
Support screen readers with semantic HTML elements

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursor/rules/08-contributing-guidelines.mdc)

**/*.{ts,tsx,js,jsx}: Follow the TypeScript/JavaScript style guidelines
Ensure code is well-tested and documented

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/08-contributing-guidelines.mdc)

Use React best practices for frontend code

Files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
🧠 Learnings (6)
📚 Learning: 2025-11-25T03:05:07.580Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/11-ui-design-patterns.mdc:0-0
Timestamp: 2025-11-25T03:05:07.580Z
Learning: Applies to **/*.{tsx,ts,jsx,js,vue,css,scss,less} : Ensure proper alignment of elements (left, center, or right)

Applied to files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
📚 Learning: 2025-11-25T03:05:07.580Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/11-ui-design-patterns.mdc:0-0
Timestamp: 2025-11-25T03:05:07.580Z
Learning: Applies to **/*.{tsx,ts,jsx,js,vue,css,scss,less} : Ensure proper spacing between card elements

Applied to files:

  • packages/ai-workspace-common/src/components/canvas/front-page/index.tsx
📚 Learning: 2025-11-25T03:03:31.945Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/01-code-style.mdc:0-0
Timestamp: 2025-11-25T03:03:31.945Z
Learning: Applies to **/*.{jsx,tsx} : Always specify proper dependency arrays in useEffect to prevent infinite loops in React

Applied to files:

  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
📚 Learning: 2025-11-25T03:02:45.779Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T03:02:45.779Z
Learning: Applies to **/*.{jsx,tsx} : Always specify proper dependency arrays in useEffect to prevent infinite loops

Applied to files:

  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
📚 Learning: 2025-11-25T03:02:45.779Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T03:02:45.779Z
Learning: Applies to **/*.{jsx,tsx} : Always use useCallback for function props to maintain referential equality

Applied to files:

  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
📚 Learning: 2025-11-25T03:03:31.945Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/01-code-style.mdc:0-0
Timestamp: 2025-11-25T03:03:31.945Z
Learning: Applies to **/*.{jsx,tsx} : Always use useCallback for function props to maintain referential equality in React

Applied to files:

  • packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
🧬 Code graph analysis (1)
packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts (2)
apps/api/src/modules/tool/sandbox/wrapper/base.ts (1)
  • canvasId (200-202)
packages/ai-workspace-common/src/events/nodeActions.ts (2)
  • nodeActionEmitter (34-34)
  • createNodeEventName (36-37)
⏰ 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: build / Build
🔇 Additional comments (5)
packages/ai-workspace-common/src/components/canvas/front-page/index.tsx (1)

392-394: LGTM! Improved positioning consistency.

The change from top-4 right-[1px] to top-5 right-5 improves consistency by using standard Tailwind spacing units instead of arbitrary values, and aligns both offsets to the same spacing increment (20px).

packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts (4)

10-13: LGTM! Event emitter imports are appropriate.

The imports are necessary for emitting memo duplication events and follow the coding guidelines for named imports.


53-53: LGTM! Extension to memo nodes is appropriate.

The filter correctly includes both skillResponse and memo node types for copy operations.


99-103: LGTM! Validation logic is consistent.

The paste validation correctly allows both skillResponse and memo node types, maintaining consistency with the copy operation.


130-130: LGTM! Dependency array is now correct.

The dependency array correctly includes all reactive values used in the callback and excludes the module-level constant nodeActionEmitter. This addresses the issue raised in the previous review.

Comment on lines 106 to 127
const fixedOffset = { x: 0, y: 200 };

// Paste all copied nodes with fixed offset from original position
for (const node of copiedNodes) {
const originalNode = getNode(node.id);
if (originalNode) {
if (!originalNode) {
continue;
}
if (originalNode.type === 'skillResponse') {
duplicateNode(originalNode, canvasId, { offset: fixedOffset });
} else if (originalNode.type === 'memo') {
nodeActionEmitter.emit(createNodeEventName(originalNode.id, 'duplicate'), {
dragCreateInfo: {
nodeId: originalNode.id,
handleType: 'source',
position: {
x: originalNode.position.x,
y: originalNode.position.y + 300,
},
},
});
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Extract magic numbers 200 and 300 into named constants.

The Y offsets (200 for skillResponse paste and 300 for memo paste) should be defined as named constants at the top of the function for clarity and maintainability, as specified in the coding guidelines: "Avoid magic numbers and strings - use named constants."

Update the code as suggested:

+ const SKILL_RESPONSE_PASTE_Y_OFFSET = 200;
+ const MEMO_PASTE_Y_OFFSET = 300;

Then use these constants in the calculations:

  • Replace line 115: { offset: fixedOffset } with references to SKILL_RESPONSE_PASTE_Y_OFFSET
  • Replace line 123: y: originalNode.position.y + 300 with y: originalNode.position.y + MEMO_PASTE_Y_OFFSET

This improves readability without requiring documentation on why the offsets differ, as that reasoning may depend on UI/UX design requirements for each node type.

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In
packages/ai-workspace-common/src/hooks/canvas/use-copy-paste-skill-response-node.ts
around lines 106 to 127, extract the magic numbers 200 and 300 into named
constants by declaring SKILL_RESPONSE_PASTE_Y_OFFSET = 200 and
MEMO_PASTE_Y_OFFSET = 300 at the top of the function, replace the fixedOffset.y
value with SKILL_RESPONSE_PASTE_Y_OFFSET (i.e., fixedOffset = { x: 0, y:
SKILL_RESPONSE_PASTE_Y_OFFSET }) and replace originalNode.position.y + 300 with
originalNode.position.y + MEMO_PASTE_Y_OFFSET, keeping all other logic
unchanged.

@mrcfps mrcfps changed the title Fix/file upload notify style feat: support multi-image batch upload and copy-pasting for memos Dec 19, 2025
@mrcfps mrcfps merged commit 79adcd7 into main Dec 19, 2025
2 checks passed
@mrcfps mrcfps deleted the fix/file-upload-notify-style branch December 19, 2025 03:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants