Skip to content

Conversation

@Siri-Ray
Copy link
Contributor

@Siri-Ray Siri-Ray commented Dec 3, 2025

Summary

Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.

Tip

Close issue syntax: Fixes #<issue number> or Resolves #<issue number>, see documentation for more details.

Impact Areas

Please check the areas this PR affects:

  • Multi-threaded Dialogues
  • AI-Powered Capabilities (Web Search, Knowledge Base Search, Question Recommendations)
  • Context Memory & References
  • Knowledge Base Integration & RAG
  • Quotes & Citations
  • AI Document Editing & WYSIWYG
  • Free-form Canvas Interface
  • Other

Screenshots/Videos

Before After
... ...

Checklist

Important

Please review the checklist below before submitting your pull request.

  • This change requires a documentation update, included: Refly Documentation
  • I understand that this PR may be closed in case there was no previous discussion or issues. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.
  • I ran dev/reformat(backend) and cd web && npx lint-staged(frontend) to appease the lint gods

Summary by CodeRabbit

  • New Features

    • Plans simplified to Free and Plus; Free now displays a $0/month price block; Plus supports per-feature styling and grouped tool entries.
  • UI Updates

    • Pricing cards refreshed: explicit selected borders, hover gradient for paid plans, rounded yearly badge, subscription and lightning icons, upgraded button icon (size/color) and visual tweaks across cards.
  • Messaging

    • Updated subscription and plan wording; "Go to Marketplace" → "Explore More Templates" (EN/ZH).

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

mrcfps and others added 10 commits November 3, 2025 17:51
fix(credit): update credit usage calculation in ShareCreationService
Staging Release 20251128
* feat(http-cache): add http cache support for file streams (#1671)

- Add lastModified field to file stream responses
- Implement http cache utilities with etag and cache-control headers
- Add cache validation in controllers for file endpoints

* feat: 304 responses no longer read from object storage (#1672)

* feat(http-cache): add http cache support for file streams

- Add lastModified field to file stream responses
- Implement http cache utilities with etag and cache-control headers
- Add cache validation in controllers for file endpoints

* feat(file): optimize file serving with metadata-first approach

Add metadata-only methods for file operations to check cache before loading full content
Implement lazy loading of file content only when cache is stale
Update controllers to use new metadata methods for better performance

* feat(credit-billing): update credit billing info component and translations (#1673)

- Enhance CreditBillingInfo component to display both input and output costs.
- Update i18n translations for credit billing to reflect new input and output cost structure.
- Adjust tooltip styling for improved layout and readability.

---------

Co-authored-by: lefarcen <[email protected]>
fix(front-page): handle empty template categories to prevent infinite loading
* feat: enhance workflow file variable support (#1686)

* feat: Implement DriveFile creation and management for resource variables in workflow apps

* feat: enhance workflow/agent stop confirmations with detailed messages, enable file-to-variable creation using storageKey, and adjust layout for shared files

* feat: Improve file type detection with MIME types and add automatic DriveFile creation for resources.

* feat: Add loading dots animation for file uploads and configure JSONC formatter in VS Code settings.

* refactor: Add optional chaining for metadata source access and configure VS Code JSON formatter for jsonc files.

* refactor: improve `DriveFile` creation logic in workflow form and add `jsonc` formatter setting for VS Code.

* chore: Update sitemap last modification dates, improve `context.ts` type filtering, and add VSCode JSONC formatter.

* feat: Add file upload error logging, configure JSONC formatter, update sitemap modification dates, and remove a canvas service comment.

* feat: Introduce `duplicateDriveFile` flag for conditional drive file duplication during canvas variable processing and update sitemap modification dates.

* feat: optimize agent system prompt (#1687)

* WIP: optimize sandbox cold start performance

Implemented two optimizations to reduce cold start latency:

1. Active mount verification (Optimization 1)
   - Replace fixed 2s wait with active polling
   - Poll every 100ms with exponential backoff
   - 5s timeout for safety
   - Saves ~1.2s (59% reduction)

2. Defer getInfo() call (Optimization 2)
   - Remove blocking getInfo() before mount
   - Use local calculation: Date.now() + timeoutMs
   - Actual timeoutAt updated on release/extendTimeout
   - Saves ~1s

Performance impact:
- Before: 13,310ms (mount ready)
- After: ~11,124ms (mount ready)
- Improvement: -2,186ms (-16.4%)

Changes:
- Add scalebox.tracer.ts: OpenTelemetry decorators (@Trace/@measure)
- Update scalebox.wrapper.ts: Both optimizations + instrumentation
- Update scalebox.constants.ts: Mount verification config
- Update scalebox.service.ts: Instrumentation
- Update scalebox.pool.ts: Instrumentation
- Add Jaeger to docker-compose for local trace collection
- Add OTLP_TRACES_ENDPOINT to .env.example

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* WIP: refactor guard.defer to enforce RAII pattern

## Changes

### 1. guard.ts - Unified defer API
- Rewrote `guard.defer` to enforce RAII (Resource Acquisition Is Initialization)
- New signature: `defer(acquirer, task, onCleanupError)`
  - acquirer: Returns `[resource, cleanup]` tuple
  - task: Receives resource and executes business logic
  - cleanup: Guaranteed to execute in finally block
- Removed separate `deferBasic` and `deferWithResource` functions
- Added comprehensive JSDoc with usage example

### 2. scalebox.service.ts - Three-layer defer refactor
- Layer 1 (executeCode): Canvas-level lock management
  - Lock resource type: `void` (lock is side-effect, not used in task)
  - Added lock timeout mechanism with `guard.retry`
  - Timeout: 5min (configurable), Poll interval: 100ms
- Layer 2 (executeCodeWithSandbox): Sandbox lifecycle
  - Resource: `SandboxWrapper`
  - Cleanup: Release sandbox to pool
- Layer 3 (executeWithMount): Drive mount/unmount
  - Resource: `SandboxWrapper`
  - Cleanup: Unmount drive

### 3. scalebox.pool.ts - Pool lock refactor
- createNew(): Global pool creation lock uses new defer API
  - Lock resource type: `void`
  - Cleanup: Release lock
- release(): Changed to `guard.bestEffort` for non-critical operations
  - Internal validations use `guard.ensure().orThrow()`
  - Errors logged but don't block main flow

### 4. scalebox.constants.ts - Lock configuration
- Added `SCALEBOX_DEFAULT_LOCK_WAIT_TIMEOUT_MS = 5min`
- Added `SCALEBOX_DEFAULT_LOCK_POLL_INTERVAL_MS = 100ms`

### 5. scalebox.exception.ts - New exception
- Added `SandboxLockTimeoutException` for lock acquisition timeout

## Benefits

✅ **Unified RAII pattern**: All resource management uses same pattern
✅ **Resource locality**: Acquire and release in same scope
✅ **Type safety**: TypeScript infers resource types automatically
✅ **Clear semantics**: Lock (void) vs Entity (wrapper) distinction
✅ **No resource leaks**: Cleanup guaranteed in finally block
✅ **Better error handling**: Cleanup errors handled separately

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* fix: add s3DrivePath to ScaleboxExecutionJobData and processor

* fix: use fusermount -uz for lazy FUSE unmount

- Changed from 'umount' to 'fusermount -uz' for FUSE filesystems
- -u: unmount, -z: lazy unmount (detach even if busy)
- Fixes 'target is busy' error when unmounting s3fs
- Verification step remains to ensure unmount completes

* fix: always use allowNonEmpty for mount in global pool

- After unmount, /mnt/refly may not be completely empty
- Reused sandboxes need nonempty option for remount
- Safe to use because we control the mount point path
- Fixes 's3fs: MOUNTPOINT directory is not empty' error

* fix: remove unmount verification for lazy unmount

- fusermount -uz is async lazy unmount, completes in background
- Immediate verification often fails while still unmounting
- Next mount uses allowNonEmpty, so residual state is safe
- Cleanup should be best-effort, not fail on verification
- Removed unused constants: SANDBOX_UNMOUNT_POLL_* and STABILIZE_DELAY

* feat: add max lifetime check for sandbox instances

Prevents accumulation of issues from long-running sandboxes:

**Resource accumulation**:
- FUSE mount/unmount residual state (memory, file descriptors)
- inode/dentry cache growth in kernel
- s3fs daemon resource leaks

**Code execution state**:
- Background processes and timers (setInterval, cron)
- Orphaned/zombie processes
- Temporary files and log accumulation
- Global state pollution (env vars, Python sys.modules, Node globals)

**Security**:
- Reduces attack window for compromised sandboxes
- Limits exposure of sensitive data in memory

**Implementation**:
- Added SCALEBOX_DEFAULT_MAX_LIFETIME_MS = 6 hours
- Check lifetime on release, discard if exceeded
- Configurable via sandbox.scalebox.maxLifetimeMs
- Logs lifetime hours for monitoring

* feat: add auto-pause mechanism for idle sandboxes

Implements delayed pause strategy to balance performance and cost:

**Design**:
- Release: Set 10min timer to auto-pause if not reused
- Acquire: Cancel timer + resume if paused
- Fast reuse (<10min): No pause/resume overhead, stays running
- Long idle (>10min): Auto-paused to save resources

**Implementation**:
- Added SCALEBOX_DEFAULT_AUTO_PAUSE_DELAY_MS = 10 minutes
- Pool maintains Map<sandboxId, NodeJS.Timeout> for timers
- Wrapper exposes getInfo(), betaPause(), resume() methods
- reconnectSandbox(): Cancel timer + check/resume paused sandboxes
- release(): Set auto-pause timer after returning to pool
- autoPauseSandbox(): Best-effort pause with error logging

**Trade-offs**:
- Simple approach: Uses setTimeout (lost on process restart)
- Acceptable: Process restart is low-frequency
- Fallback: New process will eventually pause idle sandboxes
- Worst case: Sandbox stays running → controlled cost increase, no performance impact

**Benefits**:
✅ Quick reuse: <10min window stays running (fast)
✅ Cost savings: Long idle sandboxes paused
✅ Automatic: No manual intervention needed
✅ Resilient: Resume on demand if paused

* fix: use type assertion for sandbox.resume() API

SDK type definition missing, but API exists in runtime

* feat: optimize auto-pause with state tracking and remove redundant health checks

Performance optimizations for sandbox auto-pause mechanism:

1. Add pause state tracking to prevent frequent reconnect cycles
   - Add isPaused and lastPausedAt fields to SandboxMetadata
   - Implement markAsPaused() and markAsRunning() methods in SandboxWrapper
   - Check metadata.isPaused in tryAutoPause() to skip if already paused
   - Update pause state in metadata after SDK auto-resume on reconnect
   - Reduces unnecessary reconnect→resume→pause cycles from setTimeout callbacks

2. Remove redundant health check logic
   - Remove isHealthy() method with dual checks (isRunning + getInfo)
   - Remove health check retry in reconnect() - trust SDK's connect() guarantee
   - Remove health check retry in tryReturnToIdle() - trust execution flow
   - Remove HEALTH_CHECK_RETRY_CONFIG constant
   - Remove SandboxHealthCheckFailedException
   - Reduces latency by eliminating 5s retry timeouts

3. Clean up unused code
   - Remove unused maxSandboxes config and SCALEBOX_DEFAULT_MAX_SANDBOXES import
   - Add inline comment for @config decorator dependency on ConfigService

Benefits:
- Auto-pause frequency significantly reduced (acceptable race condition overflow)
- Faster reconnection without health check delays
- Simpler code that trusts SDK guarantees
- Better resource utilization with metadata-based state tracking

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* chore(sandbox): add prisma script

* feat(sandbox): optimize log message report

* wip(sandbox): scalebox performance optimization and observability

Major improvements to sandbox system:
- Lock configuration refactoring with reverse calculation from runCodeTimeout
- Extract lock logic to dedicated scalebox.lock.ts module
- Implement SDK timeout and critical error detection
- Add observability stack (Grafana, Loki, Tempo)
- Optimize file registration and pool management
- Update configuration system with validation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* wip(sandbox): config flattening, lock simplification, s3 credential security

- Flatten app.config.ts structure, add Ms/Sec suffixes to time params
- Constants renamed to SCREAMING_SNAKE_CASE
- Lock service simplified: inline TTL/timeout calculation (300→107 lines)
- S3 mount uses passwd_file with subshell cleanup pattern
- Extract acquireQueueEvents, add ExecuteCodeContext interface

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* wip(sandbox): auto-pause via BullMQ delayed jobs

- Add QUEUE_SCALEBOX_EXECUTE / QUEUE_SCALEBOX_PAUSE queues
- Implement schedulePause/cancelPause in SandboxPool
- Merge processors: ScaleboxExecuteProcessor + ScaleboxPauseProcessor
- Remove deprecated timeout param from SandboxExecuteParams

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* wip(sandbox): fix BullMQ concurrency and optimize logging

- Fix: @processor decorator concurrency now uses SCALEBOX_DEFAULTS.LOCAL_CONCURRENCY
  (getWorkerOptions() is not supported by @nestjs/bullmq)
- Remove localConcurrency from runtime config (compile-time constant only)
- Add phase field to key logs for filtering (lock/acquire/execute/release/pause/complete)
- Use logger.assign() for automatic canvasId/sandboxId/jobId injection
- Use storage.run() for AsyncLocalStorage context in BullMQ workers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* wip(sandbox): sandbox lock TTL fix and code cleanup

- Fix sandbox lock leakage: replace ACTIVE_SET with TTL-based individual keys
- Add ScaleboxResponseFactory for unified response building
- Remove setSpanAttributes (to be added later as needed)
- Merge mkdir into mountS3 command to reduce round-trips
- QueueEvents singleton lifecycle management

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* wip(sandbox): enhance error logging and tracing

- Add try-catch in processor to log full error before re-throwing to BullMQ
- Add warn logs in wrapper for SDK failures (runCommand, executeCode, listCwdFiles)
- Add SandboxRunCodeException for runCode SDK errors
- Enable SandboxFileListException for files.list errors
- Set logger context to SandboxWrapper in constructor
- Remove redundant context fields from log statements

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* feat(sandbox): lock auto-renewal, error classification, and config simplification

Lock mechanism improvements:
- Short initial TTL (10s) with periodic renewal (3s)
- UUID-based lock ownership to prevent accidental release
- Lua scripts for atomic renewal and release operations
- Simplified lock wait timeout config (LOCK_WAIT_TIMEOUT_SEC: 60s)

Error classification enhancements:
- Distinguish code_error (exitCode!=0) from system_error (infrastructure)
- Detect transient errors: timeout, gRPC UNAVAILABLE/CANCELLED
- User-friendly error messages for model consumption

Configuration cleanup:
- Remove FILE_BUFFER_SEC, DRIVE_BUFFER_SEC, QUEUE_DEPTH
- Add LOCK_WAIT_TIMEOUT_SEC for direct timeout config
- Adjust defaults: MAX_SANDBOXES=10, LOCAL_CONCURRENCY=5

Guard utility:
- Add retryIf option for conditional retry logic

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* chore(sandbox): update .env and config variables for scalebox service.

* feat(prompt): rewrite node-agent system prompt

- Define clear identity as Refly.ai Node Agent for vibe workflow
- Add two-level agent architecture (Copilot vs Node Agent)
- Introduce ReAct with Silent Execution behavior mode
- Document builtin tools with latency and usage patterns
- Clarify fileId vs fileName for different tools
- Add override rules for user customization

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* feat: builtin toolset optimization

* fix: fallback to null when URL constructor fail

* feat(sandbox): upgrade sdk version

* fix(sandbox): optimize 503 error

* WIP: optimize agent system prompts

- node-agent: add <tool_decision> XML tag, restructure builtin tools with Use when/NOT for patterns
- copilot-agent: add <task_splitting> and <task_patterns> for workflow design guidance

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* WIP: refactor copilot-agent example with Warren Buffett analysis

- Replace minimal example with comprehensive investment analysis example
- Add Design Thinking & Decisions format for decision reasoning
- Remove .txt filename hints to avoid redundant format descriptions
- Change to sequential execution for weak model compatibility
- Add Get Time + Data pattern for implicit parameter resolution
- Add execute_code constraint for file path requirements

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* feat(agent): optimize system prompts for better tool selection

- Rewrite tool-product mapping with clear selection rules
- Add tool constraints (execute_code file paths, web_search scope)
- Optimize Jina tool descriptions (read/serp differentiation)
- Add best-effort delivery guideline to node-agent
- Remove auto-inject logic in normalizeWorkflowPlan
- Remove unused docker trace configurations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* feat(agent): use semantic time identification over date range resolution

Change example prompts from "Resolve X to date range" to "Identify X"
to reduce model tendency to over-engineer time parsing with execute_code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

---------

Co-authored-by: HanYuanxi <[email protected]>
Co-authored-by: Claude <[email protected]>

* feat(resource-handler): enhance fileId validation and extraction logic (#1695)

* feat(canvas): add publish template popover with dark mode support (#1697)

* feat(canvas): add publish template popover with dark mode support

- Add PublishTemplatePopover component with shareable link and update button
- Integrate popover into PublishTemplateButton when shareId exists
- Add i18n support for copy and update template actions
- Implement dark mode compatibility using Tailwind CSS and CSS variables
- Add proper state management and cleanup for timeouts
- Handle disabled state to prevent popover opening
- Reset linkCopied state when popover closes or shareId changes

* refactor(workflow-app): remove share link button from create modal footer

* fix: various UI and style issues (#1698)

* refactor(canvas): optimize CustomEdge component and enhance input styling

- Refactored the CustomEdge component to improve performance by consolidating status checks for target nodes.
- Updated input components across various forms to use TextArea with auto-sizing and filled variant for better user experience.
- Enhanced styling consistency by applying Tailwind CSS classes and ensuring proper use of optional chaining and nullish coalescing for safer property access.
- Added destroyOnClose property to CreateWorkflowAppModal for improved modal behavior.
- Updated success message for workflow initialization to provide clearer feedback to users.

* feat(skill-response): add iconSize prop to SkillResponseNodeHeader for customizable icon dimensions

- Introduced iconSize prop to SkillResponseNodeHeader to allow customization of icon dimensions.
- Updated SkillResponseNodePreviewComponent to pass iconSize value, enhancing flexibility in component usage.

* feat: add refly-toast-fill color and update styling for toast messages

- Introduced a new CSS variable `--refly-toast-fill` for customizable toast background color.
- Updated `antd-overrides.css` to apply the new toast fill color with enhanced styling for message notices.
- Added the `refly-toast-fill` variable to `tailwind-colors.ts` for consistent usage across the application.
- Ensured proper use of Tailwind CSS for styling adjustments and maintained code quality standards.

* fix(share): update share page detection and routing (#1699)

* fix(share): update share page detection and routing

* fix: formart

* Feat/publish precheck (#1696)

* feat: publish pre check

* feat(workflow-app): add validation and highlight for publish template

- Add validation checks before publishing template:
  - Check for user input variables (highest priority)
  - Check for agent nodes existence (second priority)
  - Check for failed or unrun agent nodes (third priority)
- Auto-fit canvas view when validation fails
- Highlight failed/unrun agent nodes using built-in highlight mechanism
- Add toast messages for each validation error
- Extend canvas-nodes store to support multiple node highlights
- Add node deletion cleanup to prevent memory leaks
- Add concurrent submission protection
- Improve error handling and edge cases

* i18n(workflow-app): update publish to community text to marketplace

* fix(workflow-app): validate empty run result and block publishing

* feat(api): store result_id, version and tool call related data to credit usages (#1702)

* feat(api): store result_id, version and tool call related data to credit usages

- Introduced `toolCallId` and `toolCallMeta` fields in the CreditUsage model to store related tool call information.
- Updated `SyncToolCreditUsageJobData` interface to include new fields for tool call metadata.
- Enhanced `syncToolCreditUsage` method in CreditService to handle tool call data during credit usage synchronization.
- Refactored related service methods to utilize the new tool call metadata for improved credit tracking and reporting.

* feat(api): set default runId using randomUUID for tool calls

- Updated the SkillInvokerService to assign a default runId using randomUUID when event.run_id is not provided.
- This change ensures that tool calls have a unique identifier even when the event data is incomplete, improving traceability and reliability.

* feat: remove user model config and prioritize system model config (#1703)

* feat(api): prioritize system model config over user config

- Removed unused ProviderModule import from auth.module.ts.
- Eliminated ProviderService dependency from auth.service.ts and its related method calls.
- Updated user preferences handling in provider.service.ts to prioritize system preferences and improved default model configuration logic.
- Ensured proper use of optional chaining and nullish coalescing for safer property access.

* refactor(settings): comment out unused settings components and update tab structure

- Commented out unused imports for ModelProviders, ModelConfig, and ParserConfig to streamline the Settings component.
- Updated the tabs structure to include the Account and Subscription settings while removing the commented-out model-related tabs.
- Adjusted the translation for 'Tools Config' to 'Tools' in both English and Chinese translations for consistency.

* fix: update file filtering logic (#1704)

fix: handle optional chaining for subscription check

refactor: update file filtering logic to exclude variables

---------

Co-authored-by: lefarcen <[email protected]>
Co-authored-by: PerishFire <[email protected]>
Co-authored-by: HanYuanxi <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: a1chzt <[email protected]>
Co-authored-by: Achieve <[email protected]>
Co-authored-by: Sophia <[email protected]>
* style: enhance CopilotMessage and ModelSelector components (#1706)

* style: enhance CopilotMessage and ModelSelector components with Tailwind CSS adjustments

- Added `break-all` class to the user query bubble in CopilotMessage for better text wrapping.
- Updated ModelSelector to include `my-2` margin for improved spacing.
- Commented out unused SettingsButton components in both ModelSelector and MediaModelSelector for cleaner code.

* refactor: remove unused settings modal logic and update model selector display

- Removed the `handleOpenSettingModal` function and related settings modal logic from the `ModelSelector` component for cleaner code.
- Updated the `SelectedModelDisplay` to show a message when no models are available instead of the configuration option.
- Added a new translation for 'No available models' in both English and Chinese.

* Feat/scalebox custom template upgrade (#1700)

* WIP: optimize sandbox cold start performance

Implemented two optimizations to reduce cold start latency:

1. Active mount verification (Optimization 1)
   - Replace fixed 2s wait with active polling
   - Poll every 100ms with exponential backoff
   - 5s timeout for safety
   - Saves ~1.2s (59% reduction)

2. Defer getInfo() call (Optimization 2)
   - Remove blocking getInfo() before mount
   - Use local calculation: Date.now() + timeoutMs
   - Actual timeoutAt updated on release/extendTimeout
   - Saves ~1s

Performance impact:
- Before: 13,310ms (mount ready)
- After: ~11,124ms (mount ready)
- Improvement: -2,186ms (-16.4%)

Changes:
- Add scalebox.tracer.ts: OpenTelemetry decorators (@Trace/@Measure)
- Update scalebox.wrapper.ts: Both optimizations + instrumentation
- Update scalebox.constants.ts: Mount verification config
- Update scalebox.service.ts: Instrumentation
- Update scalebox.pool.ts: Instrumentation
- Add Jaeger to docker-compose for local trace collection
- Add OTLP_TRACES_ENDPOINT to .env.example

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* WIP: refactor guard.defer to enforce RAII pattern

## Changes

### 1. guard.ts - Unified defer API
- Rewrote `guard.defer` to enforce RAII (Resource Acquisition Is Initialization)
- New signature: `defer(acquirer, task, onCleanupError)`
  - acquirer: Returns `[resource, cleanup]` tuple
  - task: Receives resource and executes business logic
  - cleanup: Guaranteed to execute in finally block
- Removed separate `deferBasic` and `deferWithResource` functions
- Added comprehensive JSDoc with usage example

### 2. scalebox.service.ts - Three-layer defer refactor
- Layer 1 (executeCode): Canvas-level lock management
  - Lock resource type: `void` (lock is side-effect, not used in task)
  - Added lock timeout mechanism with `guard.retry`
  - Timeout: 5min (configurable), Poll interval: 100ms
- Layer 2 (executeCodeWithSandbox): Sandbox lifecycle
  - Resource: `SandboxWrapper`
  - Cleanup: Release sandbox to pool
- Layer 3 (executeWithMount): Drive mount/unmount
  - Resource: `SandboxWrapper`
  - Cleanup: Unmount drive

### 3. scalebox.pool.ts - Pool lock refactor
- createNew(): Global pool creation lock uses new defer API
  - Lock resource type: `void`
  - Cleanup: Release lock
- release(): Changed to `guard.bestEffort` for non-critical operations
  - Internal validations use `guard.ensure().orThrow()`
  - Errors logged but don't block main flow

### 4. scalebox.constants.ts - Lock configuration
- Added `SCALEBOX_DEFAULT_LOCK_WAIT_TIMEOUT_MS = 5min`
- Added `SCALEBOX_DEFAULT_LOCK_POLL_INTERVAL_MS = 100ms`

### 5. scalebox.exception.ts - New exception
- Added `SandboxLockTimeoutException` for lock acquisition timeout

## Benefits

✅ **Unified RAII pattern**: All resource management uses same pattern
✅ **Resource locality**: Acquire and release in same scope
✅ **Type safety**: TypeScript infers resource types automatically
✅ **Clear semantics**: Lock (void) vs Entity (wrapper) distinction
✅ **No resource leaks**: Cleanup guaranteed in finally block
✅ **Better error handling**: Cleanup errors handled separately

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* fix: add s3DrivePath to ScaleboxExecutionJobData and processor

* fix: use fusermount -uz for lazy FUSE unmount

- Changed from 'umount' to 'fusermount -uz' for FUSE filesystems
- -u: unmount, -z: lazy unmount (detach even if busy)
- Fixes 'target is busy' error when unmounting s3fs
- Verification step remains to ensure unmount completes

* fix: always use allowNonEmpty for mount in global pool

- After unmount, /mnt/refly may not be completely empty
- Reused sandboxes need nonempty option for remount
- Safe to use because we control the mount point path
- Fixes 's3fs: MOUNTPOINT directory is not empty' error

* fix: remove unmount verification for lazy unmount

- fusermount -uz is async lazy unmount, completes in background
- Immediate verification often fails while still unmounting
- Next mount uses allowNonEmpty, so residual state is safe
- Cleanup should be best-effort, not fail on verification
- Removed unused constants: SANDBOX_UNMOUNT_POLL_* and STABILIZE_DELAY

* feat: add max lifetime check for sandbox instances

Prevents accumulation of issues from long-running sandboxes:

**Resource accumulation**:
- FUSE mount/unmount residual state (memory, file descriptors)
- inode/dentry cache growth in kernel
- s3fs daemon resource leaks

**Code execution state**:
- Background processes and timers (setInterval, cron)
- Orphaned/zombie processes
- Temporary files and log accumulation
- Global state pollution (env vars, Python sys.modules, Node globals)

**Security**:
- Reduces attack window for compromised sandboxes
- Limits exposure of sensitive data in memory

**Implementation**:
- Added SCALEBOX_DEFAULT_MAX_LIFETIME_MS = 6 hours
- Check lifetime on release, discard if exceeded
- Configurable via sandbox.scalebox.maxLifetimeMs
- Logs lifetime hours for monitoring

* feat: add auto-pause mechanism for idle sandboxes

Implements delayed pause strategy to balance performance and cost:

**Design**:
- Release: Set 10min timer to auto-pause if not reused
- Acquire: Cancel timer + resume if paused
- Fast reuse (<10min): No pause/resume overhead, stays running
- Long idle (>10min): Auto-paused to save resources

**Implementation**:
- Added SCALEBOX_DEFAULT_AUTO_PAUSE_DELAY_MS = 10 minutes
- Pool maintains Map<sandboxId, NodeJS.Timeout> for timers
- Wrapper exposes getInfo(), betaPause(), resume() methods
- reconnectSandbox(): Cancel timer + check/resume paused sandboxes
- release(): Set auto-pause timer after returning to pool
- autoPauseSandbox(): Best-effort pause with error logging

**Trade-offs**:
- Simple approach: Uses setTimeout (lost on process restart)
- Acceptable: Process restart is low-frequency
- Fallback: New process will eventually pause idle sandboxes
- Worst case: Sandbox stays running → controlled cost increase, no performance impact

**Benefits**:
✅ Quick reuse: <10min window stays running (fast)
✅ Cost savings: Long idle sandboxes paused
✅ Automatic: No manual intervention needed
✅ Resilient: Resume on demand if paused

* fix: use type assertion for sandbox.resume() API

SDK type definition missing, but API exists in runtime

* feat: optimize auto-pause with state tracking and remove redundant health checks

Performance optimizations for sandbox auto-pause mechanism:

1. Add pause state tracking to prevent frequent reconnect cycles
   - Add isPaused and lastPausedAt fields to SandboxMetadata
   - Implement markAsPaused() and markAsRunning() methods in SandboxWrapper
   - Check metadata.isPaused in tryAutoPause() to skip if already paused
   - Update pause state in metadata after SDK auto-resume on reconnect
   - Reduces unnecessary reconnect→resume→pause cycles from setTimeout callbacks

2. Remove redundant health check logic
   - Remove isHealthy() method with dual checks (isRunning + getInfo)
   - Remove health check retry in reconnect() - trust SDK's connect() guarantee
   - Remove health check retry in tryReturnToIdle() - trust execution flow
   - Remove HEALTH_CHECK_RETRY_CONFIG constant
   - Remove SandboxHealthCheckFailedException
   - Reduces latency by eliminating 5s retry timeouts

3. Clean up unused code
   - Remove unused maxSandboxes config and SCALEBOX_DEFAULT_MAX_SANDBOXES import
   - Add inline comment for @Config decorator dependency on ConfigService

Benefits:
- Auto-pause frequency significantly reduced (acceptable race condition overflow)
- Faster reconnection without health check delays
- Simpler code that trusts SDK guarantees
- Better resource utilization with metadata-based state tracking

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* chore(sandbox): add prisma script

* feat(sandbox): optimize log message report

* wip(sandbox): scalebox performance optimization and observability

Major improvements to sandbox system:
- Lock configuration refactoring with reverse calculation from runCodeTimeout
- Extract lock logic to dedicated scalebox.lock.ts module
- Implement SDK timeout and critical error detection
- Add observability stack (Grafana, Loki, Tempo)
- Optimize file registration and pool management
- Update configuration system with validation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* wip(sandbox): config flattening, lock simplification, s3 credential security

- Flatten app.config.ts structure, add Ms/Sec suffixes to time params
- Constants renamed to SCREAMING_SNAKE_CASE
- Lock service simplified: inline TTL/timeout calculation (300→107 lines)
- S3 mount uses passwd_file with subshell cleanup pattern
- Extract acquireQueueEvents, add ExecuteCodeContext interface

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* wip(sandbox): auto-pause via BullMQ delayed jobs

- Add QUEUE_SCALEBOX_EXECUTE / QUEUE_SCALEBOX_PAUSE queues
- Implement schedulePause/cancelPause in SandboxPool
- Merge processors: ScaleboxExecuteProcessor + ScaleboxPauseProcessor
- Remove deprecated timeout param from SandboxExecuteParams

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* wip(sandbox): fix BullMQ concurrency and optimize logging

- Fix: @Processor decorator concurrency now uses SCALEBOX_DEFAULTS.LOCAL_CONCURRENCY
  (getWorkerOptions() is not supported by @nestjs/bullmq)
- Remove localConcurrency from runtime config (compile-time constant only)
- Add phase field to key logs for filtering (lock/acquire/execute/release/pause/complete)
- Use logger.assign() for automatic canvasId/sandboxId/jobId injection
- Use storage.run() for AsyncLocalStorage context in BullMQ workers

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* wip(sandbox): sandbox lock TTL fix and code cleanup

- Fix sandbox lock leakage: replace ACTIVE_SET with TTL-based individual keys
- Add ScaleboxResponseFactory for unified response building
- Remove setSpanAttributes (to be added later as needed)
- Merge mkdir into mountS3 command to reduce round-trips
- QueueEvents singleton lifecycle management

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* wip(sandbox): enhance error logging and tracing

- Add try-catch in processor to log full error before re-throwing to BullMQ
- Add warn logs in wrapper for SDK failures (runCommand, executeCode, listCwdFiles)
- Add SandboxRunCodeException for runCode SDK errors
- Enable SandboxFileListException for files.list errors
- Set logger context to SandboxWrapper in constructor
- Remove redundant context fields from log statements

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* feat(sandbox): lock auto-renewal, error classification, and config simplification

Lock mechanism improvements:
- Short initial TTL (10s) with periodic renewal (3s)
- UUID-based lock ownership to prevent accidental release
- Lua scripts for atomic renewal and release operations
- Simplified lock wait timeout config (LOCK_WAIT_TIMEOUT_SEC: 60s)

Error classification enhancements:
- Distinguish code_error (exitCode!=0) from system_error (infrastructure)
- Detect transient errors: timeout, gRPC UNAVAILABLE/CANCELLED
- User-friendly error messages for model consumption

Configuration cleanup:
- Remove FILE_BUFFER_SEC, DRIVE_BUFFER_SEC, QUEUE_DEPTH
- Add LOCK_WAIT_TIMEOUT_SEC for direct timeout config
- Adjust defaults: MAX_SANDBOXES=10, LOCAL_CONCURRENCY=5

Guard utility:
- Add retryIf option for conditional retry logic

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* chore(sandbox): update .env and config variables for scalebox service.

* feat(prompt): rewrite node-agent system prompt

- Define clear identity as Refly.ai Node Agent for vibe workflow
- Add two-level agent architecture (Copilot vs Node Agent)
- Introduce ReAct with Silent Execution behavior mode
- Document builtin tools with latency and usage patterns
- Clarify fileId vs fileName for different tools
- Add override rules for user customization

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* feat: builtin toolset optimization

* fix: fallback to null when URL constructor fail

* feat(sandbox): upgrade sdk version

* fix(sandbox): optimize 503 error

* WIP: optimize agent system prompts

- node-agent: add <tool_decision> XML tag, restructure builtin tools with Use when/NOT for patterns
- copilot-agent: add <task_splitting> and <task_patterns> for workflow design guidance

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* WIP: refactor copilot-agent example with Warren Buffett analysis

- Replace minimal example with comprehensive investment analysis example
- Add Design Thinking & Decisions format for decision reasoning
- Remove .txt filename hints to avoid redundant format descriptions
- Change to sequential execution for weak model compatibility
- Add Get Time + Data pattern for implicit parameter resolution
- Add execute_code constraint for file path requirements

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* feat(agent): optimize system prompts for better tool selection

- Rewrite tool-product mapping with clear selection rules
- Add tool constraints (execute_code file paths, web_search scope)
- Optimize Jina tool descriptions (read/serp differentiation)
- Add best-effort delivery guideline to node-agent
- Remove auto-inject logic in normalizeWorkflowPlan
- Remove unused docker trace configurations

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* feat(agent): use semantic time identification over date range resolution

Change example prompts from "Resolve X to date range" to "Identify X"
to reduce model tendency to over-engineer time parsing with execute_code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* WIP: migrate to refly-executor-slim custom template

- Migrate from code-interpreter to refly-executor-slim-v0-2-3 template
- Simplify language support to python, javascript, shell only
- Remove S3 mount/unmount logic (handled by executor FUSE)
- Remove file diff tracking (executor returns diff.added)
- Add large code path mode support (64KB threshold)
- Add resource limits configuration (maxFileSize, maxTotalWrite, etc.)
- Simplify scalebox service from 3-layer to 2-layer architecture

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* WIP: fix InterpreterWrapper s3fs mount issues

- Add -o compat_dir option to allow mounting non-existent S3 paths
- Add mountpoint verification after s3fs daemon initialization
- Pass ctx.logger to runCommand/acquireDriveMount for proper log context
- Improve mount command with explicit error handling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

* feat(sandbox): refactor wrapper lifecycle and add idle queue TTL

- Extract BaseSandboxWrapper abstract class with shared state management
- Add lifecycle utilities (createSandbox, connectSandbox, ensureHealthy, withLifecycleRetry)
- Add SandboxLifecycleException for unified lifecycle error handling
- Add idle queue TTL with auto-refresh on push/pop (3x sandboxTimeoutMs)
- Change default wrapperType to 'interpreter' for open source compatibility
- Move WrapperType and DEFAULT_WRAPPER_TYPE to constants
- Increase global AbortSignal listener limit to avoid LLM request warnings

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <[email protected]>

---------

Co-authored-by: HanYuanxi <[email protected]>
Co-authored-by: Claude <[email protected]>

* fix: restore action polling for status sync fallback (#1707)

* fix: restore action polling for status sync fallback

- Updated MessageList component to enhance styling with Tailwind CSS, adjusting padding for better layout.
- Refactored useActionPolling hook to streamline polling logic by removing unnecessary checks and improving state management.
- Enhanced useInvokeAction hook to include a timeout handler for better event management and prevent potential memory leaks.
- Added utility function to validate non-empty events in useUpdateActionResult for improved stream handling.

* fix: enable message update in non-streaming mode

- Updated useActionPolling hook to include streaming result checks, improving state management.
- Added logic to update local results only when not streaming, ensuring accurate polling behavior.
- Utilized optional chaining and nullish coalescing for safer property access.

* feat: add RightOutlined icon to InvitationItem component (#1709)

- Imported RightOutlined from Ant Design icons for enhanced visual indication in the InvitationItem component.
- Updated the rendering logic to replace the previous text indicator with the new icon, improving user experience and visual consistency.
- Ensured compliance with Tailwind CSS styling standards.

* feat: enhance agent nodes and reasoning content display (#1710)

refactor: enhance SkillResponseNode and ReasoningContentPreview components

- Updated SkillResponseNode to conditionally render SkillResponseActions based on hover and selection state.
- Refactored ReasoningContentPreview to improve state management and styling with Tailwind CSS.
- Introduced new icons and adjusted button functionalities in SkillResponseActions for better user interaction.
- Ensured proper use of optional chaining and nullish coalescing for safer property access throughout the components.

* feat: update workflow publish translations (#1708)

* feat(workflow-app): add i18n for run result and danger color for empty state

* feat(workflow-app): add i18n for run result and danger color for empty state

* feat: add message truncation to avoid overloading context window (#1711)

* fix: handle optional chaining for subscription check

refactor: update file filtering logic to exclude variables

* feat(agent): add smart tool result truncation based on context usage

Implement tool result truncation that considers context window usage and model configuration. The truncation strategy varies based on current token usage ratio (safe/warning/danger zones) and preserves JSON structure when possible. Logs truncation details when applied.

* feat: Centralize context window management by implementing message list truncation and removing the dedicated tool result truncator.

* refactor: Revise message truncation strategy to keep message head/tail and simplify message selection.

* feat: Add message truncation logic and debug output for large prompts.

* feat: Introduce debug truncation files and refine prompt context, message, and token utilities.

* fix: Preserve tool calls and additional kwargs when truncating AI messages.

* fix: prevent system message from being included as the last user message and add debug truncation files.

* chore: Remove message length warning and add debug truncation files.

* feat: add onboarding forms (#1712)

* Revert "refactor(form): remove form-related components and API endpoints"

This reverts commit ae644bfb270e23961e131e208d0a5a6b7f0376c5.

* refactor: remove unused GenerateInvitationCode mutation and related code

- Eliminated the GenerateInvitationCode mutation and its associated key function from common queries to streamline the codebase.
- Updated comments in ActionResult type to clarify default errorType behavior.
- Ensured adherence to best practices for property access and code clarity.

* fix: update form component styles and schema options for better user experience

- Adjusted the dimensions of the ReflyRjsfForm component to improve layout consistency.
- Updated schema options to enhance clarity and user engagement, including renaming and adding new options.
- Improved the handling of enum values in schema properties to ensure robust data validation.
- Enhanced styling of buttons and input fields using Tailwind CSS for a more polished appearance.
- Applied optional chaining and nullish coalescing for safer property access throughout the codebase.

* feat: add onboarding form modal and integrate form definition retrieval

- Introduced FormOnboardingModal component to facilitate user onboarding with a dynamic form.
- Implemented form definition retrieval using the useGetFormDefinition hook for loading form schemas.
- Enhanced user experience by managing modal visibility through user store state.
- Applied Tailwind CSS for consistent styling and layout.
- Ensured safe property access with optional chaining and nullish coalescing throughout the implementation.

* feat: enhance ObjectFieldTemplate with form submission functionality

- Integrated useSubmitForm hook to manage form submission within the ObjectFieldTemplate component.
- Updated button states to reflect submission status and prevent multiple submissions.
- Improved user experience by renaming button texts to English and ensuring safe property access with optional chaining and nullish coalescing.
- Applied Tailwind CSS for consistent styling across the component.

* feat: add SVG assets and enhance subscription component styling

- Introduced new SVG assets for commission and regular icons to improve visual representation in the subscription component.
- Enhanced the subscription component's layout and styling with Tailwind CSS for better user experience.
- Added a usage section wrapper and available credits section to display credit information clearly.
- Updated translations for consistency in terminology across the application.

* feat: integrate SettingItem component across multiple areas and enhance user experience

- Added SettingItem component to AppManager, TopToolbar, WorkflowList, and FrontPage for consistent user settings access.
- Updated ContactUsPopover to utilize CommunityLinkCard for improved community engagement options.
- Enhanced layout and styling with Tailwind CSS for better visual consistency.
- Applied optional chaining and nullish coalescing for safer property access throughout the codebase.
- Updated translations for clarity and consistency in terminology.

* feat: add EndMessage component to TemplateList for Discord community engagement

- Introduced a new EndMessage component to encourage users to join the Discord community.
- Utilized React.memo for performance optimization and wrapped the button click handler with useCallback.
- Updated translations for the new EndMessage content in both English and Chinese.
- Ensured adherence to Tailwind CSS for consistent styling across the component.

* feat: update invitation modal and translations for enhanced user engagement

- Modified the invitation code text in the InvitationModal to better reflect the platform's offerings.
- Updated the success message for activating the invitation code in both English and Chinese to align with the new messaging.
- Ensured adherence to Tailwind CSS for consistent styling across components.
- Applied optional chaining and nullish coalescing for safer property access.

* feat: implement hasFilledForm feature for user onboarding

- Added a new endpoint to check if the user has filled the onboarding form.
- Updated the FormService to manage user preferences related to form completion.
- Integrated hasFilledForm functionality into the FormController and corresponding API response.
- Enhanced user experience by conditionally displaying the onboarding form modal based on invitation status and form completion.
- Ensured adherence to Tailwind CSS for consistent styling across components.
- Applied optional chaining and nullish coalescing for safer property access throughout the codebase.

* feat: limit template retrieval and update EndMessage for marketplace engagement

- Updated the template retrieval logic to limit the number of templates to a maximum of 12.
- Modified the EndMessage component to redirect users to the marketplace instead of Discord.
- Updated translations for the new marketplace messaging in both English and Chinese.
- Ensured adherence to Tailwind CSS for consistent styling across components.
- Applied optional chaining and nullish coalescing for safer property access throughout the codebase.

* feat: update EndMessage component to use Ant Design Button and enhance styling

- Replaced the native button with Ant Design's Button component for improved styling and consistency.
- Updated the button's properties to align with Tailwind CSS standards.
- Ensured the EndMessage component maintains its functionality while enhancing user engagement with the marketplace.
- Continued adherence to performance optimization practices by using React.memo.

* chore: update pnpm-lock.yaml to reflect dependency changes

* refactor(template-list): update button type and styling for improved UI consistency

* chore: update Discord community link across documentation and components

* feat: integrate i18n support for form buttons and update styling

- Added translation support for form button texts (previous, next, submit, submitting) using `react-i18next`.
- Updated button styles to use transparent backgrounds for improved UI consistency.
- Adjusted component structure to enhance maintainability and performance.

* feat: add success message for form submission and update translations

- Integrated a success message using Ant Design's message component upon successful form submission.
- Added English and Chinese translations for the new success message to enhance user feedback.

* fix: update CheckboxesWidget styling for improved UI consistency

- Changed the background of the CheckboxesWidget input to transparent for better visual integration with the overall theme.

* feat: enhance credit deduction and workflow management

- Updated `deductCreditsAndCreateUsage` to return a boolean indicating if the balance is zero or if debt was created.
- Modified `syncBatchTokenCreditUsage` to handle the new return value from credit deduction.
- Implemented `abortWorkflowExecution` in `SkillInvokerService` to manage workflow aborts when credits are insufficient.
- Refactored `WorkflowService` to utilize the new abort functionality, improving error handling during credit usage.
- Ensured proper validation and logging throughout the new workflow management processes.

* feat: add CreditPackPlan model and implement createCreditPackSession endpoint

- Introduced CreditPackPlan model in Prisma schema to manage credit pack details.
- Enhanced CreditService with createCreditPackRecharge method for processing credit pack purchases.
- Implemented createCreditPackSession endpoint in SubscriptionController to initiate credit pack checkout sessions.
- Updated SubscriptionService to handle credit pack session creation and integrate with Stripe for payment processing.
- Added necessary types and queries for credit pack session handling in the common and request modules.
- Updated OpenAPI schema to include new endpoint for credit pack session creation.

* feat: add Plus subscription plan and loading state to PriceContent component

- Introduced a new Plus subscription plan with pricing details and features.
- Updated PriceContent component to handle loading state with a spinner and appropriate styles.
- Enhanced SCSS for subscribe button to reflect loading state visually.
- Updated translation files to include new keys for Plus plan in both English and Chinese.
- Modified OpenAPI schema and types to accommodate the new subscription plan.

* feat: add publishToCommunity and publishReviewStatus fields to WorkflowApp schema

- Introduced new optional fields `publishToCommunity` and `publishReviewStatus` in the WorkflowApp schema and type definitions.
- Updated OpenAPI schema to reflect these changes, enhancing the API's capability to manage community publishing features.

* feat: implement credit pack checkout session functionality

- Added `creditPackExpiresInDays` configuration to app settings with a default value of 90 days.
- Introduced `createCreditPackCheckoutSession` method in the SubscriptionService to handle credit pack purchases.
- Updated SubscriptionController to rename the endpoint to `/createCreditPackCheckoutSession` and adjusted the service call accordingly.
- Enhanced the PriceContent component to include a new section for displaying credit packs with their respective titles, descriptions, prices, and credits.
- Implemented loading state management for credit pack purchases and ensured proper handling of user login state.
- Updated translations for credit pack titles and descriptions in both English and Chinese.
- Modified OpenAPI schema to reflect the new checkout session endpoint for credit packs.

* feat: add onboarding success animation state and modal

- Added `showOnboardingSuccessAnimation` state to the user store for managing onboarding success animations.
- Updated `ObjectFieldTemplate` to trigger the onboarding success animation upon successful form submission.
- Integrated `OnboardingSuccessModal` into the `AppLayout` for displaying the success message to users.

* refactor: update priceContent and onboarding success modal

- Simplified plan types in PriceContent component to only include 'free' and 'plus'.
- Updated translations for 'plus' plan features in both English and Chinese.
- Removed unused Lottie animation file and replaced it with a custom confetti animation in OnboardingSuccessModal.
- Enhanced OnboardingSuccessModal to include confetti animation upon successful onboarding, improving user experience.

* refactor(OnboardingSuccessModal): optimize component structure and enhance functionality

- Refactored OnboardingSuccessModal to include a handleClose function wrapped in useCallback for better performance.
- Added useTranslation for internationalization support in the modal.
- Improved cleanup logic for style elements to prevent memory leaks.
- Updated modal styling using Tailwind CSS for a more modern look and feel.
- Ensured proper handling of optional chaining and nullish coalescing for better code safety.

* feat(i18n): add onboarding translations for English and Chinese

- Introduced new onboarding translations for 'Reward Credits', '3000 credits', and 'Start Now' in both English and Chinese.
- Updated OnboardingSuccessModal to utilize the new translations, enhancing internationalization support.

* fix(OnboardingSuccessModal): update comment for clarity

- Changed comment from Chinese to English for better understanding of the code.
- Ensured consistency in code documentation to enhance maintainability.

* refactor(credit): enhance credit handling and error messaging

- Introduced a new variable to track total new balance during credit deductions.
- Updated the logic for returning credit transaction results to improve clarity on balance status.
- Enhanced error handling for credit-related issues, preserving original error messages for better user feedback.
- Added checks for credit billing processing after skill completion to ensure accurate billing.
- Updated data structures to include error messages and app IDs for better tracking and debugging.
- Improved the user experience by integrating a modal for insufficient credit notifications across various components.

* fix(sitemap): update lastmod dates to reflect new changes

- Updated the lastmod date for multiple URLs in sitemap and sitemap-templates to 2025-12-02 for consistency and accuracy.

* feat: add 2000 credit gift for first-time subscription

- Add genFirstSubscriptionGiftRechargeId function in utils/id.ts
- Add createFirstSubscriptionGiftRecharge method in credit.service.ts
- Add first subscription gift logic in subscription.service.ts

* feat: enhance subscription and credit features

- Added first subscription gift credit amount and expiration settings in app.config.ts.
- Updated CreditService to utilize new configuration for first subscription gift credit.
- Improved SubscriptionService to include logic for fetching existing user subscriptions.
- Refactored PriceContent component to optimize rendering and structure, including new PriceOption and FeatureItem components.
- Enhanced CreditInsufficientModal to handle credit pack options and subscription plans more effectively, improving user experience.
- Applied performance optimizations using React.memo and useCallback for better rendering efficiency.

* feat: add telemetry logging for user interactions

- Integrated telemetry logging in CopilotMessage component to track approval clicks.
- Added logging for sent prompts in ChatActions component.
- Implemented logging for successful invitation code activation in ActivationCodeInput component.

* refactor: update logging methods in SkillInvokerService and adjust sitemap lastmod dates

- Changed logger methods from `log` to `info` in SkillInvokerService for improved log level clarity.
- Updated `lastmod` dates in sitemap templates and main sitemap to reflect the new date of 2025-12-03.
- Enhanced code readability and maintainability by ensuring consistent logging practices.

* feat: enhance logging and event tracking in PriceContent and CreditInsufficientModal components

- Added useEffect hooks to log pricing view and insufficient credit popup view events, improving user interaction tracking.
- Updated popup type determination logic in CreditInsufficientModal for better clarity on displayed options.
- Ensured compliance with performance optimization practices by utilizing useMemo and proper dependency arrays.

* refactor: remove CreditPackPlan model and related checkout session logic

- Deleted the CreditPackPlan model from the Prisma schema to streamline the database structure.
- Removed the createCreditPackCheckoutSession method from SubscriptionService, along with its associated logic for handling credit pack purchases.
- Updated SubscriptionController to eliminate the endpoint for creating credit pack checkout sessions.
- Adjusted SubscriptionWebhooks to focus solely on subscription-related logic, removing credit pack handling.
- Refactored workflow execution methods in WorkflowService for improved clarity and maintainability.

* refactor: remove CreditInsufficientModal and related logic

- Deleted the CreditInsufficientModal component to streamline the subscription flow.
- Removed associated state management and modal visibility logic from the subscription store.
- Updated hooks and components to eliminate references to the CreditInsufficientModal, ensuring cleaner code and improved maintainability.
- Adjusted related components and hooks to comply with performance optimization practices.

* feat: enhance loading and error handling in FormOnboardingModal

- Replaced loading text with a spinner component for better user experience during form definition loading.
- Improved error display by adding an error icon and adjusting the message layout when form definition fails to load.
- Ensured compliance with Tailwind CSS styling standards and optimized component rendering.

* feat: enhance toolset display with multi-language translations (#1715)

* fix(tool): filter out internal toolsets and enhance toolset mapping

- Updated the `listBuiltinTools` method to filter out internal toolsets based on the `internal` property in the toolset definitions, improving the clarity of the toolset inventory.
- Ensured consistent use of optional chaining and nullish coalescing for safer property access throughout the method.
- Added new builtin toolsets for Get Time, Read File, and Execute Code to the inventory, enhancing the available toolset options.

* fix(mention-list): update styling and translation for unauthorized message

- Increased width of the mention list for better visibility.
- Adjusted font size of the unauthorized message for improved readability.
- Updated translation for the unauthorized message from 'Auth' to 'unauthorized' for clarity.

* fix(toolset): enhance toolset definition usage for improved localization

- Integrated the useToolsetDefinition hook across multiple components to access complete toolset definition data.
- Updated toolset item mapping to prioritize inventory definitions for better localized labels and descriptions.
- Ensured consistent use of optional chaining and nullish coalescing for safer property access throughout the components.
- Improved rendering logic for toolsets and tools to enhance clarity and maintainability.

* WIP: toolset processing in query

* refactor(query-processor): integrate processQuery function across components

- Replaced instances of processQueryWithMentions with the new processQuery function from the useQueryProcessor hook for improved query processing consistency.
- Updated components to utilize the new query processing logic, ensuring optional chaining and nullish coalescing are applied for safer property access.
- Enhanced overall code maintainability by centralizing query processing logic in the useQueryProcessor hook.

* style(model-selector): refine layout and remove unnecessary margin

- Adjusted the ModelSelector component's layout by removing the margin from the droplist container for a cleaner appearance.
- Ensured compliance with Tailwind CSS styling standards for improved visual consistency.

* feat(workflow): integrate ToolModule and enhance toolset definition handling

- Added ToolModule to the WorkflowModule for improved tool management.
- Enhanced WorkflowService with a new method to build a lookup for toolset definitions by user ID, ensuring safe property access with optional chaining and nullish coalescing.
- Updated prepareNodeExecutions to utilize the new lookup function, improving toolset integration in workflow execution.
- Ensured array checks and object property validations are in place for better reliability and maintainability.

* feat: optimize toolset popover for tool definition

- Removed unnecessary console log from ChatComposerComponent for cleaner code.
- Enhanced ToolsetPopover by integrating useMemo and useCallback for improved performance.
- Implemented optional chaining and nullish coalescing for safer property access in toolset mapping.
- Updated rendering logic to utilize enriched toolsets, ensuring better localization and clarity.
- Ensured compliance with Tailwind CSS styling standards throughout the components.

* feat: add new background color variable and update styling in mention list

- Introduced 'refly-bg-control-z2' color variable for enhanced theming.
- Updated mention list component to improve layout and styling, including increased width and adjusted padding.
- Enhanced rendering logic to utilize optional chaining for safer property access and improved readability.
- Updated translation for unauthorized message to 'Unauthorize' for better clarity.
- Ensured compliance with Tailwind CSS styling standards throughout the components.

* feat: enhance workflow handling in canvas and copy-paste functionality

- Integrated workflow state checks in Flow component to disable delete key functionality when a workflow is running.
- Updated useCopyPasteSkillResponseNode hook to prevent copy and paste actions during workflow execution.
- Ensured compliance with optional chaining and nullish coalescing for safer property access.
- Maintained Tailwind CSS styling standards throughout the components.

* fix: correct translation for unauthorized message in i18n

- Updated the translation for the unauthorized message from 'Unauthorize' to 'Unauthorized' for better clarity and consistency.
- Ensured compliance with Tailwind CSS styling standards throughout the components.

* fix: update translation for unauthorized message in i18n

- Changed the translation for the unauthorized message from 'Unauthorized' to 'Authorize' for improved clarity.
- Ensured compliance with Tailwind CSS styling standards throughout the components.

* fix: update text color in mention list based on installation status

- Changed text color for uninstalled items in the mention list from 'text-refly-text-2' to 'text-refly-text-3' for better visibility.
- Updated description text color logic to ensure consistent styling based on installation status.
- Ensured compliance with Tailwind CSS styling standards throughout the component.

---------

Co-authored-by: mrcfps <[email protected]>

* feat: Add workflow generation API (#1714)

copilot autogen

* fix: remove unused schemas and update placeholder text (#1718)

* Revert "refactor(form): remove form-related components and API endpoints"

This reverts commit ae644bfb270e23961e131e208d0a5a6b7f0376c5.

* refactor: remove unused GenerateInvitationCode mutation and related code

- Eliminated the GenerateInvitationCode mutation and its associated key function from common queries to streamline the codebase.
- Updated comments in ActionResult type to clarify default errorType behavior.
- Ensured adherence to best practices for property access and code clarity.

* fix: update form component styles and schema options for better user experience

- Adjusted the dimensions of the ReflyRjsfForm component to improve layout consistency.
- Updated schema options to enhance clarity and user engagement, including renaming and adding new options.
- Improved the handling of enum values in schema properties to ensure robust data validation.
- Enhanced styling of buttons and input fields using Tailwind CSS for a more polished appearance.
- Applied optional chaining and nullish coalescing for safer property access throughout the codebase.

* feat: add onboarding form modal and integrate form definition retrieval

- Introduced FormOnboardingModal component to facilitate user onboarding with a dynamic form.
- Implemented form definition retrieval using the useGetFormDefinition hook for loading form schemas.
- Enhanced user experience by managing modal visibility through user store state.
- Applied Tailwind CSS for consistent styling and layout.
- Ensured safe property access with optional chaining and nullish coalescing throughout the implementation.

* feat: enhance ObjectFieldTemplate with form submission functionality

- Integrated useSubmitForm hook to manage form submission within the ObjectFieldTemplate component.
- Updated button states to reflect submission status and prevent multiple submissions.
- Improved user experience by renaming button texts to English and ensuring safe property access with optional chaining and nullish coalescing.
- Applied Tailwind CSS for consistent styling across the component.

* feat: add SVG assets and enhance subscription component styling

- Introduced new SVG assets for commission and regular icons to improve visual representation in the subscription component.
- Enhanced the subscription component's layout and styling with Tailwind CSS for better user experience.
- Added a usage section wrapper and available credits section to display credit information clearly.
- Updated translations for consistency in terminology across the application.

* feat: integrate SettingItem component across multiple areas and enhance user experience

- Added SettingItem component to AppManager, TopToolbar, WorkflowList, and FrontPage for consistent user settings access.
- Updated ContactUsPopover to utilize CommunityLinkCard for improved community engagement options.
- Enhanced layout and styling with Tailwind CSS for better visual consistency.
- Applied optional chaining and nullish coalescing for safer property access throughout the codebase.
- Updated translations for clarity and consistency in terminology.

* feat: add EndMessage component to TemplateList for Discord community engagement

- Introduced a new EndMessage component to encourage users to join the Discord community.
- Utilized React.memo for performance optimization and wrapped the button click handler with useCallback.
- Updated translations for the new EndMessage content in both English and Chinese.
- Ensured adherence to Tailwind CSS for consistent styling across the component.

* feat: update invitation modal and translations for enhanced user engagement

- Modified the invitation code text in the InvitationModal to better reflect the platform's offerings.
- Updated the success message for activating the invitation code in both English and Chinese to align with the new messaging.
- Ensured adherence to Tailwind CSS for consistent styling across components.
- Applied optional chaining and nullish coalescing for safer property access.

* feat: implement hasFilledForm feature for user onboarding

- Added a new endpoint to check if the user has filled the onboarding form.
- Updated the FormService to manage user preferences related to form completion.
- Integrated hasFilledForm functionality into the FormController and corresponding API response.
- Enhanced user experience by conditionally displaying the onboarding form modal based on invitation status and form completion.
- Ensured adherence to Tailwind CSS for consistent styling across components.
- Applied optional chaining and nullish coalescing for safer property access throughout the codebase.

* feat: limit template retrieval and update EndMessage for marketplace engagement

- Updated the template retrieval logic to limit the number of templates to a maximum of 12.
- Modified the EndMessage component to redirect users to the marketplace instead of Discord.
- Updated translations for the new marketplace messaging in both English and Chinese.
- Ensured adherence to Tailwind CSS for consistent styling across components.
- Applied optional chaining and nullish coalescing for safer property access throughout the codebase.

* feat: update EndMessage component to use Ant Design Button and enhance styling

- Replaced the native button with Ant Design's Button component for improved styling and consistency.
- Updated the button's properties to align with Tailwind CSS standards.
- Ensured the EndMessage component maintains its functionality while enhancing user engagement with the marketplace.
- Continued adherence to performance optimization practices by using React.memo.

* chore: update pnpm-lock.yaml to reflect dependency changes

* refactor(template-list): update button type and styling for improved UI consistency

* chore: update Discord community link across documentation and components

* feat: integrate i18n support for form buttons and update styling

- Added translation support for form button texts (previous, next, submit, submitting) using `react-i18next`.
- Updated button styles to use transparent backgrounds for improved UI consistency.
- Adjusted component structure to enhance maintainability and performance.

* feat: add success message for form submission and update translations

- Integrated a success message using Ant Design's message component upon successful form submission.
- Added English and Chinese translations for the new success message to enhance user feedback.

* fix: update CheckboxesWidget styling for improved UI consistency

- Changed the background of the CheckboxesWidget input to transparent for better visual integration with the overall theme.

* feat: enhance credit deduction and workflow management

- Updated `deductCreditsAndCreateUsage` to return a boolean indicating if the balance is zero or if debt was created.
- Modified `syncBatchTokenCreditUsage` to handle the new return value from credit deduction.
- Implemented `abortWorkflowExecution` in `SkillInvokerService` to manage workflow aborts when credits are insufficient.
- Refactored `WorkflowService` to utilize the new abort functionality, improving error handling during credit usage.
- Ensured proper validation and logging throughout the new workflow management processes.

* feat: add CreditPackPlan model and implement createCreditPackSession endpoint

- Introduced CreditPackPlan model in Prisma schema to manage credit pack details.
- Enhanced CreditService with createCreditPackRecharge method for processing credit pack purchases.
- Implemented createCreditPackSession endpoint in SubscriptionController to initiate credit pack checkout sessions.
- Updated SubscriptionService to handle credit pack session creation and integrate with Stripe for payment processing.
- Added necessary types and queries for credit pack session handling in the common and request modules.
- Updated OpenAPI schema to include new endpoint for credit pack session creation.

* feat: add Plus subscription plan and loading state to PriceContent component

- Introduced a new Plus subscription plan with pricing details and features.
- Updated PriceContent component to handle loading state with a spinner and appropriate styles.
- Enhanced SCSS for subscribe button to reflect loading state visually.
- Updated translation files to include new keys for Plus plan in both English and Chinese.
- Modified OpenAPI schema and types to accommodate the new subscription plan.

* feat: add publishToCommunity and publishReviewStatus fields to WorkflowApp schema

- Introduced new optional fields `publishToCommunity` and `publishReviewStatus` in the WorkflowApp schema and type definitions.
- Updated OpenAPI schema to reflect these changes, enhancing the API's capability to manage community publishing features.

* feat: implement credit pack checkout session functionality

- Added `creditPackExpiresInDays` configuration to app settings with a default value of 90 days.
- Introduced `createCreditPackCheckoutSession` method in the SubscriptionService to handle credit pack purchases.
- Updated SubscriptionController to rename the endpoint to `/createCreditPackCheckoutSession` and adjusted the service call accordingly.
- Enhanced the PriceContent component to include a new section for displaying credit packs with their respective titles, descriptions, prices, and credits.
- Implemented loading state management for credit pack purchases and ensured proper handling of user login state.
- Updated translations for credit pack titles and descriptions in both English and Chinese.
- Modified OpenAPI schema to reflect the new checkout session endpoint for credit packs.

* feat: add onboarding success animation state and modal

- Added `showOnboardingSuccessAnimation` state to the user store for managing onboarding success animations.
- Updated `ObjectFieldTemplate` to trigger the onboarding success animation upon successful form submission.
- Integrated `OnboardingSuccessModal` into the `AppLayout` for displaying the success message to users.

* refactor: update priceContent and onboarding success modal

- Simplified plan types in PriceContent component to only include 'free' and 'plus'.
- Updated translations for 'plus' plan features in both English and Chinese.
- Removed unused Lottie animation file and replaced it with a custom confetti animation in OnboardingSuccessModal.
- Enhanced OnboardingSuccessModal to include confetti animation upon successful onboarding, improving user experience.

* refactor(OnboardingSuccessModal): optimize component structure and enhance functionality

- Refactored OnboardingSuccessModal to include a handleClose function wrapped in useCallback for better performance.
- Added useTranslation for internationalization support in the modal.
- Improved cleanup logic for style elements to prevent memory leaks.
- Updated modal styling using Tailwind CSS for a more modern look and feel.
- Ensured proper handling of optional chaining and nullish coalescing for better code safety.

* feat(i18n): add onboarding translations for English and Chinese

- Introduced new onboarding translations for 'Reward Credits', '3000 credits', and 'Start Now' in both English and Chinese.
- Updated OnboardingSuccessModal to utilize the new translations, enhancing internationalization support.

* fix(OnboardingSuccessModal): update comment for clarity

- Changed comment from Chinese to English for better understanding of the code.
- Ensured consistency in code documentation to enhance maintainability.

* refactor(credit): enhance credit handling and error messaging

- Introduced a new variable to track total new balance during credit deductions.
- Updated the logic for returning credit transaction results to improve clarity on balance status.
- Enhanced error handling for credit-related issues, preserving original error messages for better user feedback.
- Added checks for credit billing processing after skill completion to ensure accurate billing.
- Updated data structures to include error messages and app IDs for better tracking and debugging.
- Improved the user experience by integrating a modal for insufficient credit notifications across various components.

* fix(sitemap): update lastmod dates to reflect new changes

- Updated the lastmod date for multiple URLs in sitemap and sitemap-templates to 2025-12-02 for consistency and accuracy.

* feat: add 2000 credit gift for first-time subscription

- Add genFirstSubscriptionGiftRechargeId function in utils/id.ts
- Add createFirstSubscriptionGiftRecharge method in credit.service.ts
- Add first subscription gift logic in subscription.service.ts

* feat: enhance subscription and credit features

- Added first subscription gift credit amount and expiration settings in app.config.ts.
- Updated CreditService to utilize new configuration for first subscription gift credit.
- Improved SubscriptionService to include logic for fetching existing user subscriptions.
- Refactored PriceContent component to optimize rendering and structure, including new PriceOption and FeatureItem components.
- Enhanced CreditInsufficientModal to handle credit pack options and subscription plans more effectively, improving user experience.
- Applied performance optimizations using React.memo and useCallback for better rendering efficiency.

* feat: add telemetry logging for user interactions

- Integrated telemetry logging in CopilotMessage component to track approval clicks.
- Added logging for sent prompts in ChatActions component.
- Implemented logging for successful invitation code activation in ActivationCodeInput component.

* refactor: update logging methods in SkillInvokerService and adjust sitemap lastmod dates

- Changed logger methods from `log` to `info` in SkillInvokerService for improved log level clarity.
- Updated `lastmod` dates in sitemap templates and main sitemap to reflect the new date of 2025-12-03.
- Enhanced code readability and maintainability by ensuring consistent logging practices.

* feat: enhance logging and event tracking in PriceContent and CreditInsufficientModal components

- Added useEffect hooks to log pricing view and insufficient credit popup view events, improving user interaction tracking.
- Updated popup type determination logic in CreditInsufficientModal for better clarity on displayed options.
- Ensured compliance with performance optimization practices by utilizing useMemo and proper dependency arrays.

* refactor: remove CreditPackPlan model and related checkout session logic

- Deleted the CreditPackPlan model from the Prisma schema to streamline the database structure.
- Removed the createCreditPackCheckoutSession method from SubscriptionService, along with its associated logic for handling credit pack purchases.
- Updated SubscriptionController to eliminate the endpoint for creating credit pack checkout sessions.
- Adjusted SubscriptionWebhooks to focus solely on subscription-related logic, removing credit pack handling.
- Refactored workflow execution methods in WorkflowService for improved clarity and maintainability.

* refactor: remove CreditInsufficientModal and related logic

- Deleted the CreditInsufficientModal component to streamline the subscription flow.
- Removed associated state management and modal visibility logic from the subscription store.
- Updated hooks and components to eliminate references to the CreditInsufficientModal, ensuring cleaner code and improved maintainability.
- Adjusted related components and hooks to comply with performance optimization practices.

* feat: enhance loading and error handling in FormOnboardingModal

- Replaced loading text with a spinner component for better user experience during form definition loading.
- Improved error display by adding an error icon and adjusting the message layout when form definition fails to load.
- Ensured compliance with Tailwind CSS styling standards and optimized component rendering.

* fix: remove unused schemas and update placeholder text

- Deleted the schemas.ts file as it was no longer needed, streamlining the codebase.
- Updated the placeholder text in CheckboxesWidget to English for better clarity and consistency.

---------

Co-authored-by: Sophia <[email protected]>
Co-authored-by: PerishFire <[email protected]>
Co-authored-by: HanYuanxi <[email protected]>
Co-authored-by: Claude <[email protected]>
Co-authored-by: Siri-Ray <[email protected]>
Co-authored-by: Achieve <[email protected]>
Co-authored-by: lefarcen <[email protected]>
Co-authored-by: William Liu <[email protected]>
@coderabbitai
Copy link

coderabbitai bot commented Dec 3, 2025

Walkthrough

Updated subscription pricing UI and text: simplified plans to Free/Plus, added icons and hover gradient, extended FeatureItem props for plan-aware rendering, adjusted feature rendering and styles, updated i18n strings, and changed marketplace link to /marketplace.

Changes

Cohort / File(s) Summary
Pricing UI component
packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx
Added Subscription and lightning icons; extended FeatureItemProps with planType and featureIndex; introduced isHovered hover state and gradient for paid plans; updated border/tag styles; special pointFreeTools rendering path; Free plan shows a $0/month block; upgrade button icon updated (size/color).
Internationalization (en-US)
packages/i18n/src/en-US/ui.ts
Updated CTA and copy: marketplace CTA -> "Explore More Templates"; "Current Plan" -> "Your Current Plan"; modal title -> "Upgrade Your Plan to Get More Credits"; "Upgrade to {{planType}}" -> "Get {{planType}}"; adjusted Free plan wording and added memberBenefits.
Internationalization (zh-Hans)
packages/i18n/src/zh-Hans/ui.ts
Commented out a PLUS feature entry and a public feature block; updated marketplace CTA to “探索更多模板”; unified current-plan wording.
Canvas template link
packages/ai-workspace-common/src/components/canvas-template/template-list.tsx
Changed MARKETPLACE_LINK from ${window.location.origin} to ${window.location.origin}/marketplace.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review priceContent.tsx for correctness of planType-driven conditional styling and featureIndex propagation.
  • Verify hover state behavior and accessibility (keyboard/focus) for PlanItem.
  • Confirm i18n key edits match usages and that commented translations won't break lookups.

Possibly related PRs

Suggested reviewers

  • mrcfps

Poem

🐰 I hopped in with a spark and a grin,
Cards that shimmer when the cursors spin.
Free and Plus now tidy, bright and light,
I nudged the tags and gifted lightning light.
Hop on — subscription dreams take flight! ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description is only the template with no actual content filled in—no summary of changes, no issue reference, no motivation provided, and no screenshots included. Fill in the Summary section with a description of changes and issue reference (Fixes #), select relevant Impact Areas, add before/after screenshots, and explain the motivation behind the pricing updates.
✅ Passed checks (2 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Title check ✅ Passed The title directly relates to the main changeset, which comprehensively updates the subscription/pricing modal component (priceContent.tsx), translations, and marketplace link.
✨ 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 hotfix/credit-pricing

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.

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 (4)
packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (4)

111-112: Consider refactoring index-based styling to use feature flags.

While adding planType and featureIndex props enables planType-specific styling, using array indices (like featureIndex === 1 || featureIndex === 2 on lines 122-125) creates fragile code that breaks when features are reordered.

Consider alternatives:

  • Add a highlight?: boolean flag to the Feature interface
  • Use feature types or IDs instead of array indices
  • Move styling logic to feature data rather than component logic

Example refactor:

 interface Feature {
   name: string;
   type?: string;
+  highlight?: boolean;
   items?: string[];
   duration?: string;
 }

Then in FeatureItem:

-const isGreenDescription =
-  planType === 'plus' &&
-  featureIndex !== undefined &&
-  (featureIndex === 1 || featureIndex === 2);
+const isGreenDescription = feature.highlight && planType === 'plus';

128-156: Extract pointFreeTools rendering to a separate component.

The pointFreeTools type introduces significant complexity with nested structure rendering. This makes FeatureItem harder to test and maintain.

Consider extracting:

const PointFreeToolsFeature = memo(({ name, items, duration }: {
  name: string;
  items: string[];
  duration?: string;
}) => {
  return (
    <div className="flex flex-col gap-2">
      <div className="flex items-start gap-3">
        <div className="flex-shrink-0 mt-0.5">
          <Checked size={16} color="#0E9F77" />
        </div>
        <span className="text-sm leading-5 text-gray-900 font-semibold">{name}</span>
      </div>
      <div className="ml-7 p-3 rounded-lg bg-transparent flex flex-col gap-2">
        {items.map((item, index) => (
          <div key={index} className="flex items-center justify-between">
            {/* ... */}
          </div>
        ))}
      </div>
    </div>
  );
});

Then in FeatureItem:

if (feature.type === 'pointFreeTools' && feature.items) {
  return <PointFreeToolsFeature name={name} items={feature.items} duration={feature.duration} />;
}

69-70: Styling updates improve visual consistency.

The border and tag styling updates enhance the UI:

  • Added solid border with hover states for better interactivity
  • Changed tags to rounded-full and border-0 for a cleaner, modern appearance

Note: The !important flags (e.g., !border-solid, !border-black) suggest conflicting global styles. Consider reviewing CSS specificity to reduce reliance on !important.

Also applies to: 80-86


218-218: Hover effect enhances interactivity.

The hover state with gradient background provides good visual feedback. Implementation is correct with proper cleanup (onMouseLeave).

Optional: Extract gradient definitions to constants for reusability:

const PLAN_GRADIENTS = {
  default: '#ffffff',
  active: 'linear-gradient(180deg, rgba(14, 159, 119, 0.08) 0%, rgba(255, 255, 255, 0) 30%), #ffffff',
  hover: 'linear-gradient(180deg, #A4FFF6, #CFFFD3), #ffffff',
};

Also applies to: 344-349

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b57ea68 and 312537e.

📒 Files selected for processing (2)
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (11 hunks)
  • packages/i18n/src/en-US/ui.ts (5 hunks)
🧰 Additional context used
📓 Path-based instructions (22)
**/*.{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/en-US/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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/i18n/src/en-US/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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/i18n/src/en-US/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx
**/{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/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/en-US/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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/i18n/src/en-US/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx
**/*.{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/en-US/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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/i18n/src/en-US/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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/i18n/src/en-US/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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/i18n/src/en-US/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx
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/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/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/en-US/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx
**/*.{tsx,ts,json}

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

Support dynamic content with placeholders in translations

Files:

  • packages/i18n/src/en-US/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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/i18n/src/en-US/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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/i18n/src/en-US/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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/i18n/src/en-US/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx
**/*.{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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.tsx
🧠 Learnings (12)
📚 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/en-US/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 **/*.{tsx,ts} : Ensure all user-facing text is translatable

Applied to files:

  • 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/en-US/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/en-US/ui.ts
📚 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} : Include appropriate loading states for async actions in buttons

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Secondary buttons should have a border with transparent or light background

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Use consistent padding, border radius, and hover states for all buttons

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Primary buttons should be solid with the primary color

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Use subtle borders for card separation

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Use clear visual indicators for focus, hover, and error states in form elements

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Use consistent border radius (`rounded-lg`) for all cards

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Follow fixed button sizes based on their importance and context

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx
🧬 Code graph analysis (1)
packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (1)
packages/ai-workspace-common/src/components/common/icon.tsx (1)
  • IconLightning01 (197-197)
⏰ 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 (4)
packages/i18n/src/en-US/ui.ts (1)

2707-2707: LGTM: Translation terminology updates are clear and consistent.

The translation updates improve clarity and consistency across the subscription UI:

  • "Your Current Plan" is more personal and explicit than "Current Plan"
  • "Get {{planType}}" is more action-oriented than "Upgrade to {{planType}}"
  • Added "memberBenefits" label for better feature organization
  • Simplified "Free Plan" to "Free" for conciseness

All changes follow i18n guidelines and maintain consistency across related keys.

Also applies to: 3594-3594, 3624-3629, 3632-3633, 3829-3829, 3884-3884

packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (3)

9-9: LGTM: Icon import added for plan header.

The Subscription icon is properly imported and used in the plan card header (line 353).


300-304: LGTM: Free plan price display improves clarity.

Explicitly showing "$0/month" for the free plan improves visual consistency with paid plans and makes the pricing structure clearer to users.


277-277: LGTM: Icon additions enhance visual hierarchy.

The additions improve the UI:

  • Lightning icon on upgrade button creates urgency and action-oriented feel
  • Subscription icon in plan header provides visual context

Also applies to: 353-353

@Siri-Ray Siri-Ray force-pushed the hotfix/credit-pricing branch from 312537e to 7a7b7f6 Compare December 4, 2025 03:01
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 (2)
packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (2)

39-45: Critical: PlanPriorityMap references removed plans, breaking upgrade logic.

The PlanPriorityMap enum includes starter, maker, and enterprise plans that are no longer rendered (line 459 only includes ['free', 'plus']). This causes critical upgrade path failures:

  1. TypeScript enum reverse mapping: When both plus and starter map to priority 1, the reverse lookup PlanPriorityMap[1] returns 'starter' (the last defined key).
  2. Broken upgrade flow: If currentPlan is 'free', line 216 computes upgradePlan = PlanPriorityMap[1] = 'starter', but no PlanItem for 'starter' exists in the rendered UI.
  3. Similar issue for Plus users: If currentPlan is 'plus', upgradePlan would be 'maker' (priority 2), also absent from the UI.

This breaks the upgrade button logic and user experience for plan transitions.

Apply this diff to fix the enum and ensure consistency:

 enum PlanPriorityMap {
   free = 0,
   plus = 1,
-  starter = 1,
-  maker = 2,
-  enterprise = 3,
 }

Then update line 216 to handle the simplified priority map:

   const upgradePlan =
-    PlanPriorityMap[PlanPriorityMap[currentPlan as keyof typeof PlanPriorityMap] + 1] ||
-    'enterprise';
+    PlanPriorityMap[PlanPriorityMap[currentPlan as keyof typeof PlanPriorityMap] + 1];

Also applies to: 216-216


88-88: Use the standard success color from design guidelines.

Multiple locations use the custom green #0E9F77 instead of the standard success color #12B76A specified in the coding guidelines. For consistency across the application, use the guideline-approved color.

As per coding guidelines for **/*.{css,scss,sass,less,js,jsx,ts,tsx}: "Success color (#12B76A) should be used for success states and confirmations."

Apply this diff to standardize the color:

-            <Checked size={12} color="#fff" />
+            <Checked size={12} color="#ffffff" />

And replace #0E9F77 with #12B76A throughout:

-          <div className="ml-auto w-5 h-5 bg-[#0E9F77] rounded-full flex items-center justify-center">
+          <div className="ml-auto w-5 h-5 bg-[#12B76A] rounded-full flex items-center justify-center">
-              <Checked size={16} color="#0E9F77" />
+              <Checked size={16} color="#12B76A" />
-                  <span className="w-1.5 h-1.5 rounded-full bg-[#0E9F77] flex-shrink-0" />
+                  <span className="w-1.5 h-1.5 rounded-full bg-[#12B76A] flex-shrink-0" />
-            <Checked size={16} color="#0E9F77" />
+            <Checked size={16} color="#12B76A" />
-        <IconLightning01 size={20} color="#0E9F77" />
+        <IconLightning01 size={20} color="#12B76A" />

Also applies to: 134-134, 143-143, 164-164, 277-277

🧹 Nitpick comments (2)
packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (2)

127-156: Consider extracting the pointFreeTools rendering logic into a separate component.

The nested rendering block for feature.type === 'pointFreeTools' (lines 127-156) adds significant complexity to FeatureItem. Extracting this into a dedicated component would improve readability and maintainability.

As per coding guidelines: "Always split nested components with closures into separate components in React."

Create a new component:

const PointFreeToolsFeature = memo(({ feature }: { feature: Feature }) => {
  const parts = feature.name.split('\n');
  const name = parts[0];

  return (
    <div className="flex flex-col gap-2">
      {/* Header with check icon */}
      <div className="flex items-start gap-3">
        <div className="flex-shrink-0 mt-0.5">
          <Checked size={16} color="#12B76A" />
        </div>
        <span className="text-sm leading-5 text-gray-900 font-semibold">{name}</span>
      </div>
      {/* Sub-items list */}
      <div className="ml-7 p-3 rounded-lg bg-transparent flex flex-col gap-2">
        {feature.items?.map((item, index) => (
          <div key={index} className="flex items-center justify-between">
            <div className="flex items-center gap-2">
              <span className="w-1.5 h-1.5 rounded-full bg-[#12B76A] flex-shrink-0" />
              <span className="text-sm text-gray-700">{item}</span>
            </div>
            {feature.duration && (
              <span className="text-xs font-medium text-gray-500 bg-white px-2 py-0.5 rounded">
                {feature.duration}
              </span>
            )}
          </div>
        ))}
      </div>
    </div>
  );
});

PointFreeToolsFeature.displayName = 'PointFreeToolsFeature';

Then simplify FeatureItem:

   if (feature.type === 'pointFreeTools' && feature.items && feature.items.length > 0) {
-    return (
-      <div className="flex flex-col gap-2">
-        ...entire block...
-      </div>
-    );
+    return <PointFreeToolsFeature feature={feature} />;
   }

338-349: Simplify the background gradient logic for better readability.

The nested ternary expression for the background style (lines 341-346) is difficult to parse. Extracting this into a computed variable would improve code clarity.

Apply this refactor:

+  const cardBackground = useMemo(() => {
+    if (isCurrentPlan || isUpgrade) {
+      return 'linear-gradient(180deg, rgba(14, 159, 119, 0.08) 0%, rgba(255, 255, 255, 0) 30%), #ffffff';
+    }
+    if (isHovered) {
+      return 'linear-gradient(180deg, #A4FFF6, #CFFFD3), #ffffff';
+    }
+    return '#ffffff';
+  }, [isCurrentPlan, isUpgrade, isHovered]);
+
   return (
     <div
       className="w-full max-w-[532px] p-6 box-border rounded-2xl shadow-[0px_4px_24px_rgba(0,0,0,0.08)]"
       style={{
-        background:
-          isCurrentPlan || isUpgrade
-            ? 'linear-gradient(180deg, rgba(14, 159, 119, 0.08) 0%, rgba(255, 255, 255, 0) 30%), #ffffff'
-            : isHovered
-              ? 'linear-gradient(180deg, #A4FFF6, #CFFFD3),  #ffffff'
-              : '#ffffff',
+        background: cardBackground,
       }}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 312537e and 7a7b7f6.

📒 Files selected for processing (2)
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (11 hunks)
  • packages/i18n/src/en-US/ui.ts (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/i18n/src/en-US/ui.ts
🧰 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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.tsx
🧠 Learnings (8)
📚 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} : Include appropriate loading states for async actions in buttons

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Secondary buttons should have a border with transparent or light background

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Use consistent padding, border radius, and hover states for all buttons

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Primary buttons should be solid with the primary color

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Use subtle borders for card separation

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Use clear visual indicators for focus, hover, and error states in form elements

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Use consistent border radius (`rounded-lg`) for all cards

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Follow fixed button sizes based on their importance and context

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx
🧬 Code graph analysis (1)
packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (3)
packages/ai-workspace-common/src/components/common/icon.tsx (1)
  • IconLightning01 (197-197)
packages/request/src/requests/types.gen.ts (1)
  • Subscription (1963-1992)
packages/openapi-schema/src/types.gen.ts (1)
  • Subscription (1963-1992)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build / Build
  • GitHub Check: build / Build
🔇 Additional comments (1)
packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (1)

300-304: Good UI enhancements improve consistency and visual appeal.

The additions improve the subscription modal:

  • Free plan now displays a clear $0/month price block (lines 300-304), providing visual consistency with paid plans.
  • Proper planType and featureIndex props are passed to FeatureItem (line 329), enabling plan-specific styling.
  • The Subscription icon (line 353) enhances the visual hierarchy of paid plan headers.

These changes align well with the PR's UI improvement objectives.

Also applies to: 329-329, 353-353

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

🧹 Nitpick comments (1)
packages/ai-workspace-common/src/components/canvas-template/template-list.tsx (1)

12-21: Unify marketplace URL and window.open behavior across CTAs

Right now, the end‑of‑list CTA opens ${window.location.origin}/marketplace with noopener,noreferrer, while the “not found” CTA still opens /workflow-marketplace without those options. If /marketplace is the new canonical marketplace route, it would be cleaner and less error‑prone to centralize the path and have both CTAs share it (and the same window.open options), instead of duplicating string literals and behavior.

You could refactor along these lines:

-// Marketplace link
-const MARKETPLACE_LINK = `${window.location.origin}/marketplace`;
+// Marketplace link
+const MARKETPLACE_PATH = '/marketplace';
+const MARKETPLACE_LINK =
+  typeof window !== 'undefined'
+    ? `${window.location.origin}${MARKETPLACE_PATH}`
+    : MARKETPLACE_PATH;
@@
   const handleGoToMarketplace = useCallback(() => {
-    window.open(MARKETPLACE_LINK, '_blank', 'noopener,noreferrer');
-  }, []);
+    window.open(MARKETPLACE_LINK, '_blank', 'noopener,noreferrer');
+  }, []);
@@
-  const handleGoToMarketplace = useCallback(() => {
-    window.open('/workflow-marketplace', '_blank');
-  }, []);
+  const handleGoToMarketplace = useCallback(() => {
+    window.open(MARKETPLACE_PATH, '_blank', 'noopener,noreferrer');
+  }, []);

This also removes a magic string and keeps the URL definition in one place, in line with the coding guidelines.
As per coding guidelines, please confirm that /marketplace is indeed the intended target for both CTAs before applying.

Also applies to: 153-168

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7a7b7f6 and 2c59fba.

📒 Files selected for processing (3)
  • packages/ai-workspace-common/src/components/canvas-template/template-list.tsx (1 hunks)
  • packages/i18n/src/en-US/ui.ts (6 hunks)
  • packages/i18n/src/zh-Hans/ui.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/i18n/src/en-US/ui.ts
🧰 Additional context used
📓 Path-based instructions (22)
**/*.{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-template/template-list.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-template/template-list.tsx
  • packages/i18n/src/zh-Hans/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/ai-workspace-common/src/components/canvas-template/template-list.tsx
  • packages/i18n/src/zh-Hans/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/ai-workspace-common/src/components/canvas-template/template-list.tsx
  • packages/i18n/src/zh-Hans/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/ai-workspace-common/src/components/canvas-template/template-list.tsx
  • packages/i18n/src/zh-Hans/ui.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-template/template-list.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-template/template-list.tsx
  • packages/i18n/src/zh-Hans/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/ai-workspace-common/src/components/canvas-template/template-list.tsx
  • packages/i18n/src/zh-Hans/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/ai-workspace-common/src/components/canvas-template/template-list.tsx
  • packages/i18n/src/zh-Hans/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/ai-workspace-common/src/components/canvas-template/template-list.tsx
  • packages/i18n/src/zh-Hans/ui.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-template/template-list.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-template/template-list.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-template/template-list.tsx
  • packages/i18n/src/zh-Hans/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/ai-workspace-common/src/components/canvas-template/template-list.tsx
  • packages/i18n/src/zh-Hans/ui.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-template/template-list.tsx
  • packages/i18n/src/zh-Hans/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/ai-workspace-common/src/components/canvas-template/template-list.tsx
  • packages/i18n/src/zh-Hans/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/ai-workspace-common/src/components/canvas-template/template-list.tsx
  • packages/i18n/src/zh-Hans/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/ai-workspace-common/src/components/canvas-template/template-list.tsx
  • packages/i18n/src/zh-Hans/ui.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-template/template-list.tsx
**/{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,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/**

📄 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
🧠 Learnings (3)
📚 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/{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
📚 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/i18n/src/zh-Hans/ui.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build / Build
  • GitHub Check: build / Build
🔇 Additional comments (1)
packages/i18n/src/zh-Hans/ui.ts (1)

967-972: Updated marketplace CTA text looks good

frontPage.template.endMessage.goToMarketplace now uses自然、清晰的中文“探索更多模板”,保持了含义一致且未引入新 key,符合 i18n 文件需用中文的约束。
Based on learnings, this matches the Chinese‑only requirement for user‑facing text under packages/i18n/src/zh-Hans/**.

@Siri-Ray Siri-Ray force-pushed the hotfix/credit-pricing branch from 2c59fba to 7a0b611 Compare December 4, 2025 03:29
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

♻️ Duplicate comments (1)
packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (1)

459-459: Plan removal issue already flagged.

The reduction of planTypes to ['free', 'plus'] and its implications (broken upgrade paths, invisible current plans, type mismatches) were already comprehensively documented in the previous review.

🧹 Nitpick comments (6)
packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (6)

69-70: Avoid !important overrides and fix line length.

Using !important flags (!border-solid, !border-black, !border-gray-200) suggests specificity conflicts that should be resolved at the source. Additionally, line 70 exceeds the 100-character maximum.

As per coding guidelines, maximum line length is 100 characters and Tailwind utilities should not require !important overrides.

Refactor to remove !important and break long lines:

       ${
         isSelected
-            ? 'border-2 !border-solid !border-black bg-white'
-            : 'border-2 !border-solid !border-gray-200 bg-[#FAFAFA] hover:border-[#0E9F77]'
+            ? 'border-2 border-solid border-black bg-white'
+            : 'border-2 border-solid border-gray-200 bg-[#FAFAFA] ' +
+              'hover:border-[#0E9F77]'
       }

80-83: Remove !important overrides from Tag styling.

The Tag component uses multiple !important flags (!m-0, !px-2, !py-0.5, etc.), indicating a specificity conflict with antd's default styles.

As per coding guidelines, prefer Tailwind utilities without !important. Consider using antd's classNames prop or a wrapper component with proper CSS specificity:

-          <Tag
-            className="!m-0 !px-2 !py-0.5 !text-xs !font-medium !rounded-full !border-0"
-            color="orange"
-          >
+          <Tag
+            className="m-0 px-2 py-0.5 text-xs font-medium rounded-full border-0"
+            color="orange"
+            bordered={false}
+          >

If overrides are still needed, investigate the root cause in the component's SCSS file.


111-112: Consider using stricter types for planType.

The planType prop is typed as string, but based on the codebase it should be constrained to valid subscription plan values.

Use a union type or import SubscriptionPlanType for better type safety:

 interface FeatureItemProps {
   feature: Feature;
   isEnterprise?: boolean;
   isLast?: boolean;
-  planType?: string;
+  planType?: 'free' | 'plus' | 'starter' | 'maker' | 'enterprise';
   featureIndex?: number;
 }

Or import the existing type:

planType?: SubscriptionPlanType;

117-119: Consider safer parsing for multi-line feature names.

Splitting feature.name on \n assumes a specific format. If the data source changes or includes unexpected newlines, this could break.

Add validation or use a more explicit data structure:

-    const parts = feature.name.split('\n');
-    const name = parts[0];
-    const description = parts.length > 1 ? parts.slice(1).join('\n') : null;
+    const parts = feature.name?.split('\n') ?? [];
+    const name = parts[0] ?? feature.name;
+    const description = parts.length > 1 ? parts.slice(1).join('\n') : null;

Alternatively, update the Feature interface to include description as a separate field.


348-349: Consider extracting hover handlers with useCallback.

The inline event handlers are simple, but per coding guidelines, consider using useCallback to maintain referential equality.

As per coding guidelines, use useCallback for function props:

+  const handleMouseEnter = useCallback(() => setIsHovered(true), []);
+  const handleMouseLeave = useCallback(() => setIsHovered(false), []);
+
   <div
     className="..."
     style={{...}}
-    onMouseEnter={() => setIsHovered(true)}
-    onMouseLeave={() => setIsHovered(false)}
+    onMouseEnter={handleMouseEnter}
+    onMouseLeave={handleMouseLeave}
   >

56-430: Consider splitting tightly coupled sub-components into separate files.

The file contains four components: PriceOption, FeatureItem, PlanItem, and PriceContent. While these are internal to PriceContent, the file is lengthy (~587 lines).

As per coding guidelines, "Each component file should contain only one main component." Consider extracting into separate files:

  • priceContent/PriceOption.tsx
  • priceContent/FeatureItem.tsx
  • priceContent/PlanItem.tsx
  • priceContent/index.tsx (main PriceContent)

This improves maintainability and follows the single-responsibility principle, though the current structure is acceptable for tightly coupled components.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2c59fba and 7a0b611.

📒 Files selected for processing (4)
  • packages/ai-workspace-common/src/components/canvas-template/template-list.tsx (1 hunks)
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (11 hunks)
  • packages/i18n/src/en-US/ui.ts (8 hunks)
  • packages/i18n/src/zh-Hans/ui.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/i18n/src/zh-Hans/ui.ts
  • packages/i18n/src/en-US/ui.ts
  • packages/ai-workspace-common/src/components/canvas-template/template-list.tsx
🧰 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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.tsx
🧠 Learnings (8)
📚 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} : Include appropriate loading states for async actions in buttons

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Secondary buttons should have a border with transparent or light background

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Use consistent padding, border radius, and hover states for all buttons

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Primary buttons should be solid with the primary color

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Use subtle borders for card separation

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Use clear visual indicators for focus, hover, and error states in form elements

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Use consistent border radius (`rounded-lg`) for all cards

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Follow fixed button sizes based on their importance and context

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx
🧬 Code graph analysis (1)
packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (3)
packages/openapi-schema/src/types.gen.ts (1)
  • Subscription (1963-1992)
packages/request/src/requests/types.gen.ts (1)
  • Subscription (1963-1992)
packages/ai-workspace-common/src/components/settings/subscription/index.tsx (1)
  • Subscription (136-610)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build / Build
  • GitHub Check: build / Build
🔇 Additional comments (5)
packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (5)

218-218: LGTM: Hover state implementation.

The isHovered state is properly initialized and used for conditional background gradients on paid plan cards.


277-277: LGTM: Icon styling update.

The lightning icon color update to #0E9F77 (green) aligns with the success color palette used throughout the component.


300-304: LGTM: Free plan price display added.

Adding an explicit "$0/month" price block improves UI consistency between free and paid plan cards.


329-329: LGTM: FeatureItem prop forwarding.

The planType and featureIndex props are correctly passed to FeatureItem for conditional rendering logic.

Also applies to: 421-422


353-353: LGTM: Subscription icon added to plan header.

The Subscription icon enhances the visual hierarchy of paid plan cards.

- Introduced a new EndMessage component to encourage users to visit the marketplace instead of Discord.
- Utilized React.memo for performance optimization and wrapped the button click handler with useCallback.
- Updated translations for the new EndMessage content in both English and Chinese.
- Ensured adherence to Tailwind CSS for consistent styling across the component.
@Siri-Ray Siri-Ray force-pushed the hotfix/credit-pricing branch from 7a0b611 to 71e08fd Compare December 4, 2025 04:05
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/i18n/src/zh-Hans/ui.ts (1)

143-157: Remove large commented blocks from both translation files and verify pointFreeTools feature is intentionally disabled.

This commented block exists in both packages/i18n/src/zh-Hans/ui.ts (line 145) and packages/i18n/src/en-US/ui.ts (line 3652). The corresponding rendering logic for pointFreeTools remains active in priceContent.tsx (lines 128-156), creating a disconnect between disabled translations and active code. If this feature is permanently disabled, remove the commented translations from both language files and verify the rendering logic is also removed or guarded against being called.

♻️ Duplicate comments (1)
packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (1)

459-459: Incomplete plan removal creates critical issues (duplicate concern).

This change was previously flagged in an earlier review: reducing planTypes to ['free', 'plus'] creates critical issues:

  1. Current plan display: Users with active starter/maker/enterprise subscriptions won't see pricing cards for their plans (line 549 only maps the planTypes array)
  2. Type inconsistency: SubscriptionPlanType globally includes all 5 plans, but UI only renders 2
  3. Orphaned data: PlanPriorityMap (lines 40-44) and price data (lines 228-231) still reference removed plans

This was addressed in commit 7a7b7f6, but if this is a new occurrence, complete the migration by:

  • Updating PlanPriorityMap enum to remove starter/maker/enterprise
  • Removing price data for legacy plans
  • Handling legacy plan display for existing subscribers

✅ If commit 7a7b7f6 resolved this, disregard. Otherwise, this requires immediate attention before deployment.

🧹 Nitpick comments (5)
packages/i18n/src/zh-Hans/ui.ts (1)

141-141: Remove commented-out code or document temporary removal.

Commented-out translation entries create maintenance debt. If this feature is permanently removed, delete the line entirely. If temporarily disabled, add a comment explaining why and when it will be restored.

Apply this diff to remove the commented line:

         '每月积分\n2000点',
-        //'首次订阅额外赠送\n2000点',
         '访问丰富的工具库',

Or document if temporary:

         '每月积分\n2000点',
-        //'首次订阅额外赠送\n2000点',
+        // TODO(TICKET-XXX): Re-enable first subscription bonus after credit system update
+        // '首次订阅额外赠送\n2000点',
         '访问丰富的工具库',
packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (4)

69-70: Avoid !important flags; investigate CSS specificity conflicts.

Lines 69-70 use multiple !important flags (!border-solid, !border-black, !border-gray-200), which suggests CSS specificity conflicts. The !border-solid is also redundant since Tailwind border utilities are solid by default.

Investigate why !important is needed and resolve the underlying specificity issue. Consider:

  1. Checking if parent components have conflicting styles
  2. Using more specific selectors instead of !important
  3. Ensuring proper CSS cascade order

As per coding guidelines, maintain consistent styling without relying on !important flags.


80-85: Multiple !important flags indicate styling conflicts.

The yearly discount Tag uses several !important overrides (!m-0, !px-2, !py-0.5, !text-xs, !font-medium, !rounded-full, !border-0). This pattern suggests Ant Design's default Tag styles are conflicting with your design.

Consider creating a custom styled component or CSS class instead of multiple inline overrides:

// In a separate styles file or styled component
const StyledDiscountTag = styled(Tag)`
  margin: 0;
  padding: 2px 8px;
  font-size: 12px;
  font-weight: 500;
  border-radius: 9999px;
  border: 0;
`;

// Usage
<StyledDiscountTag color="orange">
  {t('subscription.save20')}
</StyledDiscountTag>

117-126: Add validation for feature name format and extract conditional logic.

The feature name parsing (lines 117-119) assumes a newline separator exists, which is fragile. The conditional styling logic (lines 122-125) is specific to plus plan indices and could be extracted to a helper function for clarity.

// Extract to helper function
const shouldUseGreenDescription = (
  planType?: string,
  featureIndex?: number
): boolean => {
  return planType === 'plus' && 
         featureIndex !== undefined && 
         (featureIndex === 1 || featureIndex === 2);
};

// Add validation for feature name format
const parseFeatureName = (name: string): { name: string; description: string | null } => {
  const parts = name.split('\n');
  if (parts.length < 1) {
    console.warn('Feature name is empty or invalid:', name);
    return { name: '', description: null };
  }
  return {
    name: parts[0],
    description: parts.length > 1 ? parts.slice(1).join('\n') : null,
  };
};

// Usage in component
const { name, description } = parseFeatureName(feature.name);
const isGreenDescription = shouldUseGreenDescription(planType, featureIndex);

As per coding guidelines, extract complex logic into helper functions for maintainability.


344-350: Verify hover gradient design with stakeholders.

The hover gradient uses bright cyan-to-green colors (#A4FFF6 to #CFFFD3) that create a bold visual effect. While the implementation is correct, consider verifying with design stakeholders that this intensity aligns with your brand guidelines.

The hover state could be made configurable via CSS variables for easier theming:

style={{
  background:
    isCurrentPlan || isUpgrade
      ? 'linear-gradient(180deg, rgba(14, 159, 119, 0.08) 0%, rgba(255, 255, 255, 0) 30%), #ffffff'
      : isHovered
        ? 'var(--plan-hover-gradient, linear-gradient(180deg, #A4FFF6, #CFFFD3)), #ffffff'
        : '#ffffff',
}}

As per coding guidelines, maintain consistent hover states across all interactive elements.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7a0b611 and 71e08fd.

📒 Files selected for processing (4)
  • packages/ai-workspace-common/src/components/canvas-template/template-list.tsx (1 hunks)
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (11 hunks)
  • packages/i18n/src/en-US/ui.ts (8 hunks)
  • packages/i18n/src/zh-Hans/ui.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/i18n/src/en-US/ui.ts
  • packages/ai-workspace-common/src/components/canvas-template/template-list.tsx
🧰 Additional context used
📓 Path-based instructions (22)
**/*.{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/settings/subscribe-modal/priceContent.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/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx
**/{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
**/*.{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/settings/subscribe-modal/priceContent.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/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx
**/*.{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/settings/subscribe-modal/priceContent.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/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx
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/**

📄 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
**/*.{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/settings/subscribe-modal/priceContent.tsx
**/*.{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/settings/subscribe-modal/priceContent.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/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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/i18n/src/zh-Hans/ui.ts
  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx
**/*.{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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.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/settings/subscribe-modal/priceContent.tsx
🧠 Learnings (11)
📚 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/{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
📚 Learning: 2025-11-25T03:05:15.932Z
Learnt from: CR
Repo: refly-ai/refly PR: 0
File: .cursor/rules/16-language-guidelines.mdc:0-0
Timestamp: 2025-11-25T03:05:15.932Z
Learning: UI text should default to English with i18n support for Chinese

Applied to files:

  • packages/i18n/src/zh-Hans/ui.ts
📚 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} : Include appropriate loading states for async actions in buttons

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Secondary buttons should have a border with transparent or light background

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Use consistent padding, border radius, and hover states for all buttons

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Primary buttons should be solid with the primary color

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Use subtle borders for card separation

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Use clear visual indicators for focus, hover, and error states in form elements

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Use consistent border radius (`rounded-lg`) for all cards

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.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} : Follow fixed button sizes based on their importance and context

Applied to files:

  • packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx
🧬 Code graph analysis (1)
packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (4)
packages/ai-workspace-common/src/components/common/icon.tsx (1)
  • IconLightning01 (197-197)
packages/request/src/requests/types.gen.ts (1)
  • Subscription (1963-1992)
packages/openapi-schema/src/types.gen.ts (1)
  • Subscription (1963-1992)
packages/ai-workspace-common/src/components/settings/subscription/index.tsx (1)
  • Subscription (136-610)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build / Build
  • GitHub Check: build / Build
🔇 Additional comments (3)
packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx (2)

111-113: Interface extension supports plan-specific feature rendering.

Adding optional planType and featureIndex props enables conditional styling for different plans. The optionality maintains backward compatibility with existing FeatureItem usage.


277-281: Icon size and color updates align with design refresh.

The lightning icon size (20px) and green color (#0E9F77) match the primary brand color used throughout the UI (confirmed in coding guidelines). This creates visual consistency with the upgrade action.

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

971-971: Translation consistency verified for the updated key.

The Chinese translation update at line 971 (frontPage.template.endMessage.goToMarketplace: '探索更多模板') correctly corresponds to the English version ('Explore More Templates'), maintaining consistency across both language files.

However, note that there are two separate goToMarketplace keys in each file with different translations—the one at line 971 is consistent, but ensure the other instance under notFoundQuestion is intentionally different ('Go to Marketplace' in English vs. '前往市场' in Chinese).

Comment on lines +128 to +156
if (feature.type === 'pointFreeTools' && feature.items && feature.items.length > 0) {
return (
<div className="flex flex-col gap-2">
{/* Header with check icon */}
<div className="flex items-start gap-3">
<div className="flex-shrink-0 mt-0.5">
<Checked size={16} color="#0E9F77" />
</div>
<span className="text-sm leading-5 text-gray-900 font-semibold">{name}</span>
</div>
{/* Sub-items list */}
<div className="ml-7 p-3 rounded-lg bg-transparent flex flex-col gap-2">
{feature.items.map((item, index) => (
<div key={index} className="flex items-center justify-between">
<div className="flex items-center gap-2">
<span className="w-1.5 h-1.5 rounded-full bg-[#0E9F77] flex-shrink-0" />
<span className="text-sm text-gray-700">{item}</span>
</div>
{feature.duration && (
<span className="text-xs font-medium text-gray-500 bg-white px-2 py-0.5 rounded">
{feature.duration}
</span>
)}
</div>
))}
</div>
</div>
);
}
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

# Search for pointFreeTools references in i18n files
echo "=== Searching for pointFreeTools in i18n files ==="
rg "pointFreeTools" packages/i18n/src -g "*.{ts,json}" -C 2

# Search for pointFreeTools in the entire packages directory
echo -e "\n=== Searching for pointFreeTools in entire packages ==="
rg "pointFreeTools" packages -g "*.{ts,tsx,js,jsx,json}" -C 1

# Check the zh-Hans translation file specifically
echo -e "\n=== Checking zh-Hans UI file ==="
cat packages/i18n/src/zh-Hans/ui.ts | head -170 | tail -40

Repository: refly-ai/refly

Length of output: 2784


Remove dead code for pointFreeTools feature rendering.

The rendering logic for pointFreeTools type features (lines 128-156) is dead code. The corresponding feature data is commented out in all translation files (both en-US and zh-Hans), so this branch will never execute. Remove this unused rendering logic to reduce code complexity and maintenance burden.

🤖 Prompt for AI Agents
In
packages/ai-workspace-common/src/components/settings/subscribe-modal/priceContent.tsx
around lines 128 to 156, the JSX branch that renders features of type
'pointFreeTools' is dead code because the corresponding feature data is removed
from all translation files; delete this entire conditional block (the if
(feature.type === 'pointFreeTools' && feature.items && feature.items.length > 0)
{ ... } section) and any now-unused imports or variables that become redundant
as a result; after removal, run a build/type-check and search translation/usage
to ensure no remaining references to 'pointFreeTools' remain.

@mrcfps mrcfps changed the title Hotfix/credit pricing hotfix: credit pricing page Dec 4, 2025
@mrcfps mrcfps merged commit e99a32b into main Dec 4, 2025
3 checks passed
@mrcfps mrcfps deleted the hotfix/credit-pricing branch December 4, 2025 07:43
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