feat: Add Cursor IDE custom slash commands support#1186
feat: Add Cursor IDE custom slash commands support#1186joedanz wants to merge 50 commits intoeyaltoledano:nextfrom
Conversation
🦋 Changeset detectedLatest commit: 42167b7 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 |
WalkthroughAdds Cursor profile lifecycle hooks that provision and remove Task Master slash-command files under Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Dev as Developer
participant CLI as CLI
participant Cursor as Cursor Profile
participant RT as Rule Transformer
participant FS as Filesystem
rect rgb(245,248,255)
note over Dev,CLI: Provision (onAdd)
Dev->>CLI: add cursor profile
CLI->>Cursor: onAdd(projectRoot, assetsDir)
Cursor->>FS: copyRecursiveWithTransform(assets/claude/commands → .cursor/commands)
note right of Cursor: transform Claude → Cursor syntax\ncount markdown files copied
Cursor-->>CLI: { success, failed, fileCount }
end
rect rgb(255,248,245)
note over Dev,CLI: Cleanup (onRemove)
Dev->>CLI: remove cursor profile
CLI->>RT: removeProfileRules(cursor)
RT->>Cursor: onRemove(projectRoot)
Cursor->>FS: enumerate & delete .cursor/commands/*.md
Cursor-->>RT: { success, failed, fileCount }
RT->>FS: delete remaining rule files
RT-->>CLI: { fileCount = commands + rules, failedFiles, fileRemoveFailures, ... }
CLI->>CLI: if fileCount>0 log "Total: X files processed - Y removed" else profile-based totals
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
Comment |
There was a problem hiding this comment.
Actionable comments posted: 116
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
package.json (1)
13-27: Add missing test scripts per repo guidelines.Include unit/integration split and CI entry to align with .cursor rules.
"scripts": { "test": "node --experimental-vm-modules node_modules/.bin/jest", "test:fails": "node --experimental-vm-modules node_modules/.bin/jest --onlyFailures", "test:watch": "node --experimental-vm-modules node_modules/.bin/jest --watch", "test:coverage": "node --experimental-vm-modules node_modules/.bin/jest --coverage", + "test:unit": "node --experimental-vm-modules node_modules/.bin/jest --runTestsByPath tests/unit", + "test:integration": "node --experimental-vm-modules node_modules/.bin/jest --runTestsByPath tests/integration", + "test:ci": "node --experimental-vm-modules node_modules/.bin/jest --coverage --ci", "test:e2e": "./tests/e2e/run_e2e.sh", "test:e2e-report": "./tests/e2e/run_e2e.sh --analyze-log", "prepare": "chmod +x bin/task-master.js mcp-server/server.js", "changeset": "changeset", "release": "changeset publish", "inspector": "npx @modelcontextprotocol/inspector node mcp-server/server.js", "mcp-server": "node mcp-server/server.js", "format-check": "biome format .", "format": "biome format . --write" },src/utils/rule-transformer.js (1)
408-415: fs.readdirSync does not support { recursive: true }; remainingFiles detection is unreliable.Replace this with a small recursive lister using withFileTypes to avoid missed subfiles and runtime incompatibilities:
- const allFiles = fs.readdirSync(targetDir, { recursive: true }); - const allFilePaths = allFiles - .filter((file) => { - const fullPath = path.join(targetDir, file); - return fs.statSync(fullPath).isFile(); - }) - .map((file) => file.toString()); + function listFilesRecursively(dir) { + const entries = fs.readdirSync(dir, { withFileTypes: true }); + const files = []; + for (const e of entries) { + const full = path.join(dir, e.name); + if (e.isDirectory()) files.push(...listFilesRecursively(full)); + else if (e.isFile()) files.push(full); + } + return files; + } + const allFilePaths = listFilesRecursively(targetDir).map((p) => + path.relative(targetDir, p) + );
There was a problem hiding this comment.
about to merge into next typescript support, think you can move this command apps/cli ?
There was a problem hiding this comment.
Not sure what you are looking for here..
There was a problem hiding this comment.
Actionable comments posted: 3
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/selective-profile-removal.test.js (1)
44-45: Avoid creating a real temp directory in a unit test (not used).This test doesn’t use tempDir; remove the mkdtempSync and cleanup to keep tests hermetic.
- // Create temp directory for testing - tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'task-master-test-')); @@ - // Clean up temp directory - try { - fs.rmSync(tempDir, { recursive: true, force: true }); - } catch (error) { - // Ignore cleanup errors - } + // No temp directory needed; all FS ops are mocked.Also applies to: 78-83
♻️ Duplicate comments (5)
src/profiles/cursor.js (4)
3-4: Fix ESM imports for Node core modules (runtime error risk).Use namespace imports for built-ins to avoid default-import pitfalls in native ESM. This mirrors the rest of the codebase patterns and prior guidance.
-import fs from 'fs'; -import path from 'path'; +import * as fs from 'node:fs'; +import * as path from 'node:path';
12-12: Drop redundant exists check before mkdirSync (idempotent with recursive).- if (!fs.existsSync(dest)) fs.mkdirSync(dest, { recursive: true }); + fs.mkdirSync(dest, { recursive: true });
42-57: Copy only Task Master command files and return fileCount; support both flat tm-*.md and legacy tm/ tree.
- Limit copying to tm-*.md to avoid dragging non-command docs (symmetry with removal).
- Return fileCount to align with rule-transformer aggregation and test expectations.
- // Transform function for Claude -> Cursor syntax - const transform = (content) => - content - .replace(/\/project:tm\//g, 'tm/') - .replace( - /Type '\/project:tm\/' and use tab completion/g, - "Type 'tm/' and use tab completion" - ); - - console.log(`[INFO] Adding Task Master slash commands to .cursor/commands`); - const count = copyRecursiveWithTransform(sourceDir, targetDir, transform); - console.log( - `[SUCCESS] Added ${count} Task Master slash commands to Cursor IDE` - ); - return { success: count, failed: 0 }; + // Optional transform: no-op for preconverted Cursor files; still normalize if legacy markers exist. + const transform = (content) => + content + .replace(/\/project:tm\//g, 'tm/') + .replace(/Type '\/project:tm\/' and use tab completion/g, "Type 'tm/' and use tab completion"); + + console.log(`[INFO] Adding Task Master slash commands to .cursor/commands`); + fs.mkdirSync(targetDir, { recursive: true }); + + let successCount = 0; + + // Copy flat files pattern: tm-*.md at the root of assets/cursor/commands + const items = fs.readdirSync(sourceDir); + const flatFiles = items.filter((f) => f.startsWith('tm-') && f.endsWith('.md')); + for (const file of flatFiles) { + const src = path.join(sourceDir, file); + const dest = path.join(targetDir, file); + const content = fs.readFileSync(src, 'utf8'); + fs.writeFileSync(dest, transform(content), 'utf8'); + successCount++; + } + + // Back-compat: if a legacy `tm/` directory exists under source, copy it recursively. + const legacyTmSrc = path.join(sourceDir, 'tm'); + if (fs.existsSync(legacyTmSrc) && fs.statSync(legacyTmSrc).isDirectory()) { + successCount += copyRecursiveWithTransform(legacyTmSrc, path.join(targetDir, 'tm'), transform); + } + + console.log(`[SUCCESS] Added ${successCount} Task Master slash commands to Cursor IDE`); + return { success: successCount, failed: 0, fileCount: successCount };
59-91: Handle both removal patterns (flat tm-*.md and tm/ tree) and include fileCount in returns.Currently only removing .cursor/commands/tm leaves flat tm-*.md commands orphaned. Also, lifecycle hooks should return fileCount for accurate summaries.
-const onRemove = (projectRoot) => { - const tmDir = path.join(projectRoot, '.cursor', 'commands', 'tm'); - - if (!fs.existsSync(tmDir)) { - console.log(`[INFO] No Task Master commands found to remove`); - return { success: 0, failed: 0 }; - } - - try { - // Count .md files recursively - let count = 0; - const countFiles = (dir) => { - fs.readdirSync(dir).forEach((item) => { - const fullPath = path.join(dir, item); - if (fs.statSync(fullPath).isDirectory()) { - countFiles(fullPath); - } else if (item.endsWith('.md')) { - count++; - } - }); - }; - countFiles(tmDir); - - console.log(`[INFO] Removing ${count} Task Master slash commands`); - fs.rmSync(tmDir, { recursive: true, force: true }); - console.log( - `[SUCCESS] Removed ${count} Task Master slash commands from Cursor IDE` - ); - return { success: count, failed: 0 }; - } catch (error) { - console.warn(`Failed to remove commands: ${error.message}`); - return { success: 0, failed: 1 }; - } -}; +const onRemove = (projectRoot) => { + const commandsDir = path.join(projectRoot, '.cursor', 'commands'); + const tmDir = path.join(commandsDir, 'tm'); + + if (!fs.existsSync(commandsDir) && !fs.existsSync(tmDir)) { + console.log(`[INFO] No Task Master commands found to remove`); + return { success: 0, failed: 0, fileCount: 0 }; + } + + try { + // Collect flat tm-*.md files (Cursor-native) at commands root + const flatFiles = + fs.existsSync(commandsDir) && fs.statSync(commandsDir).isDirectory() + ? fs + .readdirSync(commandsDir) + .filter((f) => f.startsWith('tm-') && f.endsWith('.md')) + .map((f) => path.join(commandsDir, f)) + : []; + + // Count legacy tm/ tree .md files + let legacyCount = 0; + const countFiles = (dir) => { + for (const item of fs.readdirSync(dir)) { + const fullPath = path.join(dir, item); + if (fs.statSync(fullPath).isDirectory()) countFiles(fullPath); + else if (item.endsWith('.md')) legacyCount++; + } + }; + if (fs.existsSync(tmDir) && fs.statSync(tmDir).isDirectory()) { + countFiles(tmDir); + } + + const total = flatFiles.length + legacyCount; + if (total === 0) { + console.log(`[INFO] No Task Master commands found to remove`); + return { success: 0, failed: 0, fileCount: 0 }; + } + + console.log(`[INFO] Removing ${total} Task Master slash commands`); + + // Remove flat files + for (const filePath of flatFiles) { + fs.rmSync(filePath, { force: true }); + } + // Remove legacy tm/ directory (if present) + if (legacyCount > 0) { + fs.rmSync(tmDir, { recursive: true, force: true }); + } + + console.log( + `[SUCCESS] Removed ${total} Task Master slash commands from Cursor IDE` + ); + return { success: total, failed: 0, fileCount: total }; + } catch (error) { + console.warn(`Failed to remove commands: ${error.message}`); + // We cannot know exactly how many failed; return total candidates as fileCount for summaries. + return { success: 0, failed: 1, fileCount: 0 }; + } +};tests/unit/profiles/selective-profile-removal.test.js (1)
33-33: Remove unused fs.unlinkSync spy.unlinkSync isn’t exercised; rmSync covers deletions. Delete the variable and spy to reduce noise.
- let mockUnlinkSync; @@ - mockUnlinkSync = jest.spyOn(fs, 'unlinkSync').mockImplementation(() => {});Also applies to: 71-71
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
src/profiles/cursor.js(2 hunks)tests/unit/profiles/selective-profile-removal.test.js(18 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.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.jstests/unit/profiles/selective-profile-removal.test.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/unit/profiles/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/unit/profiles/selective-profile-removal.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/selective-profile-removal.test.js
🧠 Learnings (40)
📓 Common learnings
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 : 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.
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.
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.
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.
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).
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 continuously improving Cursor rules based on emerging code patterns and best practices (self_improve.mdc).
📚 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 : 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: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-09-02T21:51:27.921Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/src/auth/config.ts:5-7
Timestamp: 2025-09-02T21:51:27.921Z
Learning: The user Crunchyman-ralph prefers not to use node: scheme imports (e.g., 'node:os', 'node:path') for Node.js core modules and considers suggestions to change bare imports to node: scheme as too nitpicky.
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 **/*.js : Use dynamic imports (import()) to avoid initialization order issues in modules.
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.jstests/unit/profiles/selective-profile-removal.test.js
📚 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/.taskmaster/tasks/*.{md,txt} : Treat task files in .taskmaster/tasks (md or txt) as auto-generated; avoid manual edits
Applied to files:
src/profiles/cursor.js
📚 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:
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: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: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 : When referencing files in Cursor rule files, use the format [filename](mdc:path/to/file) or [filename](mdc:filename).
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 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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/**/*.test.js : Do not include actual command execution in unit tests.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 modifications on the in-memory task objects passed to writeJSON.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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 CLI and MCP interfaces with real task data, verify end-to-end workflows across tag contexts, and test error scenarios and recovery in integration tests.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 : 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.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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 : Mock readJSON and writeJSON to avoid real file system interactions in tests.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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 : Mock API calls (e.g., Anthropic/Claude) by mocking the entire module and providing predictable responses.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.test.js
📚 Learning: 2025-07-18T17:10:31.810Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/git_workflow.mdc:0-0
Timestamp: 2025-07-18T17:10:31.810Z
Learning: Applies to **/*.{test,spec}.{js,ts,jsx,tsx} : Create a test file if needed and ensure all tests pass before completing a task
Applied to files:
tests/unit/profiles/selective-profile-removal.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 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.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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 mcp-server/src/core/direct-functions/*.js : Create direct function wrappers in 'mcp-server/src/core/direct-functions/' for MCP tool implementation, following silent mode patterns and using findTasksJsonPath for consistent path resolution.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 : Never use asynchronous operations in tests. Make all mocks return synchronous values when possible.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.test.js
🧬 Code graph analysis (2)
src/profiles/cursor.js (3)
src/profiles/roo.js (4)
src(36-36)dest(37-37)stats(53-53)sourceDir(11-11)src/profiles/claude.js (3)
stats(10-10)content(88-88)content(142-142)src/utils/rule-transformer.js (7)
content(173-173)content(272-272)assetsDir(206-206)sourceDir(204-204)targetDir(183-183)targetDir(205-205)targetDir(344-344)
tests/unit/profiles/selective-profile-removal.test.js (3)
src/utils/rule-transformer.js (5)
result(56-56)result(79-79)result(110-110)result(140-140)result(347-357)src/utils/create-mcp-config.js (1)
result(161-167)mcp-server/src/core/direct-functions/rules.js (1)
result(84-84)
🔇 Additional comments (2)
src/profiles/cursor.js (1)
101-113: Profile metadata and hooks wiring look good.tests/unit/profiles/selective-profile-removal.test.js (1)
148-159: Ignore fileCount-return change suggestion for cursorProfile onRemove
removeProfileRules aggregates each hook’s success count into its own result.fileCount and cursor’s onRemove already returns the number of removed commands as success. No changes to src/profiles/cursor.js are needed for the existing fileCount assertions.Likely an incorrect or invalid review comment.
…ster into joedanz/cursor-slash # Conflicts: # package.json # src/utils/rule-transformer.js
…s or avoid claiming zero.
…bustness and speed
There was a problem hiding this comment.
Actionable comments posted: 6
♻️ Duplicate comments (7)
.changeset/cursor-slash-commands.md (1)
5-7: Condense to a single, user-facing, imperative one-liner; fix example typo if kept.Per repo guidelines, the changeset body should be one concise sentence. Also “/tmshow-task” is missing a slash. Suggested rewrite:
--- "task-master-ai": minor --- -Add Cursor IDE custom slash command support - -When users add the Cursor profile, they now get all 47 Task Master commands available as native Cursor slash commands (/tm/add-task, /tm/next-task, /tmshow-task, etc.) with automatic distribution and cleanup via the rule-transformer system. Also improves profile summary accuracy to show total files processed including custom commands. Provides full parity to Claude Code slash commands. +Add Cursor IDE native slash commands (47 Task Master commands) with auto install/uninstall via the Cursor profile; include command files in profile summaries.src/utils/rule-transformer.js (2)
219-226: Normalize onAdd hook result: accept fileCount/failedFileCount in addition to success/failed.Make the hook schema tolerant and future-proof.
- // If hook returns result with success/failed counts, add them to totals - if ( - hookResult && - typeof hookResult === 'object' && - typeof hookResult.success === 'number' - ) { - success += hookResult.success; - failed += hookResult.failed || 0; - } + // Tolerate both {fileCount, failedFileCount} and {success, failed} + if (hookResult && typeof hookResult === 'object') { + const files = + typeof hookResult.fileCount === 'number' + ? hookResult.fileCount + : typeof hookResult.success === 'number' + ? hookResult.success + : 0; + const failures = + typeof hookResult.failedFileCount === 'number' + ? hookResult.failedFileCount + : typeof hookResult.failed === 'number' + ? hookResult.failed + : 0; + success += files; + failed += failures; + }
360-373: Make onRemove hook schema-tolerant and capture failures too.Count files from either fileCount or success; accumulate failedFileCount if provided.
- // If hook returns result with success count, add it to file count for totals - if ( - hookResult && - typeof hookResult === 'object' && - typeof hookResult.success === 'number' - ) { - result.fileCount += hookResult.success; - } + // If hook returns counts, normalize keys + if (hookResult && typeof hookResult === 'object') { + const hookFiles = + typeof hookResult.fileCount === 'number' + ? hookResult.fileCount + : typeof hookResult.success === 'number' + ? hookResult.success + : 0; + const hookFailed = + typeof hookResult.failedFileCount === 'number' + ? hookResult.failedFileCount + : typeof hookResult.failed === 'number' + ? hookResult.failed + : 0; + result.fileCount += hookFiles; + if (hookFailed) { + result.failedFileCount = (result.failedFileCount || 0) + hookFailed; + } + }src/profiles/cursor.js (4)
55-59: Prefer repo logger over console. (consistency with scripts/modules/utils.js).*Swap console.* with the shared logger for consistency and easier testing.
- console.log(`[INFO] Adding Task Master slash commands to .cursor/commands`); + // import { log } from '../../scripts/modules/utils.js' + // log('info', `Adding Task Master slash commands to .cursor/commands`); @@ - console.log( - `[SUCCESS] Added ${added} Task Master slash commands (of ${fileCount} total) to Cursor IDE` - ); + // log('success', `Added ${added} Task Master slash commands (of ${fileCount} total) to Cursor IDE`);
2-2: Remove unused import.
COMMON_TOOL_MAPPINGS is not used; drop it to satisfy lint.-import { createProfile, COMMON_TOOL_MAPPINGS } from './base-profile.js'; +import { createProfile } from './base-profile.js';
38-44: Fix source directory to Cursor assets and include fileCount in failure return.The new commands live under assets/cursor/commands per the PR. Copying from Claude will miss them. Also return fileCount for aggregator summaries.
- const sourceDir = path.join(assetsDir, 'claude', 'commands'); + const sourceDir = path.join(assetsDir, 'cursor', 'commands'); @@ if (!fs.existsSync(sourceDir)) { console.warn(`Source commands not found: ${sourceDir}`); - return { success: 0, failed: 1 }; + return { success: 0, failed: 1, fileCount: 0 }; }
63-96: Remove only Task Master commands and keep user custom commands intact; include fileCount in all paths.Current code deletes .cursor/commands/tm wholesale, which may not match the new flat tm-.md naming and risks removing user files. Scope deletion to tm-.md (recursively) and return fileCount consistently.
-const onRemove = (projectRoot) => { - const tmDir = path.join(projectRoot, '.cursor', 'commands', 'tm'); +const onRemove = (projectRoot) => { + const commandsDir = path.join(projectRoot, '.cursor', 'commands'); @@ - if (!fs.existsSync(tmDir)) { + if (!fs.existsSync(commandsDir)) { console.log(`[INFO] No Task Master commands found to remove`); - return { success: 0, failed: 0 }; + return { success: 0, failed: 0, fileCount: 0 }; } @@ - // Count .md files recursively - let count = 0; - const countFiles = (dir) => { - fs.readdirSync(dir).forEach((item) => { - const fullPath = path.join(dir, item); - if (fs.statSync(fullPath).isDirectory()) { - countFiles(fullPath); - } else if (item.endsWith('.md')) { - count++; - } - }); - }; - countFiles(tmDir); - - console.log(`[INFO] Removing ${count} Task Master slash commands`); - fs.rmSync(tmDir, { recursive: true, force: true }); - console.log( - `[SUCCESS] Removed ${count} Task Master slash commands from Cursor IDE` - ); - return { success: count, failed: 0 }; + // Collect tm-*.md recursively + const filesToRemove = []; + const walk = (dir) => { + for (const item of fs.readdirSync(dir)) { + const fullPath = path.join(dir, item); + const st = fs.statSync(fullPath); + if (st.isDirectory()) walk(fullPath); + else if (item.endsWith('.md') && item.startsWith('tm-')) filesToRemove.push(fullPath); + } + }; + walk(commandsDir); + + const fileCount = filesToRemove.length; + if (fileCount === 0) { + console.log(`[INFO] No Task Master commands found to remove`); + return { success: 0, failed: 0, fileCount: 0 }; + } + + console.log(`[INFO] Removing ${fileCount} Task Master slash commands`); + for (const fp of filesToRemove) fs.rmSync(fp, { force: true }); + console.log( + `[SUCCESS] Removed ${fileCount} Task Master slash commands from Cursor IDE` + ); + return { success: fileCount, failed: 0, fileCount }; @@ - console.warn(`Failed to remove commands: ${error.message}`); - return { success: 0, failed: 1 }; + console.warn(`Failed to remove commands: ${error.message}`); + return { success: 0, failed: 1, fileCount: 0 }; } };
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (4)
.changeset/cursor-slash-commands.md(1 hunks)scripts/modules/commands.js(1 hunks)src/profiles/cursor.js(2 hunks)src/utils/rule-transformer.js(3 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
.changeset/*.md
📄 CodeRabbit inference engine (.cursor/rules/changeset.mdc)
.changeset/*.md: When runningnpm run changesetornpx changeset add, provide a concise summary of the changes for theCHANGELOG.mdin 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
scripts/modules/commands.js
📄 CodeRabbit inference engine (.cursor/rules/ai_services.mdc)
scripts/modules/commands.js: Centralize all LLM calls throughgenerateTextServiceorgenerateObjectService.
Do not import or call anything from the oldai-services.js,ai-client-factory.js, orai-client-utils.jsfiles.
Do not fetch AI-specific parameters (model ID, max tokens, temp) usingconfig-manager.jsgetters for the AI call. Pass theroleinstead.
Do not implement fallback or retry logic outsideai-services-unified.js.
Do not handle API key resolution outside the service layer (it usesutils.jsinternally).
Determine the appropriaterole(main,research,fallback) in your core logic and pass it to the service.
Pass thesessionobject (received in thecontextparameter, especially from direct function wrappers) to the service call when in MCP context.
UsegenerateTextServiceand implement robust manual JSON parsing (with Zod validation after parsing) when structured output is needed, asgenerateObjectServicehas shown unreliability with some providers/schemas.
Be aware of potential reliability issues withgenerateObjectServiceacross different providers and complex schemas. PrefergenerateTextService+ manual parsing as a more robust alternative for structured data needs.
scripts/modules/commands.js: All new user-facing commands should be added to 'scripts/modules/commands.js'.
Use consistent patterns for option naming and help text in CLI commands.
Follow the Commander.js model for subcommand structure in CLI commands.
When using callbacks (like in Commander.js commands), define them separately to allow testing the callback logic independently.
Add help text to the command definition and update 'dev_workflow.mdc' with command reference when adding a new feature.
Follow the established pattern in 'commands.js' for CLI command implementation, using Commander.js for argument parsing, including comprehensive help text and examples, and supporting tagged task context awareness.
Provide clear error messages for common failu...
Files:
scripts/modules/commands.js
scripts/modules/*.js
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Each module in scripts/modules/ should be focused on a single responsibility, following the modular architecture (e.g., commands.js for CLI command handling, task-manager.js for task data and core logic, dependency-manager.js for dependency management, ui.js for CLI output formatting, ai-services-unified.js for AI service integration, config-manager.js for configuration management, utils.js for utility functions).
scripts/modules/*.js: Export all core functions, helper functions, and utility methods needed by your new function or command from their respective modules. Explicitly review the module's export block to ensure every required dependency is included.
Pass all required parameters to functions you call within your implementation and verify that direct function parameters match their core function counterparts.
Use consistent file naming conventions: 'task_${id.toString().padStart(3, '0')}.txt', use path.join for composing file paths, and use appropriate file extensions (.txt for tasks, .json for data).
Use structured error objects with code and message properties, include clear error messages, and handle both function-specific and file system errors.
Import all silent mode utilities together from 'scripts/modules/utils.js' and always use isSilentMode() to check global silent mode status. Wrap core function calls within direct functions using enableSilentMode() and disableSilentMode() in a try/finally block if the core function might produce console output.
Core functions should check outputFormat === 'text' before displaying UI elements and use internal logging that respects silent mode.
Design functions to accept dependencies as parameters (dependency injection) and avoid hard-coded dependencies that are difficult to mock.
Keep pure logic separate from I/O operations or UI rendering to allow testing the logic without mocking complex dependencies.
When implementing core logic for new features, do so in 'scripts/modules/' before CLI or MCP interfaces, and d...
Files:
scripts/modules/commands.js
scripts/modules/**
📄 CodeRabbit inference engine (.cursor/rules/dev_workflow.mdc)
When using the MCP server, restart it if core logic in
scripts/modulesor MCP tool/direct function definitions change.
Files:
scripts/modules/commands.js
scripts/modules/*
📄 CodeRabbit inference engine (.cursor/rules/tags.mdc)
scripts/modules/*: Every command that reads or writes tasks.json must be tag-aware
All command files must import getCurrentTag from utils.js
Every CLI command that operates on tasks must include the --tag CLI option
All commands must resolve the tag using the pattern: options.tag || getCurrentTag(projectRoot) || 'master'
All commands must find projectRoot with error handling before proceeding
All commands must pass { projectRoot, tag } as context to core functions
MCP direct functions must accept and use a context object containing projectRoot and tag, and pass them to core functions
Do not hard-code tag resolution (e.g., const tag = options.tag || 'master';); always use getCurrentTag
Do not omit the --tag CLI option in commands that operate on tasks
Do not omit the context parameter when calling core functions from commands
Do not call readJSON or writeJSON without passing projectRoot and tag
Files:
scripts/modules/commands.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:
scripts/modules/commands.jssrc/utils/rule-transformer.jssrc/profiles/cursor.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
🧠 Learnings (28)
📓 Common learnings
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.
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.
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 : 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.
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.
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.
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).
📚 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-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-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:
scripts/modules/commands.jssrc/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 : Show what will be deleted in the confirmation message for destructive commands.
Applied to files:
scripts/modules/commands.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:
scripts/modules/commands.js
📚 Learning: 2025-07-18T17:09:40.548Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/dependencies.mdc:0-0
Timestamp: 2025-07-18T17:09:40.548Z
Learning: Applies to scripts/modules/dependency-manager.js : Track and report changes made during dependency cleanup
Applied to files:
scripts/modules/commands.js
📚 Learning: 2025-07-18T17:09:40.548Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/dependencies.mdc:0-0
Timestamp: 2025-07-18T17:09:40.548Z
Learning: Applies to scripts/modules/dependency-manager.js : Provide feedback about the removal result
Applied to files:
scripts/modules/commands.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
📚 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-09-02T21:51:27.921Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/src/auth/config.ts:5-7
Timestamp: 2025-09-02T21:51:27.921Z
Learning: The user Crunchyman-ralph prefers not to use node: scheme imports (e.g., 'node:os', 'node:path') for Node.js core modules and considers suggestions to change bare imports to node: scheme as too nitpicky.
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 **/*.js : Use dynamic imports (import()) to avoid initialization order issues in modules.
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-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/.taskmaster/tasks/*.{md,txt} : Treat task files in .taskmaster/tasks (md or txt) as auto-generated; avoid manual edits
Applied to files:
src/profiles/cursor.js
📚 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:
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-08-06T21:12:20.981Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: assets/claude/agents/task-executor.md:1-6
Timestamp: 2025-08-06T21:12:20.981Z
Learning: In the eyaltoledano/claude-task-master repository, agent files in assets/claude/agents/ are intended for distribution to users (for copying), while identical files in .claude/agents/ are for internal project use. This intentional duplication serves different purposes and is not a DRY violation.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-08-06T21:12:43.715Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: assets/claude/agents/task-orchestrator.md:1-6
Timestamp: 2025-08-06T21:12:43.715Z
Learning: In the eyaltoledano/claude-task-master repository, agent files are intentionally duplicated between `.claude/agents/` (for internal project use) and `assets/claude/agents/` (as template files for users to copy). This duplication serves different purposes and should be maintained to support both internal development and user distribution needs.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-07-18T17:14:29.399Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tasks.mdc:0-0
Timestamp: 2025-07-18T17:14:29.399Z
Learning: Applies to scripts/modules/task-manager.js : Use consistent formatting for task files, include all task properties in text files, and format dependencies with status indicators.
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 scripts/modules/*.js : Use consistent file naming conventions: 'task_${id.toString().padStart(3, '0')}.txt', use path.join for composing file paths, and use appropriate file extensions (.txt for tasks, .json for data).
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-08-06T21:11:37.259Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: .claude/agents/task-orchestrator.md:0-0
Timestamp: 2025-08-06T21:11:37.259Z
Learning: For files in .claude/agents/ and assets/claude/agents/ directories, ignore markdownlint issues like MD041 (missing top-level heading) as these are Claude Code agent instruction files that follow a specific format with YAML frontmatter and don't need to conform to standard markdown documentation conventions.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-08-06T21:13:05.240Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: assets/claude/agents/task-orchestrator.md:69-78
Timestamp: 2025-08-06T21:13:05.240Z
Learning: For Claude agent instruction files in .claude/agents/ and assets/claude/agents/ directories, ignore markdownlint issues (like MD031 blanks-around-fences, MD040 fenced-code-language, MD041 missing top-level heading) as these files follow Claude's specific agent format requirements rather than standard markdown documentation conventions.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-08-06T21:11:57.597Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: .claude/agents/task-executor.md:1-6
Timestamp: 2025-08-06T21:11:57.597Z
Learning: For Claude agent instruction files located in .claude/agents or assets/claude/agents directories, Crunchyman-ralph wants to ignore MarkdownLint issues since these files follow Claude's specific format requirements rather than standard markdown documentation conventions.
Applied to files:
src/profiles/cursor.js
📚 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:
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 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: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 : When referencing files in Cursor rule files, use the format [filename](mdc:path/to/file) or [filename](mdc:filename).
Applied to files:
src/profiles/cursor.js
🧬 Code graph analysis (3)
scripts/modules/commands.js (2)
mcp-server/src/core/direct-functions/rules.js (1)
removalResults(55-55)src/utils/rule-transformer.js (5)
result(58-58)result(81-81)result(112-112)result(142-142)result(344-354)
src/utils/rule-transformer.js (2)
src/utils/asset-resolver.js (1)
getAssetsDir(21-57)mcp-server/src/core/direct-functions/rules.js (1)
result(84-84)
src/profiles/cursor.js (3)
src/profiles/roo.js (4)
src(36-36)dest(37-37)stats(53-53)sourceDir(11-11)src/utils/rule-transformer.js (8)
stats(417-417)content(175-175)content(268-268)assetsDir(212-212)assetsDir(316-316)targetDir(185-185)targetDir(204-204)targetDir(341-341)src/profiles/claude.js (3)
stats(10-10)content(88-88)content(142-142)
🪛 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)
🪛 GitHub Actions: CI
src/utils/rule-transformer.js
[error] 212-212: Biome formatting check failed. The formatter would reformat line 212 in 'src/utils/rule-transformer.js'. Run 'biome format .' to fix code style issues.
🔇 Additional comments (1)
src/profiles/cursor.js (1)
86-94: Do not requirefileCountin hook returns; require numericsuccess.
rule-transformer increments result.fileCount from hookResult.success; cursor.js already returns numericsuccess(e.g.{ success: count, failed: 0 }/{ success: 0, failed: 1 }), so add/verifysuccess: numberon any missing return paths instead of addingfileCount.Likely an incorrect or invalid review comment.
…ster into joedanz/cursor-slash
…ster into joedanz/cursor-slash
…ude-task-master into joedanz/cursor-slash
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
tests/unit/profiles/selective-profile-removal.test.js (6)
5-9: Mock-before-import to ensure logger mock applies (ESM-safe).Move the utils logger mock above imports of modules under test so the mock is guaranteed to wire before rule-transformer/create-mcp-config are evaluated.
import fs from 'fs'; import path from 'path'; import os from 'os'; import { jest } from '@jest/globals'; -import { - removeProfileRules, - getRulesProfile -} from '../../../src/utils/rule-transformer.js'; -import { removeTaskMasterMCPConfiguration } from '../../../src/utils/create-mcp-config.js'; // Mock logger const mockLog = { info: jest.fn(), error: jest.fn(), debug: jest.fn(), warn: jest.fn() }; // Mock the logger import jest.mock('../../../scripts/modules/utils.js', () => ({ log: (level, message) => mockLog[level]?.(message) })); + +import { + removeProfileRules, + getRulesProfile +} from '../../../src/utils/rule-transformer.js'; +import { removeTaskMasterMCPConfiguration } from '../../../src/utils/create-mcp-config.js';Also applies to: 20-22
48-49: Prevent accidental real FS access: provide a default readdirSync mock.Without a default, unexpected paths fall through to the real FS, causing nondeterministic ENOENTs. Set a strict default and then override with mockReturnValueOnce() in each test.
- mockReaddirSync = jest.spyOn(fs, 'readdirSync'); + mockReaddirSync = jest + .spyOn(fs, 'readdirSync') + .mockImplementation((p) => { + throw new Error(`Unexpected readdirSync on ${p}`); + });
72-85: Fix cleanup: rmSync spy blocks tempDir deletion. Restore mocks before cleanup.Currently afterEach uses the mocked rmSync, leaking temp dirs. Restore mocks first, then delete.
-afterEach(() => { - // Restore console.log - console.log = originalConsoleLog; - - // Clean up temp directory - try { - fs.rmSync(tempDir, { recursive: true, force: true }); - } catch (error) { - // Ignore cleanup errors - } - - // Restore all mocked functions - jest.restoreAllMocks(); -}); +afterEach(() => { + // Restore all mocked functions first so FS cleanup uses real methods + jest.restoreAllMocks(); + + // Restore console.log + console.log = originalConsoleLog; + + // Clean up temp directory + try { + fs.rmSync(tempDir, { recursive: true, force: true }); + } catch { + /* ignore */ + } +});
42-44: Temp dir is unused; drop to reduce noise and side effects.The tests operate on '/test/project' exclusively; tempDir isn’t referenced elsewhere.
- // Create temp directory for testing - tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'task-master-test-')); -
171-179: Make the test deterministic; don’t branch on result.success.Define FS mocks comprehensively and assert success directly.
- // The function may fail due to directory reading issues in the test environment, - // but the core functionality (file removal) should work - if (result.success) { - expect(result.success).toBe(true); - } else { - // If it fails, it should be due to directory reading, not file removal - expect(result.error).toContain('ENOENT'); - expect(result.filesRemoved.length).toBeGreaterThan(0); - } + expect(result.success).toBe(true);
31-31: Remove unused mkdirSync spy.No paths call mkdirSync; drop the spy to reduce clutter.
- let mockMkdirSync; + // (removed: unused mockMkdirSync)- mockMkdirSync = jest.spyOn(fs, 'mkdirSync').mockImplementation(() => {}); + // (removed: unused mkdirSync spy)Also applies to: 53-53
♻️ Duplicate comments (1)
tests/unit/profiles/selective-profile-removal.test.js (1)
54-69: Add an error-path test for failedFileCount/failedFiles (still missing).We should simulate rmSync throwing for one Task Master rule and assert failedFileCount increments and filesRemoved excludes that file.
Want a ready-to-drop test block that forces rmSync to throw and asserts failed accounting?
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
tests/unit/profiles/selective-profile-removal.test.js(17 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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/unit/profiles/selective-profile-removal.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/selective-profile-removal.test.js
🧠 Learnings (28)
📓 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: 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.
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 : 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.
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.
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.
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.
📚 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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/**/*.test.js : Do not include actual command execution in unit tests.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 modifications on the in-memory task objects passed to writeJSON.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 CLI and MCP interfaces with real task data, verify end-to-end workflows across tag contexts, and test error scenarios and recovery in integration tests.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 : 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.
Applied to files:
tests/unit/profiles/selective-profile-removal.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:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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 : Mock readJSON and writeJSON to avoid real file system interactions in tests.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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 : Mock API calls (e.g., Anthropic/Claude) by mocking the entire module and providing predictable responses.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 test-specific file paths (e.g., 'test-tasks.json') for all file operations in tests.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.test.js
📚 Learning: 2025-07-18T17:10:31.810Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/git_workflow.mdc:0-0
Timestamp: 2025-07-18T17:10:31.810Z
Learning: Applies to **/*.{test,spec}.{js,ts,jsx,tsx} : Create a test file if needed and ensure all tests pass before completing a task
Applied to files:
tests/unit/profiles/selective-profile-removal.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 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.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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 mcp-server/src/core/direct-functions/*.js : Create direct function wrappers in 'mcp-server/src/core/direct-functions/' for MCP tool implementation, following silent mode patterns and using findTasksJsonPath for consistent path resolution.
Applied to files:
tests/unit/profiles/selective-profile-removal.test.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 : The *Direct function is responsible for finding the exact tasks.json path using findTasksJsonPath, relying on the projectRoot passed in args.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 : Never use asynchronous operations in tests. Make all mocks return synchronous values when possible.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.test.js
🧬 Code graph analysis (1)
tests/unit/profiles/selective-profile-removal.test.js (3)
src/utils/rule-transformer.js (5)
result(58-58)result(81-81)result(112-112)result(142-142)result(353-366)src/utils/create-mcp-config.js (1)
result(161-167)mcp-server/src/core/direct-functions/rules.js (1)
result(84-84)
⏰ 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: Test
🔇 Additional comments (1)
tests/unit/profiles/selective-profile-removal.test.js (1)
328-329: Align test fileCount with lifecycle-hook + removal aggregationresult.fileCount is the sum of lifecycle hook returns (hooks may return fileCount or success) plus each removed rule file — see src/utils/rule-transformer.js (hook aggregation and result.fileCount++ on removal) and src/profiles/cursor.js (onAdd/onRemove hook returns). Update the test to mock/return hook counts or include command files so expect(result.fileCount).toBe(4) matches the aggregated total.
There was a problem hiding this comment.
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 (4)
src/utils/rule-transformer.js (4)
8-10: Fix ESM imports for Node core modules (runtime error risk).Default imports for fs/path break in native ESM. Use namespace imports with node: scheme.
Apply:
-import fs from 'fs'; -import path from 'path'; +import * as fs from 'node:fs'; +import * as path from 'node:path';
209-236: Normalize onAdd hook results (accept processed/skipped/fileCount).Current code only reads success/failed; your Cursor hook returns processed/skipped. Normalize to avoid losing counts and to match PR goals.
Apply:
if (typeof profile.onAddRulesProfile === 'function') { try { const assetsDir = getAssetsDir(); const hookResult = profile.onAddRulesProfile(projectRoot, assetsDir); @@ - /** - * Hook Contract: onAddRulesProfile can optionally return an object with count information - * Expected shape: { success: number, failed: number, fileCount?: number } - * - success: number of successful operations (e.g., files processed) - * - failed: number of failed operations - * - fileCount: optional total file count for reporting - * - * Note: This is optional - hooks can also return nothing/undefined - */ - if ( - hookResult && - typeof hookResult === 'object' && - typeof hookResult.success === 'number' - ) { - success += hookResult.success; - failed += hookResult.failed || 0; - } + // Hook Contract: accept {success/failed} or {processed/skipped} and optional fileCount + if (hookResult && typeof hookResult === 'object') { + const s = + typeof hookResult.success === 'number' + ? hookResult.success + : typeof hookResult.processed === 'number' + ? hookResult.processed + : 0; + const f = + typeof hookResult.failed === 'number' + ? hookResult.failed + : typeof hookResult.failedCount === 'number' + ? hookResult.failedCount + : typeof hookResult.skipped === 'number' + ? hookResult.skipped + : 0; + success += s; + failed += f; + }
195-196: Use repository logger instead of console.error.Aligns with existing logging and makes tests deterministic.
Apply:
- console.error(`Error converting rule file: ${error.message}`); + log('error', `[Rule Transformer] Error converting rule file: ${error.message}`);
437-456: fs.readdirSync({ recursive: true }) is not supported; replace with safe recursion.This will throw at runtime. Use withFileTypes and recurse.
Apply:
- // Get all files in the rules directory - // For root-level directories, we need to be careful to avoid circular symlinks - let allFiles = []; - if (targetDir === projectRoot || profile.rulesDir === '.') { - // For root directory, manually read without recursion into problematic directories - const items = fs.readdirSync(targetDir); - for (const item of items) { - // Skip directories that can cause issues or are irrelevant - if (item === 'node_modules' || item === '.git' || item === 'dist') { - continue; - } - const itemPath = path.join(targetDir, item); - try { - const stats = fs.lstatSync(itemPath); - if (stats.isFile()) { - allFiles.push(item); - } else if (stats.isDirectory() && !stats.isSymbolicLink()) { - // Only recurse into safe directories - const subFiles = fs.readdirSync(itemPath, { recursive: true }); - subFiles.forEach((subFile) => { - allFiles.push(path.join(item, subFile.toString())); - }); - } - } catch (err) { - // Silently skip files we can't access - } - } - } else { - // For non-root directories, use normal recursive read - allFiles = fs.readdirSync(targetDir, { recursive: true }); - } + // Get all files in the rules directory (safe recursion) + const allFiles = listFilesRecursiveSafe(targetDir, { + ignoreTopLevel: new Set(['node_modules', '.git', 'dist']) + });Add this helper (place near top of file, after other helpers):
function listFilesRecursiveSafe(dir, options = {}, rel = '') { const out = []; const entries = fs.readdirSync(dir, { withFileTypes: true }); for (const entry of entries) { if (!rel && options.ignoreTopLevel && options.ignoreTopLevel.has(entry.name)) continue; const abs = path.join(dir, entry.name); const relPath = path.join(rel || '', entry.name); try { if (entry.isSymbolicLink()) continue; if (entry.isDirectory()) { out.push(...listFilesRecursiveSafe(abs, options, relPath)); } else if (entry.isFile()) { out.push(relPath); } } catch { // skip unreadable entries } } return out; }Also applies to: 460-466
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
src/profiles/cursor.js(2 hunks)src/utils/rule-transformer.js(5 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.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.jssrc/utils/rule-transformer.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
🧠 Learnings (30)
📓 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: assets/AGENTS.md:0-0
Timestamp: 2025-09-01T09:55:15.061Z
Learning: Applies to assets/.claude/commands/taskmaster-next.md : Create .claude/commands/taskmaster-next.md implementing the 4-step workflow to find and show the next task
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 : 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.
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.
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.
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.
📚 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
📚 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: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: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 **/*.js : Use dynamic imports (import()) to avoid initialization order issues in modules.
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-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/.taskmaster/tasks/*.{md,txt} : Treat task files in .taskmaster/tasks (md or txt) as auto-generated; avoid manual edits
Applied to files:
src/profiles/cursor.js
📚 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:
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-08-06T21:12:43.715Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: assets/claude/agents/task-orchestrator.md:1-6
Timestamp: 2025-08-06T21:12:43.715Z
Learning: In the eyaltoledano/claude-task-master repository, agent files are intentionally duplicated between `.claude/agents/` (for internal project use) and `assets/claude/agents/` (as template files for users to copy). This duplication serves different purposes and should be maintained to support both internal development and user distribution needs.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-08-06T21:12:20.981Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: assets/claude/agents/task-executor.md:1-6
Timestamp: 2025-08-06T21:12:20.981Z
Learning: In the eyaltoledano/claude-task-master repository, agent files in assets/claude/agents/ are intended for distribution to users (for copying), while identical files in .claude/agents/ are for internal project use. This intentional duplication serves different purposes and is not a DRY violation.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-08-06T21:13:05.240Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: assets/claude/agents/task-orchestrator.md:69-78
Timestamp: 2025-08-06T21:13:05.240Z
Learning: For Claude agent instruction files in .claude/agents/ and assets/claude/agents/ directories, ignore markdownlint issues (like MD031 blanks-around-fences, MD040 fenced-code-language, MD041 missing top-level heading) as these files follow Claude's specific agent format requirements rather than standard markdown documentation conventions.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-07-18T17:14:29.399Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tasks.mdc:0-0
Timestamp: 2025-07-18T17:14:29.399Z
Learning: Applies to scripts/modules/task-manager.js : Use consistent formatting for task files, include all task properties in text files, and format dependencies with status indicators.
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 scripts/modules/*.js : Use consistent file naming conventions: 'task_${id.toString().padStart(3, '0')}.txt', use path.join for composing file paths, and use appropriate file extensions (.txt for tasks, .json for data).
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-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/task-manager.js : Features that create, read, update, or delete tasks belong in 'scripts/modules/task-manager.js'.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-08-06T21:11:37.259Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: .claude/agents/task-orchestrator.md:0-0
Timestamp: 2025-08-06T21:11:37.259Z
Learning: For files in .claude/agents/ and assets/claude/agents/ directories, ignore markdownlint issues like MD041 (missing top-level heading) as these are Claude Code agent instruction files that follow a specific format with YAML frontmatter and don't need to conform to standard markdown documentation conventions.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-08-06T21:11:57.597Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: .claude/agents/task-executor.md:1-6
Timestamp: 2025-08-06T21:11:57.597Z
Learning: For Claude agent instruction files located in .claude/agents or assets/claude/agents directories, Crunchyman-ralph wants to ignore MarkdownLint issues since these files follow Claude's specific format requirements rather than standard markdown documentation conventions.
Applied to files:
src/profiles/cursor.js
📚 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:
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-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.md : Maintain CLAUDE.md as auto-loaded context for Claude Code
Applied to files:
src/profiles/cursor.js
📚 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-next.md : Create .claude/commands/taskmaster-next.md implementing the 4-step workflow to find and show the next task
Applied to files:
src/profiles/cursor.js
📚 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:
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 : Check if files exist before attempting to delete them, and handle file deletion errors gracefully.
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 : Follow the provided structure for removing subtasks, including options for conversion, file path, and regeneration, with detailed error handling.
Applied to files:
src/profiles/cursor.jssrc/utils/rule-transformer.js
📚 Learning: 2025-07-18T17:09:40.548Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/dependencies.mdc:0-0
Timestamp: 2025-07-18T17:09:40.548Z
Learning: Applies to scripts/modules/dependency-manager.js : Check for and remove references to non-existent tasks during cleanup
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: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: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 : When referencing files in Cursor rule files, use the format [filename](mdc:path/to/file) or [filename](mdc:filename).
Applied to files:
src/profiles/cursor.js
🧬 Code graph analysis (2)
src/profiles/cursor.js (3)
src/profiles/roo.js (4)
src(36-36)dest(37-37)stats(53-53)sourceDir(11-11)src/utils/rule-transformer.js (10)
stats(446-446)content(175-175)content(277-277)assetsDir(212-212)assetsDir(325-325)targetDir(185-185)targetDir(204-204)targetDir(350-350)filePath(479-479)items(438-438)src/profiles/claude.js (3)
stats(10-10)content(88-88)content(142-142)
src/utils/rule-transformer.js (3)
src/utils/asset-resolver.js (1)
assetsDir(65-65)mcp-server/src/core/direct-functions/rules.js (1)
result(84-84)src/profiles/cursor.js (2)
targetDir(68-68)targetDir(120-120)
⏰ 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: Test
🔇 Additional comments (5)
src/profiles/cursor.js (2)
7-39: Idempotent copy + per-file transform look good.Counts only .md files, preserves user edits via skip-on-exist, and logs per‑file failures. LGTM.
230-241: Profile export details look correct.ESM-safe imports, explicit profile/rules dirs, and lifecycle wiring read well.
Please confirm base-profile maps onAdd/onRemove → onAddRulesProfile/onRemoveRulesProfile so utils can call these hooks.
src/utils/rule-transformer.js (3)
361-366: Nice: expanded removal telemetry.fileCount/failedFileCount/failedFiles/fileRemoveFailures will improve UX and CI logs.
377-400: Good schema tolerance for onRemove hook results.Accepts fileCount/success and failed/failedCount. Matches PR objectives.
590-595: Return object/logging flow reads clean.Happy path sets success and logs debug summary.
There was a problem hiding this comment.
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 (3)
tests/unit/profiles/selective-profile-removal.test.js (3)
171-179: Make the test deterministic; don’t branch on result.success.Unit tests shouldn’t accept both success and failure. Provide complete fs mocks so success is always true and assert it.
Apply this diff:
- // The function may fail due to directory reading issues in the test environment, - // but the core functionality (file removal) should work - if (result.success) { - expect(result.success).toBe(true); - } else { - // If it fails, it should be due to directory reading, not file removal - expect(result.error).toContain('ENOENT'); - expect(result.filesRemoved.length).toBeGreaterThan(0); - } + // The function should succeed with fully mocked fs + expect(result.success).toBe(true);
303-311: Profile dir not removed due to existsSync mock always returning true for .cursor/commands.In this test you expect the entire profile directory to be removed, but existsSync mocks .cursor/commands as present. Make commands absent here.
Apply this diff:
- mockExistsSync.mockImplementation((filePath) => { + mockExistsSync.mockImplementation((filePath) => { if (filePath.includes('.cursor')) return true; if (filePath.includes('.cursor/rules')) return true; - if (filePath.includes('.cursor/commands')) return true; + // Simulate commands removed by lifecycle hook so profile becomes empty + if (filePath.includes('.cursor/commands')) return false; if (filePath.includes('mcp.json')) return true; return false; });This should make result.profileDirRemoved === true consistent with your assertion and CI expectation.
Also applies to: 331-337, 338-342
20-22: Mock utils before importing rule-transformer (ESM jest.mock not hoisted).tests/unit/profiles/selective-profile-removal.test.js — the jest.mock('../../../scripts/modules/utils.js') is at lines 20–22 but rule-transformer/create-mcp-config are statically imported at lines 5–9; with ESM, jest.mock may not be hoisted and the real logger can leak into tests. Fix by either:
- Reorder (static imports): import { jest } from '@jest/globals'; define mockLog; call jest.mock(...) before importing rule-transformer/create-mcp-config.
import { jest } from '@jest/globals'; const mockLog = { info: jest.fn(), error: jest.fn(), debug: jest.fn(), warn: jest.fn() }; jest.mock('../../../scripts/modules/utils.js', () => ({ log: (l,m) => mockLog[l]?.(m) })); import { removeProfileRules, getRulesProfile } from '../../../src/utils/rule-transformer.js'; import { removeTaskMasterMCPConfiguration } from '../../../src/utils/create-mcp-config.js';
- ESM-safe async pattern (if you must keep dynamic/module order): use jest.unstable_mockModule + dynamic import inside beforeAll.
import { jest } from '@jest/globals'; const mockLog = { info: jest.fn(), error: jest.fn(), debug: jest.fn(), warn: jest.fn() }; let removeProfileRules, getRulesProfile; beforeAll(async () => { jest.resetModules(); await jest.unstable_mockModule('../../../scripts/modules/utils.js', () => ({ log: (level, message) => mockLog[level]?.(message) })); ({ removeProfileRules, getRulesProfile } = await import('../../../src/utils/rule-transformer.js')); });
♻️ Duplicate comments (1)
tests/unit/profiles/selective-profile-removal.test.js (1)
54-69: Path-heuristic statSync is brittle; prefer extname/Dirent-based classification.Relying on includes('commands/tm/') and extensions is fragile across platforms; mock readdirSync with withFileTypes: true and return Dirent-like objects, or classify via path.extname. This reduces false directory/file detections.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
tests/unit/profiles/selective-profile-removal.test.js(17 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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/unit/profiles/selective-profile-removal.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/selective-profile-removal.test.js
🧠 Learnings (34)
📓 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: assets/AGENTS.md:0-0
Timestamp: 2025-09-01T09:55:15.061Z
Learning: Applies to assets/.claude/commands/taskmaster-next.md : Create .claude/commands/taskmaster-next.md implementing the 4-step workflow to find and show the next task
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 : 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.
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.
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.
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.
📚 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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/**/*.test.js : Do not include actual command execution in unit tests.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 modifications on the in-memory task objects passed to writeJSON.
Applied to files:
tests/unit/profiles/selective-profile-removal.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:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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 test-specific file paths (e.g., 'test-tasks.json') for all file operations in tests.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 different file paths for each test to avoid test interdependence.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/*.js : Use consistent file naming conventions: 'task_${id.toString().padStart(3, '0')}.txt', use path.join for composing file paths, and use appropriate file extensions (.txt for tasks, .json for data).
Applied to files:
tests/unit/profiles/selective-profile-removal.test.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:
tests/unit/profiles/selective-profile-removal.test.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:
tests/unit/profiles/selective-profile-removal.test.js
📚 Learning: 2025-07-18T17:09:40.548Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/dependencies.mdc:0-0
Timestamp: 2025-07-18T17:09:40.548Z
Learning: Applies to scripts/modules/dependency-manager.js : Check for and remove references to non-existent tasks during cleanup
Applied to files:
tests/unit/profiles/selective-profile-removal.test.js
📚 Learning: 2025-07-18T17:10:31.810Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/git_workflow.mdc:0-0
Timestamp: 2025-07-18T17:10:31.810Z
Learning: Applies to **/*.{test,spec}.{js,ts,jsx,tsx} : Create a test file if needed and ensure all tests pass before completing a task
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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 : Mock readJSON and writeJSON to avoid real file system interactions in tests.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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 : Mock API calls (e.g., Anthropic/Claude) by mocking the entire module and providing predictable responses.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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 CLI and MCP interfaces with real task data, verify end-to-end workflows across tag contexts, and test error scenarios and recovery in integration tests.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 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.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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 mcp-server/src/core/direct-functions/*.js : Create direct function wrappers in 'mcp-server/src/core/direct-functions/' for MCP tool implementation, following silent mode patterns and using findTasksJsonPath for consistent path resolution.
Applied to files:
tests/unit/profiles/selective-profile-removal.test.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 : The *Direct function is responsible for finding the exact tasks.json path using findTasksJsonPath, relying on the projectRoot passed in args.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 : Never use asynchronous operations in tests. Make all mocks return synchronous values when possible.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.test.js
🧬 Code graph analysis (1)
tests/unit/profiles/selective-profile-removal.test.js (3)
src/utils/rule-transformer.js (5)
result(58-58)result(81-81)result(112-112)result(142-142)result(353-366)src/utils/create-mcp-config.js (1)
result(161-167)mcp-server/src/core/direct-functions/rules.js (1)
result(84-84)
🪛 GitHub Actions: CI
tests/unit/profiles/selective-profile-removal.test.js
[error] 291-291: Selective Rules Removal: removeProfileRules - Selective File Removal: expected to remove directory '/test/project/.cursor/rules' via rmSync with { recursive: true, force: true }, but rmSync was invoked separately for individual files inside the directory (cursor_rules.mdc, taskmaster/dev_workflow.mdc, self_improve.mdc).
[error] 334-334: Selective Rules Removal: removeProfileRules - should remove entire profile directory when completely empty and all rules were Task Master rules and MCP config deleted: expected result.profileDirRemoved to be true, but was false.
🔇 Additional comments (2)
tests/unit/profiles/selective-profile-removal.test.js (2)
274-295: Remove empty .cursor/rules directory when profile rules are deletedCI shows rmSync wasn't called on the directory (only files). Keep the test assertion and update removeProfileRules to rmSync the .cursor/rules directory when it's empty.
File: src/utils/rule-transformer.js (after deleting profile rule files)
Suggested implementation:
import fs from 'fs'; import path from 'path'; function isDirEmpty(p) { try { return fs.readdirSync(p).length === 0; } catch { return false; } } const rulesDir = path.join(projectRoot, '.cursor/rules'); if (fs.existsSync(rulesDir) && isDirEmpty(rulesDir)) { fs.rmSync(rulesDir, { recursive: true, force: true }); // optional: result.profileRulesDirRemoved = true; }
389-409: Lifecycle hook counting is correct — no change required.
rule-transformer adds hookResult.fileCount (falls back to hookResult.success) and also increments result.fileCount for each removed rule file, so lifecycle hook command processing is included in fileCount.
There was a problem hiding this comment.
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 (3)
tests/unit/profiles/selective-profile-removal.test.js (3)
5-9: Fix ESM mock order: mock before importing modules under test.
jest.mockruns after static imports here, soscripts/modules/utils.jsisn’t mocked forrule-transformerandcreate-mcp-config. Switch tojest.unstable_mockModule()and dynamically import the modules inbeforeAll().-import { - removeProfileRules, - getRulesProfile -} from '../../../src/utils/rule-transformer.js'; -import { removeTaskMasterMCPConfiguration } from '../../../src/utils/create-mcp-config.js'; +let removeProfileRules, getRulesProfile, removeTaskMasterMCPConfiguration; // Mock the logger import -jest.mock('../../../scripts/modules/utils.js', () => ({ - log: (level, message) => mockLog[level]?.(message) -})); +beforeAll(async () => { + await jest.unstable_mockModule('../../../scripts/modules/utils.js', () => ({ + log: (level, message) => mockLog[level]?.(message) + })); + ({ removeProfileRules, getRulesProfile } = await import('../../../src/utils/rule-transformer.js')); + ({ removeTaskMasterMCPConfiguration } = await import('../../../src/utils/create-mcp-config.js')); +});Also applies to: 20-22
189-197: Remove non-deterministic assertions; make test deterministic.Tests shouldn’t branch on success. Stabilize mocks and assert success directly.
- // The function may fail due to directory reading issues in the test environment, - // but the core functionality (file removal) should work - if (result.success) { - expect(result.success).toBe(true); - } else { - // If it fails, it should be due to directory reading, not file removal - expect(result.error).toContain('ENOENT'); - expect(result.filesRemoved.length).toBeGreaterThan(0); - } + // Deterministic: mocks guarantee success + expect(result.success).toBe(true);
42-44: Remove unused temp dir and mkdirSync spy.They add noise without affecting behavior.
- let mockMkdirSync; ... - // Create temp directory for testing - tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'task-master-test-')); ... - mockMkdirSync = jest.spyOn(fs, 'mkdirSync').mockImplementation(() => {}); + // No real temp dir needed; all FS ops are mocked ... - // Clean up temp directory - try { - fs.rmSync(tempDir, { recursive: true, force: true }); - } catch (error) { - // Ignore cleanup errors - }Also applies to: 31-31, 53-53, 95-99
♻️ Duplicate comments (1)
tests/unit/profiles/selective-profile-removal.test.js (1)
136-147: Replace call-order readdir mocks with a tiny stateful in-memory FS.Sequencing
.mockReturnValueOnce()is brittle across refactors. Model directories/files in an object and havereaddirSyncreturn by path; update it in yourrmSyncspy.Example sketch (apply in
beforeEach):const fsState = { [path.join(projectRoot, '.cursor/commands')]: ['tm-add-task.md', 'tm-next-task.md'], [path.join(projectRoot, '.cursor/rules')]: ['cursor_rules.mdc', 'taskmaster', 'self_improve.mdc', 'custom_rule.mdc'], [path.join(projectRoot, '.cursor/rules/taskmaster')]: ['dev_workflow.mdc', 'taskmaster.mdc'] }; mockReaddirSync.mockImplementation((p) => fsState[p] ?? []); mockRmSync.mockImplementation((p, opts) => { const dir = path.dirname(p); const base = path.basename(p); if (fsState[dir]) fsState[dir] = fsState[dir].filter(x => x !== base); });Also applies to: 148-176, 254-265, 271-277, 418-425, 469-481, 695-703
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
tests/unit/profiles/selective-profile-removal.test.js(16 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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/unit/profiles/selective-profile-removal.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/selective-profile-removal.test.js
🧠 Learnings (35)
📓 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: assets/AGENTS.md:0-0
Timestamp: 2025-09-01T09:55:15.061Z
Learning: Applies to assets/.claude/commands/taskmaster-next.md : Create .claude/commands/taskmaster-next.md implementing the 4-step workflow to find and show the next task
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 : 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.
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.
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.
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.
📚 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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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 test-specific file paths (e.g., 'test-tasks.json') for all file operations in tests.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 different file paths for each test to avoid test interdependence.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/*.js : Use consistent file naming conventions: 'task_${id.toString().padStart(3, '0')}.txt', use path.join for composing file paths, and use appropriate file extensions (.txt for tasks, .json for data).
Applied to files:
tests/unit/profiles/selective-profile-removal.test.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:
tests/unit/profiles/selective-profile-removal.test.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:
tests/unit/profiles/selective-profile-removal.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:
tests/unit/profiles/selective-profile-removal.test.js
📚 Learning: 2025-07-18T17:09:40.548Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/dependencies.mdc:0-0
Timestamp: 2025-07-18T17:09:40.548Z
Learning: Applies to scripts/modules/dependency-manager.js : Check for and remove references to non-existent tasks during cleanup
Applied to files:
tests/unit/profiles/selective-profile-removal.test.js
📚 Learning: 2025-07-18T17:10:31.810Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/git_workflow.mdc:0-0
Timestamp: 2025-07-18T17:10:31.810Z
Learning: Applies to **/*.{test,spec}.{js,ts,jsx,tsx} : Create a test file if needed and ensure all tests pass before completing a task
Applied to files:
tests/unit/profiles/selective-profile-removal.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 modifications on the in-memory task objects passed to writeJSON.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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 : Never use asynchronous operations in tests. Make all mocks return synchronous values when possible.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 : Mock API calls (e.g., Anthropic/Claude) by mocking the entire module and providing predictable responses.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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 : Mock readJSON and writeJSON to avoid real file system interactions in tests.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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 CLI and MCP interfaces with real task data, verify end-to-end workflows across tag contexts, and test error scenarios and recovery in integration tests.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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 mcp-server/src/core/direct-functions/*.js : Create direct function wrappers in 'mcp-server/src/core/direct-functions/' for MCP tool implementation, following silent mode patterns and using findTasksJsonPath for consistent path resolution.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 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.
Applied to files:
tests/unit/profiles/selective-profile-removal.test.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 : The *Direct function is responsible for finding the exact tasks.json path using findTasksJsonPath, relying on the projectRoot passed in args.
Applied to files:
tests/unit/profiles/selective-profile-removal.test.js
🧬 Code graph analysis (1)
tests/unit/profiles/selective-profile-removal.test.js (3)
src/utils/rule-transformer.js (5)
result(58-58)result(81-81)result(112-112)result(142-142)result(353-366)src/utils/create-mcp-config.js (1)
result(161-167)src/profiles/cursor.js (2)
cursorProfile(224-242)cursorProfile(224-242)
⏰ 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: Test
🔇 Additional comments (2)
tests/unit/profiles/selective-profile-removal.test.js (2)
309-313: Good: assert rules dir removal when emptied.This strengthens behavior checks.
353-353: fileCount semantics: counts lifecycle-hook files AND rule files removed — ensure tests assert the combined total.rule-transformer aggregates hookResult.fileCount (or falls back to hookResult.success) and also increments result.fileCount for each rule file removed. See src/utils/rule-transformer.js (init at 362; aggregation 377–386; increment 484) and src/profiles/cursor.js (onAdd 98–107; onRemove 208–212). Verify tests asserting 4 in tests/unit/profiles/selective-profile-removal.test.js (lines 353, 447–448, 499–500, 723–724) reflect the sum of command files + rule removals.
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (2)
src/profiles/cursor.js (2)
122-146: Defensive: guard against missing assetsDir in onRemove.Prevents
path.join(undefined, ...)and makes the hook safer.-const onRemove = (projectRoot, assetsDir) => { +const onRemove = (projectRoot, assetsDir) => { + if (!assetsDir) { + log('warn', 'onRemove called without assetsDir; aborting to avoid unsafe deletes'); + return { processed: 0, skipped: 0, fileCount: 0, success: 0, failed: 1 }; + }
200-205: Use rmSync instead of deprecated rmdirSync.Avoid deprecation and be explicit.
- if (remainingItems.length === 0 && dir !== targetDir) { - fs.rmdirSync(dir); - } + if (remainingItems.length === 0 && dir !== targetDir) { + fs.rmSync(dir, { recursive: false, force: true }); + }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
src/profiles/cursor.js(2 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.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 (30)
📓 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: assets/AGENTS.md:0-0
Timestamp: 2025-09-01T09:55:15.061Z
Learning: Applies to assets/.claude/commands/taskmaster-next.md : Create .claude/commands/taskmaster-next.md implementing the 4-step workflow to find and show the next task
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 : 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.
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.
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.
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.
📚 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
📚 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: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: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 **/*.js : Use dynamic imports (import()) to avoid initialization order issues in modules.
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-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/.taskmaster/tasks/*.{md,txt} : Treat task files in .taskmaster/tasks (md or txt) as auto-generated; avoid manual edits
Applied to files:
src/profiles/cursor.js
📚 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:
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-08-06T21:12:43.715Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: assets/claude/agents/task-orchestrator.md:1-6
Timestamp: 2025-08-06T21:12:43.715Z
Learning: In the eyaltoledano/claude-task-master repository, agent files are intentionally duplicated between `.claude/agents/` (for internal project use) and `assets/claude/agents/` (as template files for users to copy). This duplication serves different purposes and should be maintained to support both internal development and user distribution needs.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-08-06T21:12:20.981Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: assets/claude/agents/task-executor.md:1-6
Timestamp: 2025-08-06T21:12:20.981Z
Learning: In the eyaltoledano/claude-task-master repository, agent files in assets/claude/agents/ are intended for distribution to users (for copying), while identical files in .claude/agents/ are for internal project use. This intentional duplication serves different purposes and is not a DRY violation.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-08-06T21:13:05.240Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: assets/claude/agents/task-orchestrator.md:69-78
Timestamp: 2025-08-06T21:13:05.240Z
Learning: For Claude agent instruction files in .claude/agents/ and assets/claude/agents/ directories, ignore markdownlint issues (like MD031 blanks-around-fences, MD040 fenced-code-language, MD041 missing top-level heading) as these files follow Claude's specific agent format requirements rather than standard markdown documentation conventions.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-07-18T17:14:29.399Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tasks.mdc:0-0
Timestamp: 2025-07-18T17:14:29.399Z
Learning: Applies to scripts/modules/task-manager.js : Use consistent formatting for task files, include all task properties in text files, and format dependencies with status indicators.
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 scripts/modules/*.js : Use consistent file naming conventions: 'task_${id.toString().padStart(3, '0')}.txt', use path.join for composing file paths, and use appropriate file extensions (.txt for tasks, .json for data).
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-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/task-manager.js : Features that create, read, update, or delete tasks belong in 'scripts/modules/task-manager.js'.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-08-06T21:11:37.259Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: .claude/agents/task-orchestrator.md:0-0
Timestamp: 2025-08-06T21:11:37.259Z
Learning: For files in .claude/agents/ and assets/claude/agents/ directories, ignore markdownlint issues like MD041 (missing top-level heading) as these are Claude Code agent instruction files that follow a specific format with YAML frontmatter and don't need to conform to standard markdown documentation conventions.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-08-06T21:11:57.597Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: .claude/agents/task-executor.md:1-6
Timestamp: 2025-08-06T21:11:57.597Z
Learning: For Claude agent instruction files located in .claude/agents or assets/claude/agents directories, Crunchyman-ralph wants to ignore MarkdownLint issues since these files follow Claude's specific format requirements rather than standard markdown documentation conventions.
Applied to files:
src/profiles/cursor.js
📚 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:
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-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.md : Maintain CLAUDE.md as auto-loaded context for Claude Code
Applied to files:
src/profiles/cursor.js
📚 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-next.md : Create .claude/commands/taskmaster-next.md implementing the 4-step workflow to find and show the next task
Applied to files:
src/profiles/cursor.js
📚 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:
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 : Check if files exist before attempting to delete them, and handle file deletion errors gracefully.
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 : Follow the provided structure for removing subtasks, including options for conversion, file path, and regeneration, with detailed error handling.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-07-18T17:09:40.548Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/dependencies.mdc:0-0
Timestamp: 2025-07-18T17:09:40.548Z
Learning: Applies to scripts/modules/dependency-manager.js : Check for and remove references to non-existent tasks during cleanup
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: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: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 : When referencing files in Cursor rule files, use the format [filename](mdc:path/to/file) or [filename](mdc:filename).
Applied to files:
src/profiles/cursor.js
🧬 Code graph analysis (1)
src/profiles/cursor.js (3)
src/profiles/roo.js (4)
src(36-36)dest(37-37)stats(53-53)sourceDir(11-11)src/utils/rule-transformer.js (10)
stats(446-446)content(175-175)content(277-277)assetsDir(212-212)assetsDir(325-325)targetDir(185-185)targetDir(204-204)targetDir(350-350)filePath(479-479)items(438-438)src/profiles/claude.js (3)
stats(10-10)content(88-88)content(142-142)
⏰ 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: Test
🔇 Additional comments (5)
src/profiles/cursor.js (5)
3-5: Good ESM/core-module imports and repo logger usage.Using
node:specifiers and the shared logger is correct and consistent with repo style.
99-112: Return shape and logging look consistent.Processed/failed/fileCount are exposed as required and message reflects idempotent behavior.
235-254: Profile export looks correct and complete.Name, dirs, hooks, and extensions align with rule‑transformer expectations.
66-79: Approve — transform hook handling OK; asset file count not verified
- Confirmed: src/utils/rule-transformer.js aggregates hook results (success, failed, fileCount) into the overall counters.
- Asset count not validated: the fd run returned 0 due to the path-pattern usage. Re-run with a full-path or directory pattern, e.g.:
fd . 'assets/claude/commands' -e md | wc -l
or
fd --full-path 'assets/claude/commands' -e md | wc -l
and share the output.
82-97: Verify transform coverage for Cursor format.
File: src/profiles/cursor.js — current transform only replaces "/project:tm/" and the specific "Type '/project:tm/' and use tab completion" string. Confirm there are no other Claude-specific tokens (e.g. $ARGUMENTS blocks, tip text, , {{args}}, "Claude" mentions) in assets/claude/commands that require conversion; extend the transform if any are found.
There was a problem hiding this comment.
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 (2)
src/utils/rule-transformer.js (2)
438-476: Incorrect use of fs.readdirSync({ recursive: true }) — recursion not supported.Node’s readdirSync ignores “recursive”; nested files are missed, risking accidental rulesDir deletion when non‑Task Master files exist in subdirs.
- let allFiles = []; + let allFiles = []; if (targetDir === projectRoot || profile.rulesDir === '.') { - // For root directory, manually read without recursion into problematic directories - const items = fs.readdirSync(targetDir); - for (const item of items) { - // Skip directories that can cause issues or are irrelevant - if (item === 'node_modules' || item === '.git' || item === 'dist') { - continue; - } - const itemPath = path.join(targetDir, item); - try { - const stats = fs.lstatSync(itemPath); - if (stats.isFile()) { - allFiles.push(item); - } else if (stats.isDirectory() && !stats.isSymbolicLink()) { - // Only recurse into safe directories - const subFiles = fs.readdirSync(itemPath, { recursive: true }); - subFiles.forEach((subFile) => { - allFiles.push(path.join(item, subFile.toString())); - }); - } - } catch (err) { - // Silently skip files we can't access - } - } + const list = (dir, rel = '') => { + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + const abs = path.join(dir, entry.name); + const r = rel ? path.join(rel, entry.name) : entry.name; + try { + if (entry.isDirectory()) { + if (!['node_modules', '.git', 'dist'].includes(entry.name)) list(abs, r); + } else if (entry.isFile()) { + allFiles.push(r); + } + } catch {} + } + }; + list(targetDir, ''); } else { - // For non-root directories, use normal recursive read - allFiles = fs.readdirSync(targetDir, { recursive: true }); + const list = (dir, rel = '') => { + for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { + const abs = path.join(dir, entry.name); + const r = rel ? path.join(rel, entry.name) : entry.name; + try { + if (entry.isDirectory()) list(abs, r); + else if (entry.isFile()) allFiles.push(r); + } catch {} + } + }; + list(targetDir, ''); }
195-197: Use repository logger instead of console.error.Aligns with logging conventions and testability.
- console.error(`Error converting rule file: ${error.message}`); + log('error', `[Rule Transformer] Error converting rule file: ${error.message}`);
♻️ Duplicate comments (3)
tests/unit/profiles/selective-profile-removal.test.js (1)
336-343: Normalize paths; avoid platform‑fragile .includes checks.Compare normalized paths with path.join(...) equality to prevent Windows separator issues.
- mockExistsSync.mockImplementation((filePath) => { - if (filePath.includes('.cursor')) return true; - if (filePath.includes('.cursor/rules')) return true; - if (filePath.includes('.cursor/commands')) return true; - if (filePath.includes('mcp.json')) return true; + mockExistsSync.mockImplementation((p) => { + const fp = path.normalize(p); + if (fp === path.join(projectRoot, '.cursor')) return true; + if (fp === path.join(projectRoot, '.cursor', 'rules')) return true; + if (fp === path.join(projectRoot, '.cursor', 'commands')) return true; + if (fp === path.join(projectRoot, '.cursor', 'mcp.json')) return true; return false; });src/profiles/cursor.js (2)
168-173: Case‑insensitive .md match for robustness.Handle “.MD/.Md” variants when selecting files to remove.
- } else if (item.endsWith('.md')) { + } else if (item.toLowerCase().endsWith('.md')) {
209-214: Use force on directory cleanup to avoid spurious throws.Harmless but avoids transient errors.
- if (remainingItems.length === 0 && dir !== targetDir) { - fs.rmSync(dir, { recursive: false }); - } + if (remainingItems.length === 0 && dir !== targetDir) { + fs.rmSync(dir, { recursive: false, force: true }); + }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
src/profiles/cursor.js(2 hunks)src/utils/rule-transformer.js(5 hunks)tests/unit/profiles/selective-profile-removal.test.js(15 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.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.jstests/unit/profiles/selective-profile-removal.test.jssrc/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/unit/profiles/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/unit/profiles/selective-profile-removal.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/selective-profile-removal.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
🧠 Learnings (67)
📓 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: .cursor/rules/cursor_rules.mdc:0-0
Timestamp: 2025-07-18T17:09:23.831Z
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.
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.
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.
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.
📚 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.jstests/unit/profiles/selective-profile-removal.test.jssrc/utils/rule-transformer.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.jstests/unit/profiles/selective-profile-removal.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 .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: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: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 **/*.js : Use dynamic imports (import()) to avoid initialization order issues in modules.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-09-02T21:51:27.921Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/src/auth/config.ts:5-7
Timestamp: 2025-09-02T21:51:27.921Z
Learning: The user Crunchyman-ralph prefers not to use node: scheme imports (e.g., 'node:os', 'node:path') for Node.js core modules and considers suggestions to change bare imports to node: scheme as too nitpicky.
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.jstests/unit/profiles/selective-profile-removal.test.js
📚 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/.taskmaster/tasks/*.{md,txt} : Treat task files in .taskmaster/tasks (md or txt) as auto-generated; avoid manual edits
Applied to files:
src/profiles/cursor.js
📚 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:
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.jstests/unit/profiles/selective-profile-removal.test.js
📚 Learning: 2025-08-06T21:12:43.715Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: assets/claude/agents/task-orchestrator.md:1-6
Timestamp: 2025-08-06T21:12:43.715Z
Learning: In the eyaltoledano/claude-task-master repository, agent files are intentionally duplicated between `.claude/agents/` (for internal project use) and `assets/claude/agents/` (as template files for users to copy). This duplication serves different purposes and should be maintained to support both internal development and user distribution needs.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-08-06T21:12:20.981Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: assets/claude/agents/task-executor.md:1-6
Timestamp: 2025-08-06T21:12:20.981Z
Learning: In the eyaltoledano/claude-task-master repository, agent files in assets/claude/agents/ are intended for distribution to users (for copying), while identical files in .claude/agents/ are for internal project use. This intentional duplication serves different purposes and is not a DRY violation.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-08-06T21:13:05.240Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: assets/claude/agents/task-orchestrator.md:69-78
Timestamp: 2025-08-06T21:13:05.240Z
Learning: For Claude agent instruction files in .claude/agents/ and assets/claude/agents/ directories, ignore markdownlint issues (like MD031 blanks-around-fences, MD040 fenced-code-language, MD041 missing top-level heading) as these files follow Claude's specific agent format requirements rather than standard markdown documentation conventions.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-07-18T17:14:29.399Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tasks.mdc:0-0
Timestamp: 2025-07-18T17:14:29.399Z
Learning: Applies to scripts/modules/task-manager.js : Use consistent formatting for task files, include all task properties in text files, and format dependencies with status indicators.
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 scripts/modules/*.js : Use consistent file naming conventions: 'task_${id.toString().padStart(3, '0')}.txt', use path.join for composing file paths, and use appropriate file extensions (.txt for tasks, .json for data).
Applied to files:
src/profiles/cursor.jstests/unit/profiles/selective-profile-removal.test.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-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/task-manager.js : Features that create, read, update, or delete tasks belong in 'scripts/modules/task-manager.js'.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-08-06T21:11:37.259Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: .claude/agents/task-orchestrator.md:0-0
Timestamp: 2025-08-06T21:11:37.259Z
Learning: For files in .claude/agents/ and assets/claude/agents/ directories, ignore markdownlint issues like MD041 (missing top-level heading) as these are Claude Code agent instruction files that follow a specific format with YAML frontmatter and don't need to conform to standard markdown documentation conventions.
Applied to files:
src/profiles/cursor.js
📚 Learning: 2025-08-06T21:11:57.597Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: .claude/agents/task-executor.md:1-6
Timestamp: 2025-08-06T21:11:57.597Z
Learning: For Claude agent instruction files located in .claude/agents or assets/claude/agents directories, Crunchyman-ralph wants to ignore MarkdownLint issues since these files follow Claude's specific format requirements rather than standard markdown documentation conventions.
Applied to files:
src/profiles/cursor.js
📚 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:
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-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.md : Maintain CLAUDE.md as auto-loaded context for Claude Code
Applied to files:
src/profiles/cursor.js
📚 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-next.md : Create .claude/commands/taskmaster-next.md implementing the 4-step workflow to find and show the next task
Applied to files:
src/profiles/cursor.js
📚 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:
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 : Check if files exist before attempting to delete them, and handle file deletion errors gracefully.
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 : Follow the provided structure for removing subtasks, including options for conversion, file path, and regeneration, with detailed error handling.
Applied to files:
src/profiles/cursor.jssrc/utils/rule-transformer.js
📚 Learning: 2025-07-18T17:09:40.548Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/dependencies.mdc:0-0
Timestamp: 2025-07-18T17:09:40.548Z
Learning: Applies to scripts/modules/dependency-manager.js : Check for and remove references to non-existent tasks during cleanup
Applied to files:
src/profiles/cursor.jstests/unit/profiles/selective-profile-removal.test.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/{tools,core/direct-functions}/*.js : Use kebab-case for all file names in mcp-server/src/tools/ and mcp-server/src/core/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.jstests/unit/profiles/selective-profile-removal.test.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: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 : When referencing files in Cursor rule files, use the format [filename](mdc:path/to/file) or [filename](mdc:filename).
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 : Use mock-fs to mock file system operations in tests, and restore the file system after each test.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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 modifications on the in-memory task objects passed to writeJSON.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 : Mock readJSON and writeJSON to avoid real file system interactions in tests.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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: Create simplified test functions that focus only on core logic and remove file system operations, API calls, and other external dependencies.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 test-specific file paths (e.g., 'test-tasks.json') for all file operations in tests.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 different file paths for each test to avoid test interdependence.
Applied to files:
tests/unit/profiles/selective-profile-removal.test.js
📚 Learning: 2025-07-18T17:10:31.810Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/git_workflow.mdc:0-0
Timestamp: 2025-07-18T17:10:31.810Z
Learning: Applies to **/*.{test,spec}.{js,ts,jsx,tsx} : Create a test file if needed and ensure all tests pass before completing a task
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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 : Never use asynchronous operations in tests. Make all mocks return synchronous values when possible.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 : Mock API calls (e.g., Anthropic/Claude) by mocking the entire module and providing predictable responses.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.test.js
📚 Learning: 2025-07-18T17:18:17.759Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/utilities.mdc:0-0
Timestamp: 2025-07-18T17:18:17.759Z
Learning: Applies to scripts/modules/utils.js : Use `path.join()` for cross-platform path construction, `path.resolve()` for absolute paths, and validate paths before file operations.
Applied to files:
tests/unit/profiles/selective-profile-removal.test.js
📚 Learning: 2025-07-18T17:18:17.759Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/utilities.mdc:0-0
Timestamp: 2025-07-18T17:18:17.759Z
Learning: Applies to mcp-server/src/tools/utils.js : Use `normalizeProjectRoot(rawPath, log)`, `getRawProjectRootFromSession(session, log)`, and `withNormalizedProjectRoot(executeFn)` in `mcp-server/src/tools/utils.js` to ensure project root paths are normalized for MCP tools.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 use real AI client initialization logic in tests; create test-specific paths that bypass client initialization.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 : 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.
Applied to files:
tests/unit/profiles/selective-profile-removal.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: Applies to scripts/modules/task-manager/*.js : Files in scripts/modules/task-manager/ should each handle a specific action related to task management (e.g., add-task.js, expand-task.js), supporting the tagged task lists system and backward compatibility.
Applied to files:
tests/unit/profiles/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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/selective-profile-removal.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 : Create self-contained test implementations rather than using real implementations when testing modules with initialization issues.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 CLI and MCP interfaces with real task data, verify end-to-end workflows across tag contexts, and test error scenarios and recovery in integration tests.
Applied to files:
tests/unit/profiles/selective-profile-removal.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 mcp-server/src/core/direct-functions/*.js : Create direct function wrappers in 'mcp-server/src/core/direct-functions/' for MCP tool implementation, following silent mode patterns and using findTasksJsonPath for consistent path resolution.
Applied to files:
tests/unit/profiles/selective-profile-removal.test.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 : The *Direct function is responsible for finding the exact tasks.json path using findTasksJsonPath, relying on the projectRoot passed in args.
Applied to files:
tests/unit/profiles/selective-profile-removal.test.js
📚 Learning: 2025-07-18T17:09:40.548Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/dependencies.mdc:0-0
Timestamp: 2025-07-18T17:09:40.548Z
Learning: Applies to scripts/modules/dependency-manager.js : Track and report changes made during dependency cleanup
Applied to files:
src/utils/rule-transformer.js
🧬 Code graph analysis (3)
src/profiles/cursor.js (3)
src/profiles/roo.js (4)
src(36-36)dest(37-37)stats(53-53)sourceDir(11-11)src/utils/rule-transformer.js (11)
stats(447-447)content(175-175)content(277-277)assetsDir(212-212)assetsDir(325-325)assetsDir(372-372)targetDir(185-185)targetDir(204-204)targetDir(350-350)filePath(480-480)items(439-439)src/profiles/claude.js (3)
stats(10-10)content(88-88)content(142-142)
tests/unit/profiles/selective-profile-removal.test.js (2)
src/utils/rule-transformer.js (7)
filePath(480-480)result(58-58)result(81-81)result(112-112)result(142-142)result(353-366)removeProfileRules(349-605)src/profiles/cursor.js (2)
cursorProfile(245-263)cursorProfile(245-263)
src/utils/rule-transformer.js (2)
src/utils/asset-resolver.js (2)
assetsDir(65-65)getAssetsDir(21-57)mcp-server/src/core/direct-functions/rules.js (2)
result(84-84)error(152-153)
⏰ 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: Test
🔇 Additional comments (1)
src/profiles/cursor.js (1)
81-97: Verify transform covers Cursor argument syntax conversions.Current transform only handles “/project:tm/” phrasing. If the PR claims Claude $ARGUMENTS → Cursor syntax conversion, ensure those replacements are implemented or intentionally not needed.
| const isMarkdown = path.extname(src).toLowerCase() === '.md'; | ||
| // Preserve existing user files; do not overwrite | ||
| if (!fs.existsSync(dest)) { | ||
| if (transformFn && isMarkdown) { | ||
| const content = fs.readFileSync(src, 'utf8'); | ||
| const transformed = transformFn(content); | ||
| fs.writeFileSync(dest, transformed, { encoding: 'utf8', flag: 'wx' }); | ||
| } else { | ||
| fs.copyFileSync(src, dest); | ||
| } | ||
| } | ||
| if (isMarkdown) count++; |
There was a problem hiding this comment.
Make copy atomic; avoid TOCTOU on non‑transform branch.
Use COPYFILE_EXCL and drop existsSync to prevent races and unintended overwrites.
- // Preserve existing user files; do not overwrite
- if (!fs.existsSync(dest)) {
- if (transformFn && isMarkdown) {
- const content = fs.readFileSync(src, 'utf8');
- const transformed = transformFn(content);
- fs.writeFileSync(dest, transformed, { encoding: 'utf8', flag: 'wx' });
- } else {
- fs.copyFileSync(src, dest);
- }
- }
+ // Preserve existing user files; do not overwrite
+ if (transformFn && isMarkdown) {
+ try {
+ fs.writeFileSync(dest, transformFn(fs.readFileSync(src, 'utf8')), { encoding: 'utf8', flag: 'wx' });
+ } catch (e) {
+ // EEXIST is fine (idempotent); warn only on other errors
+ if (e?.code !== 'EEXIST') throw e;
+ }
+ } else {
+ try {
+ fs.copyFileSync(src, dest, fs.constants.COPYFILE_EXCL);
+ } catch (e) {
+ if (e?.code !== 'EEXIST') throw e;
+ }
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const isMarkdown = path.extname(src).toLowerCase() === '.md'; | |
| // Preserve existing user files; do not overwrite | |
| if (!fs.existsSync(dest)) { | |
| if (transformFn && isMarkdown) { | |
| const content = fs.readFileSync(src, 'utf8'); | |
| const transformed = transformFn(content); | |
| fs.writeFileSync(dest, transformed, { encoding: 'utf8', flag: 'wx' }); | |
| } else { | |
| fs.copyFileSync(src, dest); | |
| } | |
| } | |
| if (isMarkdown) count++; | |
| const isMarkdown = path.extname(src).toLowerCase() === '.md'; | |
| // Preserve existing user files; do not overwrite | |
| if (transformFn && isMarkdown) { | |
| try { | |
| fs.writeFileSync(dest, transformFn(fs.readFileSync(src, 'utf8')), { encoding: 'utf8', flag: 'wx' }); | |
| } catch (e) { | |
| // EEXIST is fine (idempotent); warn only on other errors | |
| if (e?.code !== 'EEXIST') throw e; | |
| } | |
| } else { | |
| try { | |
| fs.copyFileSync(src, dest, fs.constants.COPYFILE_EXCL); | |
| } catch (e) { | |
| if (e?.code !== 'EEXIST') throw e; | |
| } | |
| } | |
| if (isMarkdown) count++; |
🤖 Prompt for AI Agents
In src/profiles/cursor.js around lines 22 to 33: remove the pre-check using
fs.existsSync and make the copy atomic by using exclusive operations and
handling EEXIST; for the non-transform branch call fs.copyFileSync(src, dest,
fs.constants.COPYFILE_EXCL) inside a try/catch and ignore or handle the EEXIST
error instead of relying on existsSync, for the transform branch keep
fs.writeFileSync(dest, transformed, { encoding: 'utf8', flag: 'wx' }) inside the
same try/catch, and only increment count when isMarkdown and the write/copy
succeeded.
| return { | ||
| processed: processed, | ||
| skipped: fileCount - processed, | ||
| fileCount: fileCount, | ||
| success: processed, | ||
| failed: fileCount - processed | ||
| }; |
There was a problem hiding this comment.
Don’t report “skipped” as failures in hook result.
failed should reflect actual copy/write errors, not (fileCount - processed). This inflates upstream “failed conversions” totals.
return {
- processed: processed,
- skipped: fileCount - processed,
- fileCount: fileCount,
- success: processed,
- failed: fileCount - processed
+ processed,
+ skipped: fileCount - processed,
+ fileCount,
+ success: processed,
+ failed: 0
};📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| return { | |
| processed: processed, | |
| skipped: fileCount - processed, | |
| fileCount: fileCount, | |
| success: processed, | |
| failed: fileCount - processed | |
| }; | |
| return { | |
| processed, | |
| skipped: fileCount - processed, | |
| fileCount, | |
| success: processed, | |
| failed: 0 | |
| }; |
🤖 Prompt for AI Agents
In src/profiles/cursor.js around lines 106 to 112, the hook result currently
sets failed to fileCount - processed which treats skipped items as failures;
instead maintain and use a separate failed counter that increments only on real
copy/write errors, set failed to that failedCount, and compute skipped as
fileCount - processed - failed (or use an explicit skipped counter if already
tracked); ensure success remains processed and return the three distinct
counters (processed/success, skipped, failed).
| const assetsDir = getAssetsDir(); | ||
| profile.onAddRulesProfile(projectRoot, assetsDir); | ||
| const hookResult = profile.onAddRulesProfile(projectRoot, assetsDir); | ||
| log( | ||
| 'debug', | ||
| `[Rule Transformer] Called onAddRulesProfile for ${profile.profileName}` | ||
| ); | ||
|
|
||
| /** | ||
| * Hook Contract: onAddRulesProfile can optionally return an object with count information | ||
| * Expected shape: { success: number, failed: number, fileCount?: number } | ||
| * - success: number of successful operations (e.g., files processed) | ||
| * - failed: number of failed operations | ||
| * - fileCount: optional total file count for reporting | ||
| * | ||
| * Note: This is optional - hooks can also return nothing/undefined | ||
| */ | ||
| if ( | ||
| hookResult && | ||
| typeof hookResult === 'object' && | ||
| typeof hookResult.success === 'number' | ||
| ) { | ||
| success += hookResult.success; | ||
| failed += hookResult.failed || 0; | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick
Reconsider adding hookResult.failed to conversion failures.
Hook “failed” from onAdd represents asset copy issues/skip counts, not rule conversion failures; aggregating it here can mislead CLI summaries.
- if (hookResult && typeof hookResult === 'object' && typeof hookResult.success === 'number') {
- success += hookResult.success;
- failed += hookResult.failed || 0;
- }
+ if (hookResult && typeof hookResult === 'object' && typeof hookResult.success === 'number') {
+ success += hookResult.success;
+ // Treat hookResult.failed as non-conversion failures; do not add to rule conversion 'failed'
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const assetsDir = getAssetsDir(); | |
| profile.onAddRulesProfile(projectRoot, assetsDir); | |
| const hookResult = profile.onAddRulesProfile(projectRoot, assetsDir); | |
| log( | |
| 'debug', | |
| `[Rule Transformer] Called onAddRulesProfile for ${profile.profileName}` | |
| ); | |
| /** | |
| * Hook Contract: onAddRulesProfile can optionally return an object with count information | |
| * Expected shape: { success: number, failed: number, fileCount?: number } | |
| * - success: number of successful operations (e.g., files processed) | |
| * - failed: number of failed operations | |
| * - fileCount: optional total file count for reporting | |
| * | |
| * Note: This is optional - hooks can also return nothing/undefined | |
| */ | |
| if ( | |
| hookResult && | |
| typeof hookResult === 'object' && | |
| typeof hookResult.success === 'number' | |
| ) { | |
| success += hookResult.success; | |
| failed += hookResult.failed || 0; | |
| } | |
| const assetsDir = getAssetsDir(); | |
| const hookResult = profile.onAddRulesProfile(projectRoot, assetsDir); | |
| log( | |
| 'debug', | |
| `[Rule Transformer] Called onAddRulesProfile for ${profile.profileName}` | |
| ); | |
| /** | |
| * Hook Contract: onAddRulesProfile can optionally return an object with count information | |
| * Expected shape: { success: number, failed: number, fileCount?: number } | |
| * - success: number of successful operations (e.g., files processed) | |
| * - failed: number of failed operations | |
| * - fileCount: optional total file count for reporting | |
| * | |
| * Note: This is optional - hooks can also return nothing/undefined | |
| */ | |
| if ( | |
| hookResult && | |
| typeof hookResult === 'object' && | |
| typeof hookResult.success === 'number' | |
| ) { | |
| success += hookResult.success; | |
| // Treat hookResult.failed as non-conversion failures; do not add to rule conversion 'failed' | |
| } |
🤖 Prompt for AI Agents
In src/utils/rule-transformer.js around lines 212 to 235, the code adds
hookResult.failed to the rule-conversion failure tally which is misleading
because onAddRulesProfile.failed refers to asset copy/skip counts, not
conversion failures; remove the line that increments failed with
hookResult.failed and either ignore that value for CLI conversion summaries or
store it in a separate variable (e.g., assetCopyFailures) and log/report it
separately so conversion failure counts remain accurate.
| // Set up spies on fs methods | ||
| mockExistsSync = jest.spyOn(fs, 'existsSync'); | ||
| mockRmSync = jest.spyOn(fs, 'rmSync').mockImplementation(() => {}); | ||
| mockReaddirSync = jest.spyOn(fs, 'readdirSync'); | ||
| mockRmSync = jest.spyOn(fs, 'rmSync').mockImplementation((filePath) => { | ||
| // Remove file from in-memory filesystem | ||
| const dir = path.dirname(filePath); | ||
| const filename = path.basename(filePath); | ||
| if (fileSystem[dir]) { | ||
| const index = fileSystem[dir].indexOf(filename); | ||
| if (index === -1) { | ||
| throw new Error( | ||
| `ENOENT: no such file or directory, unlink '${filePath}'` | ||
| ); | ||
| } | ||
| fileSystem[dir].splice(index, 1); | ||
| } | ||
| }); | ||
| mockReaddirSync = jest |
There was a problem hiding this comment.
🧹 Nitpick
rmSync stub doesn’t handle directory deletions.
If later assertions depend on actual directory removal, extend the stub to delete directory entries from fileSystem and allow recursive removals.
- mockRmSync = jest.spyOn(fs, 'rmSync').mockImplementation((filePath) => {
- const dir = path.dirname(filePath);
- const filename = path.basename(filePath);
- if (fileSystem[dir]) {
- const index = fileSystem[dir].indexOf(filename);
- if (index === -1) {
- throw new Error(`ENOENT: no such file or directory, unlink '${filePath}'`);
- }
- fileSystem[dir].splice(index, 1);
- }
- });
+ mockRmSync = jest.spyOn(fs, 'rmSync').mockImplementation((p, opts = {}) => {
+ const target = path.normalize(p);
+ const parent = path.dirname(target);
+ const name = path.basename(target);
+ if (fileSystem[target] && (opts.recursive || opts.force)) {
+ // Removing a directory: clear its listing and remove reference from parent
+ delete fileSystem[target];
+ if (fileSystem[parent]) {
+ fileSystem[parent] = fileSystem[parent].filter((x) => x !== name);
+ }
+ return;
+ }
+ if (fileSystem[parent]) {
+ const i = fileSystem[parent].indexOf(name);
+ if (i === -1 && !opts.force) {
+ throw new Error(`ENOENT: no such file or directory, unlink '${p}'`);
+ }
+ if (i !== -1) fileSystem[parent].splice(i, 1);
+ }
+ });🤖 Prompt for AI Agents
In tests/unit/profiles/selective-profile-removal.test.js around lines 51-67, the
mock implementation of fs.rmSync only removes a file entry and throws when
filename not found; extend it to handle directory removals by detecting if the
provided filePath corresponds to a directory in the in-memory fileSystem and,
when options.recursive (or second arg === { recursive: true }) is passed,
recursively remove that directory and all nested entries from the fileSystem; if
recursive is not set and the path is a non-empty directory, throw an appropriate
ENOENT/EPERM-like error or mimic Node's behaviour for rmSync on directories, and
ensure the stub still throws ENOENT when the path truly doesn't exist.
|
Coderabbit went down the rabbit hole with this PR. Submitting a fresh one. |
Overview
This PR adds comprehensive support for Cursor IDE's new custom slash commands feature, bringing all 47 Task Master commands to Cursor users as native
/tm-*slash commands.What's New
When users add the Cursor profile to their Task Master project, they now automatically get:
/tm-add-task,/tm-next-task,/tm-show-task, etc.)User Impact
Before
task-masterCLI commandsAfter
/tm-in Cursor to see all available Task Master commandsImplementation Details
Command Structure
assets/claude/commands/tm/assets/cursor/commands/$ARGUMENTSsyntax to Cursor's native formattm-category-action.mdpatternExamples
Automatic Distribution
task-master rules add cursorFiles Added/Modified
New Files
assets/cursor/commands/- 47 new command files (tm-*.md).changeset/cursor-slash-commands.md- Changeset for the featureModified Files
src/profiles/cursor.js- Enhanced with lifecycle hooks for command distributionsrc/utils/rule-transformer.js- Enhanced to support lifecycle hook return values and file countingscripts/modules/commands.js- Updated summary generation to show accurate file countsTest Files Updated
tests/unit/profiles/selective-profile-removal.test.js- Updated for new cursor profile behavior with lifecycle hookstests/unit/profiles/rule-transformer-cursor.test.js- Cursor rule transformation teststests/unit/profiles/cursor-integration.test.js- Cursor integration teststests/integration/profiles/cursor-init-functionality.test.js- Cursor initialization testsKey Technical Fixes
Summary Accuracy
Lifecycle Hook Integration
onAdd/onRemovevsonAddRulesProfile/onRemoveRulesProfile)[INFO]/[SUCCESS]format matching system patternsUser Experience
Testing
Migration Guide
Users upgrading Task Master will get Cursor commands automatically:
Commands appear immediately in Cursor's slash command interface.

Summary by CodeRabbit
New Features
Bug Fixes
Tests
Documentation