Skip to content

feat: Add Cursor IDE custom slash commands support#1215

Merged
Crunchyman-ralph merged 23 commits intoeyaltoledano:nextfrom
joedanz:joedanz/cursor-commands
Sep 26, 2025
Merged

feat: Add Cursor IDE custom slash commands support#1215
Crunchyman-ralph merged 23 commits intoeyaltoledano:nextfrom
joedanz:joedanz/cursor-commands

Conversation

@joedanz
Copy link
Contributor

@joedanz joedanz commented Sep 18, 2025

Summary

Updates the Cursor profile to copy command files from assets/claude/commands/ to .cursor/commands/, enabling Cursor users to access Task Master commands through Cursor's command system.

Changes

src/profiles/cursor.js

  • Added imports: fs, path, and log utility for file operations
  • Added helper functions:
    • copyRecursiveSync: Recursively copies directories and files
    • removeDirectoryRecursive: Safely removes directories with error handling
  • Added lifecycle functions:
    • onAddRulesProfile: Copies commands from assets/claude/commands/ to .cursor/commands/
    • onRemoveRulesProfile: Removes .cursor/commands/ directory when profile is removed
  • Updated profile configuration: Added onAdd and onRemove lifecycle hooks
  • Added exports: Export lifecycle functions for potential external use

Behavior

When adding Cursor profile:

  • All command files from assets/claude/commands/ are copied to .cursor/commands/
  • Directory structure is preserved (e.g., tm/ subdirectory with all commands)
  • Provides debug logging for successful operations and error logging for failures

When removing Cursor profile:

  • .cursor/commands/ directory is completely removed
  • Safe cleanup with proper error handling

Technical Details

  • Follows the same pattern as the existing Claude profile implementation
  • Uses the shared command files from assets/claude/commands/ (same source as Claude profile)
  • Maintains Cursor-specific directory structure (.cursor/commands/ vs .claude/commands/)
  • Includes proper error handling and logging for debugging

Testing

Manual Testing

  • ✅ Successfully copies all command files when adding profile
  • ✅ Successfully removes command directory when removing profile
  • ✅ Preserves directory structure and all subdirectories
  • ✅ Handles missing source directories gracefully
  • ✅ Works in both development and production builds

Automated Testing

Unit Tests (tests/unit/profiles/cursor-integration.test.js)

  • Profile structure validation: Verifies cursor profile exports lifecycle functions correctly
  • Command copying functionality: Tests onAddRulesProfile copies from assets/claude/commands/ to .cursor/commands/
  • Directory creation: Ensures target .cursor/commands directory is created with proper recursive flag
  • Missing source handling: Gracefully handles when source claude/commands directory doesn't exist
  • Command removal: Tests onRemoveRulesProfile removes .cursor/commands directory with rmSync
  • Missing target handling: Handles removal when target directory doesn't exist
  • Error resilience: Gracefully handles file system errors during removal operations

Integration Tests (tests/integration/profiles/cursor-init-functionality.test.js)

  • Source code verification: Confirms presence of onAddRulesProfile and onRemoveRulesProfile functions in source
  • Helper function presence: Validates copyRecursiveSync and removeDirectoryRecursive exist in source
  • Path configuration: Verifies correct source path path.join(assetsDir, 'claude', 'commands')
  • Destination configuration: Confirms target path path.join(targetDir, '.cursor', 'commands')
  • Function registration: Ensures lifecycle functions are properly registered with cursor profile object
  • Function invocation: Validates copyRecursiveSync(commandsSourceDir, commandsDestDir) call exists

Mock Setup & Testing Strategy

  • Comprehensive mocking: All file system operations mocked to avoid side effects
  • Chalk dependency isolation: Custom console mocking to avoid color formatting issues in tests
  • Error simulation: Tests include scenarios for missing directories and permission failures
  • State isolation: Each test runs with fresh mocks and temporary directories

Test Results: 18/18 tests passing for cursor profile functionality

Summary by CodeRabbit

  • New Features

    • Adds Cursor IDE slash command support: Task Master commands are installed when a Cursor profile is added and removed when the profile is removed.
    • Profile lifecycle now automatically manages Cursor command assets and integrates lifecycle hooks to ensure consistent install/uninstall behavior and resilience to missing assets.
  • Tests

    • Added integration and unit tests covering command installation, removal, lifecycle wiring, error handling, and different filesystem scenarios.

@changeset-bot
Copy link

changeset-bot bot commented Sep 18, 2025

🦋 Changeset detected

Latest commit: 83d9aea

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 18, 2025

Walkthrough

Adds lifecycle hooks to the Cursor profile that copy Cursor slash-command assets from assets/claude/commands into a profile's .cursor/commands on profile add and remove that directory on profile remove; introduces recursive filesystem helpers, updates lifecycle invocations, a changeset, and tests.

Changes

Cohort / File(s) Summary
Changeset entry
.changeset/cursor-slash-commands.md
New minor changeset documenting Cursor slash-command support and asset install/removal on profile add/remove.
Cursor profile lifecycle
src/profiles/cursor.js
Add fs, path, and log usage; implement copyRecursiveSync and removeDirectoryRecursive; add resolveCursorProfileDir; add and export lifecycle hooks onAddRulesProfile(targetDir, assetsDir) and onRemoveRulesProfile(targetDir) that copy assets/claude/commands<targetDir>/.cursor/commands and remove that directory; wire hooks into cursorProfile.
Lifecycle wiring invocations
src/utils/rule-transformer.js
Change lifecycle hook first arg from projectRoot to targetDir (computed as path.join(projectRoot, profile.rulesDir)) for calls to onAddRulesProfile, onPostConvertRulesProfile, and onRemoveRulesProfile.
Integration tests
tests/integration/profiles/cursor-init-functionality.test.js
Add tests asserting presence of lifecycle/helper functions, correct source/destination path construction, and that cursorProfile.onAddRulesProfile/onRemoveRulesProfile are defined functions referencing the copy/remove logic.
Unit tests for lifecycle
tests/unit/profiles/cursor-integration.test.js
Replace console mocking with mockConsole/mockLog, mock utils via unstable_mockModule, dynamically import src/profiles/cursor.js after mocks, and add tests that mock fs to verify directory creation, recursive copy behavior, handling of missing source, removal with { recursive: true, force: true }, and tolerant error handling when rmSync throws.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant CLI as Task Master CLI
  participant Cursor as src/profiles/cursor.js
  participant FS as Filesystem

  CLI->>Cursor: onAddRulesProfile(targetDir, assetsDir)
  Cursor->>FS: stat/check `assets/.../claude/commands`
  alt source exists
    Cursor->>FS: mkdir -p `<targetDir>/.cursor/commands`
    Cursor->>FS: copy files recursively -> `.cursor/commands`
  else source missing
    Note over Cursor: skip copy, log debug
  end

  CLI->>Cursor: onRemoveRulesProfile(targetDir)
  Cursor->>FS: rm -rf `<targetDir>/.cursor/commands` (force, recursive)
  Note over Cursor: swallow/log errors if removal fails
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • Crunchyman-ralph

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "feat: Add Cursor IDE custom slash commands support" is concise and accurately summarizes the primary change: adding support to expose Task Master commands to Cursor via custom slash commands and lifecycle hooks. It clearly relates to the changeset and is specific enough for a reviewer scanning history. The conventional "feat:" prefix is appropriate for this feature addition.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Copy link
Contributor

@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: 9

Caution

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

⚠️ Outside diff range comments (1)
tests/unit/profiles/cursor-integration.test.js (1)

54-61: Cleanup may be skipped due to mocked fs.rmSync; restore mocks before removing tempDir

jest.clearAllMocks() doesn’t restore implementations. If fs.rmSync is mocked in nested tests, the outer afterEach cleanup becomes a no‑op.

Apply:

 afterEach(() => {
-	// Clean up the temporary directory
-	try {
-		fs.rmSync(tempDir, { recursive: true, force: true });
+	// Restore real implementations before cleanup
+	jest.restoreAllMocks();
+	try {
+		fs.rmSync(tempDir, { recursive: true, force: true });
 	} catch (err) {
 		console.error(`Error cleaning up: ${err.message}`);
 	}
 });
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 170d6f2 and e1b3b45.

📒 Files selected for processing (4)
  • .changeset/cursor-slash-commands.md (1 hunks)
  • src/profiles/cursor.js (1 hunks)
  • tests/integration/profiles/cursor-init-functionality.test.js (1 hunks)
  • tests/unit/profiles/cursor-integration.test.js (2 hunks)
🧰 Additional context used
📓 Path-based instructions (12)
.changeset/*.md

📄 CodeRabbit inference engine (.cursor/rules/changeset.mdc)

.changeset/*.md: When running npm run changeset or npx changeset add, provide a concise summary of the changes for the CHANGELOG.md in imperative mood, typically a single line, and not a detailed Git commit message.
The changeset summary should be user-facing, describing what changed in the released version that is relevant to users or consumers of the package.
Do not use your detailed Git commit message body as the changeset summary.

Files:

  • .changeset/cursor-slash-commands.md
.changeset/*

📄 CodeRabbit inference engine (.cursor/rules/new_features.mdc)

Create appropriate changesets for new features, use semantic versioning, include tagged system information in release notes, and document breaking changes if any.

Files:

  • .changeset/cursor-slash-commands.md
tests/{unit,integration,e2e,fixtures}/**/*.js

📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)

Test files must be organized as follows: unit tests in tests/unit/, integration tests in tests/integration/, end-to-end tests in tests/e2e/, and test fixtures in tests/fixtures/.

Files:

  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
**/*.{test,spec}.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/git_workflow.mdc)

**/*.{test,spec}.{js,ts,jsx,tsx}: Create a test file and ensure all tests pass when all subtasks are complete; commit tests if added or modified
When all subtasks are complete, run final testing using the appropriate test runner (e.g., npm test, jest, or manual testing)

Files:

  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
**/*.test.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

**/*.test.js: Never use asynchronous operations in tests. Make all mocks return synchronous values when possible.
Always mock tests properly based on the way the tested functions are defined and used.
Follow the test file organization: mocks must be set up before importing modules under test, and spies on mocked modules should be set up after imports.
Use fixtures from tests/fixtures/ for consistent sample data across tests.
Always declare mocks before importing the modules being tested in Jest test files.
Use jest.spyOn() after imports to create spies on mock functions and reference these spies in test assertions.
When testing functions with callbacks, get the callback from your mock's call arguments, execute it directly with test inputs, and verify the results.
For ES modules, use jest.mock() before static imports and jest.unstable_mockModule() before dynamic imports to mock dependencies.
Reset mock functions (mockFn.mockReset()) before dynamic imports if they might have been called previously.
When verifying console assertions, assert against the actual arguments passed (single formatted string), not multiple arguments.
Use mock-fs to mock file system operations in tests, and restore the file system after each test.
Mock API calls (e.g., Anthropic/Claude) by mocking the entire module and providing predictable responses.
Set mock environment variables in test setup and restore them after each test.
Maintain test fixtures separate from test logic.
Follow the mock-first-then-import pattern for all Jest mocks.
Do not define mock variables before jest.mock() calls (they won't be accessible due to hoisting).
Use test-specific file paths (e.g., 'test-tasks.json') for all file operations in tests.
Mock readJSON and writeJSON to avoid real file system interactions in tests.
Verify file operations use the correct paths in expect statements.
Use different file paths for each test to avoid test interdependence.
Verify modifications on the in-memory task objects passed to w...

Files:

  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
tests/integration/**/*.test.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

Integration tests must be located in tests/integration/, test interactions between modules, and focus on component interfaces rather than implementation details.

Files:

  • tests/integration/profiles/cursor-init-functionality.test.js
tests/{unit,integration,e2e}/**/*.test.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

tests/{unit,integration,e2e}/**/*.test.js: When testing CLI commands built with Commander.js, test the command action handlers directly rather than trying to mock the entire Commander.js chain.
When mocking the Commander.js chain, mock ALL chainable methods (option, argument, action, on, etc.) and return this (or the mock object) from all chainable method mocks.
Explicitly handle all options, including defaults and shorthand flags (e.g., -p for --prompt), and include null/undefined checks in test implementations for parameters that might be optional.
Do not try to use the real action implementation without proper mocking, and do not mock Commander partially—either mock it completely or test the action directly.
Mock the action handlers for CLI commands and verify they're called with correct arguments.
Use sample task fixtures for consistent test data, mock file system operations, and test both success and error paths for task operations.
Mock console output and verify correct formatting in UI function tests. Use flexible assertions like toContain() or toMatch() for formatted output.
Mock chalk functions to return the input text to make testing easier while still verifying correct function calls.

Files:

  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
tests/{integration,e2e}/**/*.test.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

Properly mock session objects when required by functions, and reset environment variables between tests if modified.

Files:

  • tests/integration/profiles/cursor-init-functionality.test.js
**/*.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

**/*.js: Declare and initialize global variables at the top of modules to avoid hoisting issues.
Use proper function declarations to avoid hoisting issues and initialize variables before they are referenced.
Do not reference variables before their declaration in module scope.
Use dynamic imports (import()) to avoid initialization order issues in modules.

Files:

  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
  • src/profiles/cursor.js
**/*.{test,spec}.*

📄 CodeRabbit inference engine (.cursor/rules/test_workflow.mdc)

Test files should follow naming conventions: .test., .spec., or _test. depending on the language

Files:

  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
tests/{unit,integration,e2e}/**

📄 CodeRabbit inference engine (.cursor/rules/test_workflow.mdc)

Organize test directories by test type (unit, integration, e2e) and mirror source structure where possible

Files:

  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
tests/unit/**/*.test.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

tests/unit/**/*.test.js: Unit tests must be located in tests/unit/, test individual functions and utilities in isolation, mock all external dependencies, and keep tests small, focused, and fast.
Do not include actual command execution in unit tests.

Files:

  • tests/unit/profiles/cursor-integration.test.js
🧠 Learnings (23)
📓 Common learnings
Learnt from: joedanz
PR: eyaltoledano/claude-task-master#1186
File: src/profiles/cursor.js:37-43
Timestamp: 2025-09-17T19:28:51.448Z
Learning: In the eyaltoledano/claude-task-master repository cursor profile implementation, the onAdd lifecycle hook sources command files from 'assets/claude/commands' and transforms them for Cursor IDE compatibility, rather than using separate cursor-specific command files.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-11T12:30:23.843Z
Learning: Import Task Master's development workflow commands and guidelines; treat the contents of ./.taskmaster/CLAUDE.md as if included in the main CLAUDE.md
📚 Learning: 2025-09-17T19:28:51.448Z
Learnt from: joedanz
PR: eyaltoledano/claude-task-master#1186
File: src/profiles/cursor.js:37-43
Timestamp: 2025-09-17T19:28:51.448Z
Learning: In the eyaltoledano/claude-task-master repository cursor profile implementation, the onAdd lifecycle hook sources command files from 'assets/claude/commands' and transforms them for Cursor IDE compatibility, rather than using separate cursor-specific command files.

Applied to files:

  • .changeset/cursor-slash-commands.md
  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:09:28.215Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/cursor_rules.mdc:0-0
Timestamp: 2025-07-18T17:09:28.215Z
Learning: Applies to .cursor/rules/*.mdc : Maintain Cursor rule files by updating them when new patterns emerge, adding examples from the actual codebase, removing outdated patterns, and cross-referencing related rules.

Applied to files:

  • tests/integration/profiles/cursor-init-functionality.test.js
  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Verify file operations use the correct paths in expect statements.

Applied to files:

  • tests/integration/profiles/cursor-init-functionality.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Mock the action handlers for CLI commands and verify they're called with correct arguments.

Applied to files:

  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{integration,e2e}/**/*.test.js : Properly mock session objects when required by functions, and reset environment variables between tests if modified.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Do not import real AI service clients in tests; create fully mocked versions that return predictable responses.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Mock console output and verify correct formatting in UI function tests. Use flexible assertions like toContain() or toMatch() for formatted output.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Do not try to use the real action implementation without proper mocking, and do not mock Commander partially—either mock it completely or test the action directly.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Troubleshoot mock functions not being called by ensuring mocks are defined before imports, referencing the correct mock instance, and verifying import paths.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : When testing CLI commands built with Commander.js, test the command action handlers directly rather than trying to mock the entire Commander.js chain.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Mock chalk functions to return the input text to make testing easier while still verifying correct function calls.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/**/*.test.js : Test core logic independently with both data formats, mock file system operations, test tag resolution behavior, and verify migration compatibility in unit tests.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:07:39.336Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/architecture.mdc:0-0
Timestamp: 2025-07-18T17:07:39.336Z
Learning: Module dependencies should be mocked before importing the test module, following Jest's hoisting behavior.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/**/*.test.js : Follow the mock-first-then-import pattern and use jest.spyOn() for testing in Jest, clearing mocks between tests.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:07:39.336Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/architecture.mdc:0-0
Timestamp: 2025-07-18T17:07:39.336Z
Learning: Mock external libraries (e.g., fs, commander, anthropic-ai/sdk) at the module level in tests.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Use sample task fixtures for consistent test data, mock file system operations, and test both success and error paths for task operations.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : For ES modules, use jest.mock() before static imports and jest.unstable_mockModule() before dynamic imports to mock dependencies.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Use mock-fs to mock file system operations in tests, and restore the file system after each test.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:07:53.100Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/changeset.mdc:0-0
Timestamp: 2025-07-18T17:07:53.100Z
Learning: Applies to .cursor/rules/** : Do not add a changeset for changes only to files within `.cursor/rules/` that solely guide internal development practices for this specific repository.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to .cursor/rules/*.mdc : Update relevant '.cursor/rules/*.mdc' files and include tagged system considerations in architecture docs when adding new features.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:10:12.881Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/dev_workflow.mdc:0-0
Timestamp: 2025-07-18T17:10:12.881Z
Learning: Applies to .*/rules/** : Each AI coding assistant rule profile (e.g., Claude Code, Cursor, Windsurf) creates its own directory (e.g., `.cursor/rules`, `.roo/rules`) with appropriate configuration files. Manage rule sets using the `task-master rules` commands.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:10:53.657Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/glossary.mdc:0-0
Timestamp: 2025-07-18T17:10:53.657Z
Learning: Guidelines for creating and maintaining Cursor rules to ensure consistency and effectiveness (cursor_rules.mdc).

Applied to files:

  • src/profiles/cursor.js
🧬 Code graph analysis (3)
tests/integration/profiles/cursor-init-functionality.test.js (1)
src/profiles/cursor.js (2)
  • cursorProfile (73-82)
  • cursorProfile (73-82)
tests/unit/profiles/cursor-integration.test.js (1)
src/profiles/cursor.js (2)
  • cursorProfile (73-82)
  • cursorProfile (73-82)
src/profiles/cursor.js (2)
src/utils/rule-transformer.js (6)
  • stats (398-398)
  • targetDir (185-185)
  • targetDir (204-204)
  • targetDir (332-332)
  • assetsDir (212-212)
  • assetsDir (307-307)
src/profiles/base-profile.js (1)
  • createProfile (27-243)
🪛 markdownlint-cli2 (0.17.2)
.changeset/cursor-slash-commands.md

5-5: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)


7-7: Files should end with a single newline character

(MD047, single-trailing-newline)

🔇 Additional comments (5)
src/profiles/cursor.js (2)

72-82: LGTM on profile wiring

Lifecycle hooks are correctly registered and Cursor keeps .mdc with subdirectories support.


84-85: LGTM on named exports

Publicly exposing lifecycle functions is helpful for tests and tooling.

tests/integration/profiles/cursor-init-functionality.test.js (1)

58-64: LGTM: lifecycle helpers presence checks

Good coverage ensuring helper and lifecycle function definitions exist.

tests/unit/profiles/cursor-integration.test.js (2)

28-31: Top‑level await in tests conflicts with “no async in tests” guideline; confirm exception

Project guidelines discourage async in tests. If we must use dynamic import for ESM/mocking order, switch to jest.unstable_mockModule + dynamic import inside beforeAll, and keep tests themselves synchronous.

Example structure:

-const { cursorProfile, onAddRulesProfile, onRemoveRulesProfile } = await import(
-	'../../../src/profiles/cursor.js'
-);
+beforeAll(async () => {
+	const mod = await import('../../../src/profiles/cursor.js');
+	global.__cursor = {
+		cursorProfile: mod.cursorProfile,
+		onAddRulesProfile: mod.onAddRulesProfile,
+		onRemoveRulesProfile: mod.onRemoveRulesProfile
+	};
+});

Then reference via __cursor.cursorProfile etc.


92-99: LGTM: verifies lifecycle export wiring

Good assertion that profile exports are wired to the named functions.

Copy link
Contributor

@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: 3

♻️ Duplicate comments (4)
.changeset/cursor-slash-commands.md (1)

5-7: Condense to a single, user-facing imperative summary; drop the extra line

Keep only one summary line per our changeset guideline; remove the generic line and retain the descriptive one. Ensure the file ends with a newline.

Apply:

-Add Cursor IDE custom slash command support
-
-Expose Task Master commands as Cursor slash commands by copying assets/claude/commands to .cursor/commands on profile add and cleaning up on remove.
+Expose Task Master commands as Cursor slash commands by copying assets/claude/commands to .cursor/commands on profile add and cleaning up on remove.
src/profiles/cursor.js (3)

57-65: Clean destination before copy to prevent stale/removed commands lingering

Overwrite-only copying won’t delete files removed upstream. Remove the dest dir first, then copy.

Apply:

 try {
-  copyRecursiveSync(commandsSourceDir, commandsDestDir);
+  // Ensure fresh state to avoid stale command files
+  fs.rmSync(commandsDestDir, { recursive: true, force: true });
+  fs.mkdirSync(commandsDestDir, { recursive: true });
+  copyRecursiveSync(commandsSourceDir, commandsDestDir);
   log('debug', `[Cursor] Copied commands directory to ${commandsDestDir}`);

68-74: Use the same profile-dir resolver on remove

Keep add/remove symmetric to avoid mismatched paths.

Apply:

-  const commandsDir = path.join(targetDir, '.cursor', 'commands');
+  const profileDir = resolveCursorProfileDir(targetDir);
+  const commandsDir = path.join(profileDir, 'commands');

43-48: Normalize target to the Cursor profile root to avoid nested ".cursor" paths

onAdd/onRemove receive either projectRoot or projectRoot + profile.rulesDir; resolve the Cursor profile directory first (e.g., add a resolveCursorProfileDir helper) and use that profile root when joining 'commands' in BOTH onAddRulesProfile and onRemoveRulesProfile in src/profiles/cursor.js. Call-site evidence: src/utils/rule-transformer.js calls profile.onAddRulesProfile(projectRoot, assetsDir) (line 213) and profile.onRemoveRulesProfile(projectRoot) (line 350); convertAllRulesToProfileRules computes targetDir = path.join(projectRoot, profile.rulesDir) (line 204).

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e1b3b45 and 041a941.

📒 Files selected for processing (2)
  • .changeset/cursor-slash-commands.md (1 hunks)
  • src/profiles/cursor.js (2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
.changeset/*.md

📄 CodeRabbit inference engine (.cursor/rules/changeset.mdc)

.changeset/*.md: When running npm run changeset or npx changeset add, provide a concise summary of the changes for the CHANGELOG.md in imperative mood, typically a single line, and not a detailed Git commit message.
The changeset summary should be user-facing, describing what changed in the released version that is relevant to users or consumers of the package.
Do not use your detailed Git commit message body as the changeset summary.

Files:

  • .changeset/cursor-slash-commands.md
.changeset/*

📄 CodeRabbit inference engine (.cursor/rules/new_features.mdc)

Create appropriate changesets for new features, use semantic versioning, include tagged system information in release notes, and document breaking changes if any.

Files:

  • .changeset/cursor-slash-commands.md
**/*.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

**/*.js: Declare and initialize global variables at the top of modules to avoid hoisting issues.
Use proper function declarations to avoid hoisting issues and initialize variables before they are referenced.
Do not reference variables before their declaration in module scope.
Use dynamic imports (import()) to avoid initialization order issues in modules.

Files:

  • src/profiles/cursor.js
🧠 Learnings (16)
📓 Common learnings
Learnt from: joedanz
PR: eyaltoledano/claude-task-master#1186
File: src/profiles/cursor.js:37-43
Timestamp: 2025-09-17T19:28:51.448Z
Learning: In the eyaltoledano/claude-task-master repository cursor profile implementation, the onAdd lifecycle hook sources command files from 'assets/claude/commands' and transforms them for Cursor IDE compatibility, rather than using separate cursor-specific command files.
📚 Learning: 2025-09-17T19:28:51.448Z
Learnt from: joedanz
PR: eyaltoledano/claude-task-master#1186
File: src/profiles/cursor.js:37-43
Timestamp: 2025-09-17T19:28:51.448Z
Learning: In the eyaltoledano/claude-task-master repository cursor profile implementation, the onAdd lifecycle hook sources command files from 'assets/claude/commands' and transforms them for Cursor IDE compatibility, rather than using separate cursor-specific command files.

Applied to files:

  • .changeset/cursor-slash-commands.md
  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:07:53.100Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/changeset.mdc:0-0
Timestamp: 2025-07-18T17:07:53.100Z
Learning: Applies to .cursor/rules/** : Do not add a changeset for changes only to files within `.cursor/rules/` that solely guide internal development practices for this specific repository.

Applied to files:

  • .changeset/cursor-slash-commands.md
  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:07:53.100Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/changeset.mdc:0-0
Timestamp: 2025-07-18T17:07:53.100Z
Learning: Applies to .changeset/*.md : When running `npm run changeset` or `npx changeset add`, provide a concise summary of the changes for the `CHANGELOG.md` in imperative mood, typically a single line, and not a detailed Git commit message.

Applied to files:

  • .changeset/cursor-slash-commands.md
📚 Learning: 2025-08-02T14:54:52.216Z
Learnt from: eyaltoledano
PR: eyaltoledano/claude-task-master#1069
File: .changeset/floppy-news-buy.md:7-38
Timestamp: 2025-08-02T14:54:52.216Z
Learning: For major feature additions like new CLI commands, eyaltoledano prefers detailed changesets with comprehensive descriptions, usage examples, and feature explanations rather than minimal single-line summaries.

Applied to files:

  • .changeset/cursor-slash-commands.md
📚 Learning: 2025-08-11T12:30:23.843Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-11T12:30:23.843Z
Learning: Import Task Master's development workflow commands and guidelines; treat the contents of ./.taskmaster/CLAUDE.md as if included in the main CLAUDE.md

Applied to files:

  • .changeset/cursor-slash-commands.md
📚 Learning: 2025-09-01T09:55:15.061Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: assets/AGENTS.md:0-0
Timestamp: 2025-09-01T09:55:15.061Z
Learning: Applies to assets/.claude/commands/taskmaster-complete.md : Create .claude/commands/taskmaster-complete.md implementing the 5-step task completion workflow

Applied to files:

  • .changeset/cursor-slash-commands.md
📚 Learning: 2025-07-18T17:09:28.215Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/cursor_rules.mdc:0-0
Timestamp: 2025-07-18T17:09:28.215Z
Learning: Applies to .cursor/rules/*.mdc : Maintain Cursor rule files by updating them when new patterns emerge, adding examples from the actual codebase, removing outdated patterns, and cross-referencing related rules.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to .cursor/rules/*.mdc : Update relevant '.cursor/rules/*.mdc' files and include tagged system considerations in architecture docs when adding new features.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:11:36.732Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/mcp.mdc:0-0
Timestamp: 2025-07-18T17:11:36.732Z
Learning: Applies to mcp-server/src/core/direct-functions/*.js : Use path.join() instead of string concatenation for file paths, and follow established file naming conventions (e.g., 'task_001.txt') in direct functions.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:10:12.881Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/dev_workflow.mdc:0-0
Timestamp: 2025-07-18T17:10:12.881Z
Learning: Applies to .*/rules/** : Each AI coding assistant rule profile (e.g., Claude Code, Cursor, Windsurf) creates its own directory (e.g., `.cursor/rules`, `.roo/rules`) with appropriate configuration files. Manage rule sets using the `task-master rules` commands.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:09:28.215Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/cursor_rules.mdc:0-0
Timestamp: 2025-07-18T17:09:28.215Z
Learning: Applies to .cursor/rules/*.mdc : Cursor rules should start with a high-level overview, include specific actionable requirements, show examples of correct implementation, reference existing code when possible, and keep rules DRY by referencing other rules.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:08:48.695Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/commands.mdc:0-0
Timestamp: 2025-07-18T17:08:48.695Z
Learning: Applies to scripts/modules/commands.js : Suggest non-destructive alternatives when appropriate, explain the difference between deletion and status changes, and include examples of alternative commands.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-31T22:07:49.716Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/commands.mdc:0-0
Timestamp: 2025-07-31T22:07:49.716Z
Learning: Applies to scripts/modules/commands.js : Suggest non-destructive alternatives when appropriate, explaining the difference between deletion and status changes, and include examples of alternative commands.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:09:23.831Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/cursor_rules.mdc:0-0
Timestamp: 2025-07-18T17:09:23.831Z
Learning: Applies to .cursor/rules/*.mdc : Cursor rule files must follow the required structure: a YAML frontmatter block with description, globs, and alwaysApply fields, followed by main points in bold, sub-points, and examples/explanations in markdown.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:10:53.657Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/glossary.mdc:0-0
Timestamp: 2025-07-18T17:10:53.657Z
Learning: Guidelines for creating and maintaining Cursor rules to ensure consistency and effectiveness (cursor_rules.mdc).

Applied to files:

  • src/profiles/cursor.js
🧬 Code graph analysis (1)
src/profiles/cursor.js (5)
src/profiles/roo.js (5)
  • src (36-36)
  • dest (37-37)
  • exists (52-52)
  • stats (53-53)
  • isDirectory (54-54)
src/profiles/claude.js (3)
  • exists (9-9)
  • stats (10-10)
  • isDirectory (11-11)
src/utils/rule-transformer.js (6)
  • stats (398-398)
  • targetDir (185-185)
  • targetDir (204-204)
  • targetDir (332-332)
  • assetsDir (212-212)
  • assetsDir (307-307)
scripts/modules/task-manager/migrate.js (1)
  • dirPath (267-267)
scripts/init.js (1)
  • targetDir (567-567)
🪛 markdownlint-cli2 (0.17.2)
.changeset/cursor-slash-commands.md

5-5: First line in a file should be a top-level heading

(MD041, first-line-heading, first-line-h1)

Copy link
Contributor

@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: 4

Caution

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

⚠️ Outside diff range comments (1)
src/utils/rule-transformer.js (1)

350-355: Cleanup hook OK — fix Node compatibility for fs.readdirSync({ recursive: true })

fs.readdirSync(..., { recursive: true }) is used in src/utils/rule-transformer.js at lines 403 and 414 while package.json lists engines.node = ">=18.0.0". The recursive option was added in Node v18.17.0 (and v20.1.0); some 18.x releases have reported buggy behaviour. (nodejs.org)

  • Options:
    • Bump engines.node to ">=18.17.0" (or ">=20.1.0") to guarantee support.
    • Or replace these calls with a small recursive walker using fs.readdirSync(..., { withFileTypes: true }) (the helper suggested in the original comment is fine).

Locations: src/utils/rule-transformer.js:403, 414; package.json (engines.node = ">=18.0.0").

♻️ Duplicate comments (3)
tests/integration/profiles/cursor-init-functionality.test.js (1)

66-85: Nice: resilient path assertions

Switch to resolveCursorProfileDir and regex for path.join(..., 'commands') removes brittle string-coupling. This addresses the earlier nit.

tests/unit/profiles/cursor-integration.test.js (2)

11-22: Console mocking and restore look correct

Restores original console in afterAll; prevents leakage.


105-137: LGTM: per-test restoration of fs spies

afterEach(jest.restoreAllMocks) ensures isolation.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 041a941 and 9b4b371.

📒 Files selected for processing (4)
  • src/profiles/cursor.js (2 hunks)
  • src/utils/rule-transformer.js (3 hunks)
  • tests/integration/profiles/cursor-init-functionality.test.js (1 hunks)
  • tests/unit/profiles/cursor-integration.test.js (2 hunks)
🧰 Additional context used
📓 Path-based instructions (11)
**/*.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

**/*.js: Declare and initialize global variables at the top of modules to avoid hoisting issues.
Use proper function declarations to avoid hoisting issues and initialize variables before they are referenced.
Do not reference variables before their declaration in module scope.
Use dynamic imports (import()) to avoid initialization order issues in modules.

Files:

  • src/utils/rule-transformer.js
  • src/profiles/cursor.js
  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
{src/utils/**,src/middleware/**}

📄 CodeRabbit inference engine (.cursor/rules/test_workflow.mdc)

Test coverage for all code should meet or exceed 80% lines/functions and 70% branches globally; critical code (utils, middleware) should meet higher thresholds (90% utils, 85% middleware)

Files:

  • src/utils/rule-transformer.js
tests/{unit,integration,e2e,fixtures}/**/*.js

📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)

Test files must be organized as follows: unit tests in tests/unit/, integration tests in tests/integration/, end-to-end tests in tests/e2e/, and test fixtures in tests/fixtures/.

Files:

  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
**/*.{test,spec}.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/git_workflow.mdc)

**/*.{test,spec}.{js,ts,jsx,tsx}: Create a test file and ensure all tests pass when all subtasks are complete; commit tests if added or modified
When all subtasks are complete, run final testing using the appropriate test runner (e.g., npm test, jest, or manual testing)

Files:

  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
**/*.test.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

**/*.test.js: Never use asynchronous operations in tests. Make all mocks return synchronous values when possible.
Always mock tests properly based on the way the tested functions are defined and used.
Follow the test file organization: mocks must be set up before importing modules under test, and spies on mocked modules should be set up after imports.
Use fixtures from tests/fixtures/ for consistent sample data across tests.
Always declare mocks before importing the modules being tested in Jest test files.
Use jest.spyOn() after imports to create spies on mock functions and reference these spies in test assertions.
When testing functions with callbacks, get the callback from your mock's call arguments, execute it directly with test inputs, and verify the results.
For ES modules, use jest.mock() before static imports and jest.unstable_mockModule() before dynamic imports to mock dependencies.
Reset mock functions (mockFn.mockReset()) before dynamic imports if they might have been called previously.
When verifying console assertions, assert against the actual arguments passed (single formatted string), not multiple arguments.
Use mock-fs to mock file system operations in tests, and restore the file system after each test.
Mock API calls (e.g., Anthropic/Claude) by mocking the entire module and providing predictable responses.
Set mock environment variables in test setup and restore them after each test.
Maintain test fixtures separate from test logic.
Follow the mock-first-then-import pattern for all Jest mocks.
Do not define mock variables before jest.mock() calls (they won't be accessible due to hoisting).
Use test-specific file paths (e.g., 'test-tasks.json') for all file operations in tests.
Mock readJSON and writeJSON to avoid real file system interactions in tests.
Verify file operations use the correct paths in expect statements.
Use different file paths for each test to avoid test interdependence.
Verify modifications on the in-memory task objects passed to w...

Files:

  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
tests/integration/**/*.test.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

Integration tests must be located in tests/integration/, test interactions between modules, and focus on component interfaces rather than implementation details.

Files:

  • tests/integration/profiles/cursor-init-functionality.test.js
tests/{unit,integration,e2e}/**/*.test.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

tests/{unit,integration,e2e}/**/*.test.js: When testing CLI commands built with Commander.js, test the command action handlers directly rather than trying to mock the entire Commander.js chain.
When mocking the Commander.js chain, mock ALL chainable methods (option, argument, action, on, etc.) and return this (or the mock object) from all chainable method mocks.
Explicitly handle all options, including defaults and shorthand flags (e.g., -p for --prompt), and include null/undefined checks in test implementations for parameters that might be optional.
Do not try to use the real action implementation without proper mocking, and do not mock Commander partially—either mock it completely or test the action directly.
Mock the action handlers for CLI commands and verify they're called with correct arguments.
Use sample task fixtures for consistent test data, mock file system operations, and test both success and error paths for task operations.
Mock console output and verify correct formatting in UI function tests. Use flexible assertions like toContain() or toMatch() for formatted output.
Mock chalk functions to return the input text to make testing easier while still verifying correct function calls.

Files:

  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
tests/{integration,e2e}/**/*.test.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

Properly mock session objects when required by functions, and reset environment variables between tests if modified.

Files:

  • tests/integration/profiles/cursor-init-functionality.test.js
**/*.{test,spec}.*

📄 CodeRabbit inference engine (.cursor/rules/test_workflow.mdc)

Test files should follow naming conventions: .test., .spec., or _test. depending on the language

Files:

  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
tests/{unit,integration,e2e}/**

📄 CodeRabbit inference engine (.cursor/rules/test_workflow.mdc)

Organize test directories by test type (unit, integration, e2e) and mirror source structure where possible

Files:

  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
tests/unit/**/*.test.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

tests/unit/**/*.test.js: Unit tests must be located in tests/unit/, test individual functions and utilities in isolation, mock all external dependencies, and keep tests small, focused, and fast.
Do not include actual command execution in unit tests.

Files:

  • tests/unit/profiles/cursor-integration.test.js
🧠 Learnings (33)
📓 Common learnings
Learnt from: joedanz
PR: eyaltoledano/claude-task-master#1186
File: src/profiles/cursor.js:37-43
Timestamp: 2025-09-17T19:28:51.448Z
Learning: In the eyaltoledano/claude-task-master repository cursor profile implementation, the onAdd lifecycle hook sources command files from 'assets/claude/commands' and transforms them for Cursor IDE compatibility, rather than using separate cursor-specific command files.
📚 Learning: 2025-09-17T19:28:51.448Z
Learnt from: joedanz
PR: eyaltoledano/claude-task-master#1186
File: src/profiles/cursor.js:37-43
Timestamp: 2025-09-17T19:28:51.448Z
Learning: In the eyaltoledano/claude-task-master repository cursor profile implementation, the onAdd lifecycle hook sources command files from 'assets/claude/commands' and transforms them for Cursor IDE compatibility, rather than using separate cursor-specific command files.

Applied to files:

  • src/profiles/cursor.js
  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:09:28.215Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/cursor_rules.mdc:0-0
Timestamp: 2025-07-18T17:09:28.215Z
Learning: Applies to .cursor/rules/*.mdc : Maintain Cursor rule files by updating them when new patterns emerge, adding examples from the actual codebase, removing outdated patterns, and cross-referencing related rules.

Applied to files:

  • src/profiles/cursor.js
  • tests/integration/profiles/cursor-init-functionality.test.js
📚 Learning: 2025-07-18T17:07:53.100Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/changeset.mdc:0-0
Timestamp: 2025-07-18T17:07:53.100Z
Learning: Applies to .cursor/rules/** : Do not add a changeset for changes only to files within `.cursor/rules/` that solely guide internal development practices for this specific repository.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to .cursor/rules/*.mdc : Update relevant '.cursor/rules/*.mdc' files and include tagged system considerations in architecture docs when adding new features.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:11:36.732Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/mcp.mdc:0-0
Timestamp: 2025-07-18T17:11:36.732Z
Learning: Applies to mcp-server/src/core/direct-functions/*.js : Use path.join() instead of string concatenation for file paths, and follow established file naming conventions (e.g., 'task_001.txt') in direct functions.

Applied to files:

  • src/profiles/cursor.js
  • tests/integration/profiles/cursor-init-functionality.test.js
📚 Learning: 2025-07-18T17:10:12.881Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/dev_workflow.mdc:0-0
Timestamp: 2025-07-18T17:10:12.881Z
Learning: Applies to .*/rules/** : Each AI coding assistant rule profile (e.g., Claude Code, Cursor, Windsurf) creates its own directory (e.g., `.cursor/rules`, `.roo/rules`) with appropriate configuration files. Manage rule sets using the `task-master rules` commands.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:09:28.215Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/cursor_rules.mdc:0-0
Timestamp: 2025-07-18T17:09:28.215Z
Learning: Applies to .cursor/rules/*.mdc : Cursor rules should start with a high-level overview, include specific actionable requirements, show examples of correct implementation, reference existing code when possible, and keep rules DRY by referencing other rules.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:08:48.695Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/commands.mdc:0-0
Timestamp: 2025-07-18T17:08:48.695Z
Learning: Applies to scripts/modules/commands.js : Suggest non-destructive alternatives when appropriate, explain the difference between deletion and status changes, and include examples of alternative commands.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-31T22:07:49.716Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/commands.mdc:0-0
Timestamp: 2025-07-31T22:07:49.716Z
Learning: Applies to scripts/modules/commands.js : Suggest non-destructive alternatives when appropriate, explaining the difference between deletion and status changes, and include examples of alternative commands.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:09:23.831Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/cursor_rules.mdc:0-0
Timestamp: 2025-07-18T17:09:23.831Z
Learning: Applies to .cursor/rules/*.mdc : Cursor rule files must follow the required structure: a YAML frontmatter block with description, globs, and alwaysApply fields, followed by main points in bold, sub-points, and examples/explanations in markdown.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:10:53.657Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/glossary.mdc:0-0
Timestamp: 2025-07-18T17:10:53.657Z
Learning: Guidelines for creating and maintaining Cursor rules to ensure consistency and effectiveness (cursor_rules.mdc).

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Verify file operations use the correct paths in expect statements.

Applied to files:

  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Mock the action handlers for CLI commands and verify they're called with correct arguments.

Applied to files:

  • tests/integration/profiles/cursor-init-functionality.test.js
  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Do not import real AI service clients in tests; create fully mocked versions that return predictable responses.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{integration,e2e}/**/*.test.js : Properly mock session objects when required by functions, and reset environment variables between tests if modified.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Mock console output and verify correct formatting in UI function tests. Use flexible assertions like toContain() or toMatch() for formatted output.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Do not try to use the real action implementation without proper mocking, and do not mock Commander partially—either mock it completely or test the action directly.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Troubleshoot mock functions not being called by ensuring mocks are defined before imports, referencing the correct mock instance, and verifying import paths.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : When testing CLI commands built with Commander.js, test the command action handlers directly rather than trying to mock the entire Commander.js chain.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/**/*.test.js : Test core logic independently with both data formats, mock file system operations, test tag resolution behavior, and verify migration compatibility in unit tests.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Use mock-fs to mock file system operations in tests, and restore the file system after each test.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Mock chalk functions to return the input text to make testing easier while still verifying correct function calls.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Isolate tests by properly mocking shared resources and resetting state in beforeEach and afterEach hooks.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Clear mocks between tests with jest.clearAllMocks() in beforeEach.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Set mock environment variables in test setup and restore them after each test.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Be careful with how you mock or stub functions that depend on module state; use factory functions in mocks to ensure proper initialization order.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Always mock tests properly based on the way the tested functions are defined and used.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Use sample task fixtures for consistent test data, mock file system operations, and test both success and error paths for task operations.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/**/*.test.js : Follow the mock-first-then-import pattern and use jest.spyOn() for testing in Jest, clearing mocks between tests.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Follow the test file organization: mocks must be set up before importing modules under test, and spies on mocked modules should be set up after imports.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:07:39.336Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/architecture.mdc:0-0
Timestamp: 2025-07-18T17:07:39.336Z
Learning: Module dependencies should be mocked before importing the test module, following Jest's hoisting behavior.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Use jest.spyOn() after imports to create spies on mock functions and reference these spies in test assertions.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
🧬 Code graph analysis (4)
src/utils/rule-transformer.js (2)
scripts/init.js (1)
  • targetDir (567-567)
src/utils/asset-resolver.js (1)
  • assetsDir (65-65)
src/profiles/cursor.js (4)
src/profiles/roo.js (5)
  • src (36-36)
  • dest (37-37)
  • exists (52-52)
  • stats (53-53)
  • isDirectory (54-54)
src/profiles/claude.js (3)
  • exists (9-9)
  • stats (10-10)
  • isDirectory (11-11)
src/utils/rule-transformer.js (7)
  • stats (398-398)
  • targetDir (185-185)
  • targetDir (204-204)
  • targetDir (332-332)
  • assetsDir (212-212)
  • assetsDir (307-307)
  • profileDir (333-333)
src/utils/profiles.js (1)
  • profileDir (43-43)
tests/integration/profiles/cursor-init-functionality.test.js (1)
src/profiles/cursor.js (2)
  • cursorProfile (132-141)
  • cursorProfile (132-141)
tests/unit/profiles/cursor-integration.test.js (1)
src/profiles/cursor.js (2)
  • cursorProfile (132-141)
  • cursorProfile (132-141)
🔇 Additional comments (12)
src/utils/rule-transformer.js (2)

308-313: Post-conversion hook also aligned

onPostConvertRulesProfile now receives targetDir consistently. Good.


213-224: Approve — lifecycle hooks now receive targetDir across profiles Verified: all matched profile hook definitions declare targetDir as the first parameter and rule-transformer calls pass targetDir; package.json node engine is ">=18.0.0".

tests/integration/profiles/cursor-init-functionality.test.js (1)

58-64: LGTM: lifecycle helpers presence is asserted

Coverage for onAddRulesProfile/onRemoveRulesProfile and helper symbols looks good.

tests/unit/profiles/cursor-integration.test.js (6)

37-39: LGTM: console restored after suite


97-104: LGTM: lifecycle exports wired on profile


152-162: LGTM: missing source handled without side effects


164-176: LGTM: removal performs rmSync with recursive+force


178-187: LGTM: graceful no-op when directory absent


189-198: LGTM: removal errors are caught and do not throw

src/profiles/cursor.js (3)

7-52: Robust copy helper with cpSync fallback

Good use of fs.cpSync when available and safe fallback with TOCTOU handling.


81-120: onAddRulesProfile: correct source/dest resolution and clean replace

  • Uses resolveCursorProfileDir to avoid nested “.cursor”.
  • Cleans dest before copying; logs at warn for missing source. Solid.

138-140: LGTM: lifecycle hooks wired and exported

Also applies to: 143-145

Copy link
Contributor

@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: 2

Caution

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

⚠️ Outside diff range comments (1)
tests/unit/profiles/cursor-integration.test.js (1)

7-9: Remove unused child_process mock

Not used in this suite; drop to reduce noise.

-jest.mock('child_process', () => ({
-  execSync: jest.fn()
-}));
+// (unused) — remove mock
♻️ Duplicate comments (3)
tests/unit/profiles/cursor-integration.test.js (2)

23-33: ESM mocking/import order is correct

unstable_mockModule before dynamic import is the right pattern.


38-41: Console restore to avoid leakage

Restoring global.console in afterAll prevents cross‑suite bleed. Good.

src/profiles/cursor.js (1)

68-79: Optionally export resolver for reuse/tests

Exporting resolveCursorProfileDir avoids re-implementations and enables direct unit tests.

-// Resolve the Cursor profile directory from either project root, profile root, or rules dir
-function resolveCursorProfileDir(baseDir) {
+// Resolve the Cursor profile directory from either project root, profile root, or rules dir
+export function resolveCursorProfileDir(baseDir) {

And at the bottom:

-export { onAddRulesProfile, onRemoveRulesProfile };
+export { onAddRulesProfile, onRemoveRulesProfile, resolveCursorProfileDir };
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9b4b371 and b4599b8.

📒 Files selected for processing (2)
  • src/profiles/cursor.js (2 hunks)
  • tests/unit/profiles/cursor-integration.test.js (2 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
tests/{unit,integration,e2e,fixtures}/**/*.js

📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)

Test files must be organized as follows: unit tests in tests/unit/, integration tests in tests/integration/, end-to-end tests in tests/e2e/, and test fixtures in tests/fixtures/.

Files:

  • tests/unit/profiles/cursor-integration.test.js
**/*.{test,spec}.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (.cursor/rules/git_workflow.mdc)

**/*.{test,spec}.{js,ts,jsx,tsx}: Create a test file and ensure all tests pass when all subtasks are complete; commit tests if added or modified
When all subtasks are complete, run final testing using the appropriate test runner (e.g., npm test, jest, or manual testing)

Files:

  • tests/unit/profiles/cursor-integration.test.js
**/*.test.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

**/*.test.js: Never use asynchronous operations in tests. Make all mocks return synchronous values when possible.
Always mock tests properly based on the way the tested functions are defined and used.
Follow the test file organization: mocks must be set up before importing modules under test, and spies on mocked modules should be set up after imports.
Use fixtures from tests/fixtures/ for consistent sample data across tests.
Always declare mocks before importing the modules being tested in Jest test files.
Use jest.spyOn() after imports to create spies on mock functions and reference these spies in test assertions.
When testing functions with callbacks, get the callback from your mock's call arguments, execute it directly with test inputs, and verify the results.
For ES modules, use jest.mock() before static imports and jest.unstable_mockModule() before dynamic imports to mock dependencies.
Reset mock functions (mockFn.mockReset()) before dynamic imports if they might have been called previously.
When verifying console assertions, assert against the actual arguments passed (single formatted string), not multiple arguments.
Use mock-fs to mock file system operations in tests, and restore the file system after each test.
Mock API calls (e.g., Anthropic/Claude) by mocking the entire module and providing predictable responses.
Set mock environment variables in test setup and restore them after each test.
Maintain test fixtures separate from test logic.
Follow the mock-first-then-import pattern for all Jest mocks.
Do not define mock variables before jest.mock() calls (they won't be accessible due to hoisting).
Use test-specific file paths (e.g., 'test-tasks.json') for all file operations in tests.
Mock readJSON and writeJSON to avoid real file system interactions in tests.
Verify file operations use the correct paths in expect statements.
Use different file paths for each test to avoid test interdependence.
Verify modifications on the in-memory task objects passed to w...

Files:

  • tests/unit/profiles/cursor-integration.test.js
tests/unit/**/*.test.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

tests/unit/**/*.test.js: Unit tests must be located in tests/unit/, test individual functions and utilities in isolation, mock all external dependencies, and keep tests small, focused, and fast.
Do not include actual command execution in unit tests.

Files:

  • tests/unit/profiles/cursor-integration.test.js
tests/{unit,integration,e2e}/**/*.test.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

tests/{unit,integration,e2e}/**/*.test.js: When testing CLI commands built with Commander.js, test the command action handlers directly rather than trying to mock the entire Commander.js chain.
When mocking the Commander.js chain, mock ALL chainable methods (option, argument, action, on, etc.) and return this (or the mock object) from all chainable method mocks.
Explicitly handle all options, including defaults and shorthand flags (e.g., -p for --prompt), and include null/undefined checks in test implementations for parameters that might be optional.
Do not try to use the real action implementation without proper mocking, and do not mock Commander partially—either mock it completely or test the action directly.
Mock the action handlers for CLI commands and verify they're called with correct arguments.
Use sample task fixtures for consistent test data, mock file system operations, and test both success and error paths for task operations.
Mock console output and verify correct formatting in UI function tests. Use flexible assertions like toContain() or toMatch() for formatted output.
Mock chalk functions to return the input text to make testing easier while still verifying correct function calls.

Files:

  • tests/unit/profiles/cursor-integration.test.js
**/*.js

📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)

**/*.js: Declare and initialize global variables at the top of modules to avoid hoisting issues.
Use proper function declarations to avoid hoisting issues and initialize variables before they are referenced.
Do not reference variables before their declaration in module scope.
Use dynamic imports (import()) to avoid initialization order issues in modules.

Files:

  • tests/unit/profiles/cursor-integration.test.js
  • src/profiles/cursor.js
**/*.{test,spec}.*

📄 CodeRabbit inference engine (.cursor/rules/test_workflow.mdc)

Test files should follow naming conventions: .test., .spec., or _test. depending on the language

Files:

  • tests/unit/profiles/cursor-integration.test.js
tests/{unit,integration,e2e}/**

📄 CodeRabbit inference engine (.cursor/rules/test_workflow.mdc)

Organize test directories by test type (unit, integration, e2e) and mirror source structure where possible

Files:

  • tests/unit/profiles/cursor-integration.test.js
🧠 Learnings (36)
📓 Common learnings
Learnt from: joedanz
PR: eyaltoledano/claude-task-master#1186
File: src/profiles/cursor.js:37-43
Timestamp: 2025-09-17T19:28:51.448Z
Learning: In the eyaltoledano/claude-task-master repository cursor profile implementation, the onAdd lifecycle hook sources command files from 'assets/claude/commands' and transforms them for Cursor IDE compatibility, rather than using separate cursor-specific command files.
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{integration,e2e}/**/*.test.js : Properly mock session objects when required by functions, and reset environment variables between tests if modified.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Do not import real AI service clients in tests; create fully mocked versions that return predictable responses.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Mock console output and verify correct formatting in UI function tests. Use flexible assertions like toContain() or toMatch() for formatted output.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-09-17T19:28:51.448Z
Learnt from: joedanz
PR: eyaltoledano/claude-task-master#1186
File: src/profiles/cursor.js:37-43
Timestamp: 2025-09-17T19:28:51.448Z
Learning: In the eyaltoledano/claude-task-master repository cursor profile implementation, the onAdd lifecycle hook sources command files from 'assets/claude/commands' and transforms them for Cursor IDE compatibility, rather than using separate cursor-specific command files.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Do not try to use the real action implementation without proper mocking, and do not mock Commander partially—either mock it completely or test the action directly.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Troubleshoot mock functions not being called by ensuring mocks are defined before imports, referencing the correct mock instance, and verifying import paths.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/**/*.test.js : Test core logic independently with both data formats, mock file system operations, test tag resolution behavior, and verify migration compatibility in unit tests.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:09:28.215Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/cursor_rules.mdc:0-0
Timestamp: 2025-07-18T17:09:28.215Z
Learning: Applies to .cursor/rules/*.mdc : Maintain Cursor rule files by updating them when new patterns emerge, adding examples from the actual codebase, removing outdated patterns, and cross-referencing related rules.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Use mock-fs to mock file system operations in tests, and restore the file system after each test.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Mock chalk functions to return the input text to make testing easier while still verifying correct function calls.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Isolate tests by properly mocking shared resources and resetting state in beforeEach and afterEach hooks.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Clear mocks between tests with jest.clearAllMocks() in beforeEach.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Set mock environment variables in test setup and restore them after each test.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Be careful with how you mock or stub functions that depend on module state; use factory functions in mocks to ensure proper initialization order.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Always mock tests properly based on the way the tested functions are defined and used.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Use sample task fixtures for consistent test data, mock file system operations, and test both success and error paths for task operations.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Verify file operations use the correct paths in expect statements.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Mock the action handlers for CLI commands and verify they're called with correct arguments.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/**/*.test.js : Follow the mock-first-then-import pattern and use jest.spyOn() for testing in Jest, clearing mocks between tests.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Follow the test file organization: mocks must be set up before importing modules under test, and spies on mocked modules should be set up after imports.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : For ES modules, use jest.mock() before static imports and jest.unstable_mockModule() before dynamic imports to mock dependencies.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:07:39.336Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/architecture.mdc:0-0
Timestamp: 2025-07-18T17:07:39.336Z
Learning: Module dependencies should be mocked before importing the test module, following Jest's hoisting behavior.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Always declare mocks before importing the modules being tested in Jest test files.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Use jest.spyOn() after imports to create spies on mock functions and reference these spies in test assertions.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Follow the mock-first-then-import pattern for all Jest mocks.

Applied to files:

  • tests/unit/profiles/cursor-integration.test.js
📚 Learning: 2025-07-18T17:07:53.100Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/changeset.mdc:0-0
Timestamp: 2025-07-18T17:07:53.100Z
Learning: Applies to .cursor/rules/** : Do not add a changeset for changes only to files within `.cursor/rules/` that solely guide internal development practices for this specific repository.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to .cursor/rules/*.mdc : Update relevant '.cursor/rules/*.mdc' files and include tagged system considerations in architecture docs when adding new features.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:11:36.732Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/mcp.mdc:0-0
Timestamp: 2025-07-18T17:11:36.732Z
Learning: Applies to mcp-server/src/core/direct-functions/*.js : Use path.join() instead of string concatenation for file paths, and follow established file naming conventions (e.g., 'task_001.txt') in direct functions.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:10:12.881Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/dev_workflow.mdc:0-0
Timestamp: 2025-07-18T17:10:12.881Z
Learning: Applies to .*/rules/** : Each AI coding assistant rule profile (e.g., Claude Code, Cursor, Windsurf) creates its own directory (e.g., `.cursor/rules`, `.roo/rules`) with appropriate configuration files. Manage rule sets using the `task-master rules` commands.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:09:28.215Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/cursor_rules.mdc:0-0
Timestamp: 2025-07-18T17:09:28.215Z
Learning: Applies to .cursor/rules/*.mdc : Cursor rules should start with a high-level overview, include specific actionable requirements, show examples of correct implementation, reference existing code when possible, and keep rules DRY by referencing other rules.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:08:48.695Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/commands.mdc:0-0
Timestamp: 2025-07-18T17:08:48.695Z
Learning: Applies to scripts/modules/commands.js : Suggest non-destructive alternatives when appropriate, explain the difference between deletion and status changes, and include examples of alternative commands.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-31T22:07:49.716Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/commands.mdc:0-0
Timestamp: 2025-07-31T22:07:49.716Z
Learning: Applies to scripts/modules/commands.js : Suggest non-destructive alternatives when appropriate, explaining the difference between deletion and status changes, and include examples of alternative commands.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:08:48.695Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/commands.mdc:0-0
Timestamp: 2025-07-18T17:08:48.695Z
Learning: Applies to scripts/modules/commands.js : Use path.join() to construct file paths, follow established naming conventions (like task_001.txt), check file existence before deletion, and handle file deletion errors gracefully.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:09:23.831Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/cursor_rules.mdc:0-0
Timestamp: 2025-07-18T17:09:23.831Z
Learning: Applies to .cursor/rules/*.mdc : Cursor rule files must follow the required structure: a YAML frontmatter block with description, globs, and alwaysApply fields, followed by main points in bold, sub-points, and examples/explanations in markdown.

Applied to files:

  • src/profiles/cursor.js
📚 Learning: 2025-07-18T17:10:53.657Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/glossary.mdc:0-0
Timestamp: 2025-07-18T17:10:53.657Z
Learning: Guidelines for creating and maintaining Cursor rules to ensure consistency and effectiveness (cursor_rules.mdc).

Applied to files:

  • src/profiles/cursor.js
🧬 Code graph analysis (2)
tests/unit/profiles/cursor-integration.test.js (1)
src/profiles/cursor.js (2)
  • cursorProfile (135-144)
  • cursorProfile (135-144)
src/profiles/cursor.js (4)
src/profiles/roo.js (5)
  • src (36-36)
  • dest (37-37)
  • exists (52-52)
  • stats (53-53)
  • isDirectory (54-54)
src/profiles/claude.js (3)
  • exists (9-9)
  • stats (10-10)
  • isDirectory (11-11)
src/utils/rule-transformer.js (7)
  • stats (398-398)
  • targetDir (185-185)
  • targetDir (204-204)
  • targetDir (332-332)
  • assetsDir (212-212)
  • assetsDir (307-307)
  • profileDir (333-333)
src/utils/profiles.js (1)
  • profileDir (43-43)
🔇 Additional comments (4)
src/profiles/cursor.js (4)

32-51: Manual copy fallback looks solid

Good TOCTOU handling and parent mkdir for files. No changes needed.


88-95: Correct severity for missing source

Downgrading to warn is appropriate; early-return is right.


122-132: Idempotent remove with clear logging

Good: uses resolver, handles missing dirs, and logs idempotently.


135-144: Profile wiring LGTM

Hooks are correctly attached via createProfile; subdirectory support flag set.

@Crunchyman-ralph Crunchyman-ralph merged commit 0079b7d into eyaltoledano:next Sep 26, 2025
4 checks passed
github-actions bot added a commit that referenced this pull request Sep 26, 2025
  This PR was automatically generated to update documentation based on recent changes.

  Original commit: feat: Add Cursor IDE custom slash commands support (#1215)\n\n\n

  Co-authored-by: Claude <claude-assistant@anthropic.com>
@coderabbitai coderabbitai bot mentioned this pull request Oct 4, 2025
16 tasks
@github-actions github-actions bot mentioned this pull request Oct 7, 2025
@coderabbitai coderabbitai bot mentioned this pull request Nov 29, 2025
16 tasks
sfc-gh-dflippo pushed a commit to sfc-gh-dflippo/task-master-ai that referenced this pull request Dec 4, 2025
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.

2 participants