Conversation
🦋 Changeset detectedLatest commit: 4c2801d 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 |
WalkthroughSwitch CLI root to use Commander.Command, source CLI version from build-time TM_PUBLIC_VERSION, add and export resolveComplexityReportPath utility, inject TM_PUBLIC_VERSION at build, bump prerelease versions/changelogs, and update tests and assets paths accordingly. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant User
participant CLI as scripts/modules/commands.js
participant Cmd as Commander.Command
participant Resolver as resolveComplexityReportPath
Note over CLI,Cmd: CLI constructed with new Command() and version from TM_PUBLIC_VERSION
User->>CLI: runCLI(argv)
activate CLI
CLI->>Cmd: setupCLI() -> new Command()
CLI->>Cmd: .version(process.env.TM_PUBLIC_VERSION || 'unknown')
CLI->>Cmd: registerCommands(...)
User->>Cmd: invoke subcommand
alt subcommand needs complexity report path
Cmd->>Resolver: resolveComplexityReportPath({projectRoot, tag, output})
Resolver-->>Cmd: resolved file path
end
Cmd-->>User: command result / exit
deactivate CLI
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Pre-merge checks and finishing touches❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
scripts/modules/commands.js (6)
3288-3292: Fix ReferenceError: tasksPath is undefined in remove-task error pathWhen no valid tasks are found, this path references an undefined variable.
- console.error( - chalk.red(`Error: No valid tasks found in ${tasksPath}`) - ); + console.error( + chalk.red(`Error: No valid tasks found in ${taskMaster.getTasksPath()}`) + );
3614-3623: Provider-flag validation misses --azure and --vertexMultiple provider flags can be passed without tripping the guard. Include azure and vertex.
- const providerFlags = [ - options.openrouter, - options.ollama, - options.bedrock, - options.claudeCode, - options.geminiCli - ].filter(Boolean).length; + const providerFlags = [ + options.openrouter, + options.ollama, + options.bedrock, + options.claudeCode, + options.geminiCli, + options.azure, + options.vertex + ].filter(Boolean).length;
808-815: Avoid private Commander property _nameUse the public API instead of relying on the private _name field.
- const commandName = this._name || 'unknown'; + const commandName = typeof this.name === 'function' ? this.name() : 'unknown';
1740-1746: Unify complexity-report option naming across commandsThree different flags exist for the same concept: expand (--complexity-report), next (-r/--report), analyze-complexity (-o/--output). Add aliases to converge on --complexity-report without breaking existing usage.
Example for next:
.option( - '-r, --report <report>', - 'Path to the complexity report file', + '-r, --report <report>', + 'Path to the complexity report file', COMPLEXITY_REPORT_FILE ) + .option('--complexity-report <file>', 'Alias of --report')And in action:
- if (options.report && options.report !== COMPLEXITY_REPORT_FILE) { - initOptions.complexityReportPath = options.report; - } + const reportPathOpt = options.complexityReport || options.report; + if (reportPathOpt && reportPathOpt !== COMPLEXITY_REPORT_FILE) { + initOptions.complexityReportPath = reportPathOpt; + }Apply similar aliases to analyze-complexity (accept --complexity-report as alias for --output).
5268-5276: JSDoc params don’t match the function signatureDocument the destructured object correctly to avoid confusion.
- * @param {string|undefined} outputOpt --output value from CLI (may be undefined) - * @param {string} targetTag resolved tag (defaults to 'master') - * @param {string} projectRoot absolute project root + * @param {Object} params + * @param {string} params.projectRoot absolute project root + * @param {string} [params.tag='master'] resolved tag (defaults to 'master') + * @param {string} [params.output] --output value from CLI (may be undefined)
5278-5286: Make tag-based filename derivation robust to extension changesAvoid string replace on ".json"; use path.parse to preserve arbitrary extensions.
- // 2. default naming - const base = path.join(projectRoot, COMPLEXITY_REPORT_FILE); - return tag !== 'master' ? base.replace('.json', `_${tag}.json`) : base; + // 2. default naming + const base = path.join(projectRoot, COMPLEXITY_REPORT_FILE); + const { dir, name, ext } = path.parse(base); + const suffix = tag !== 'master' ? `_${tag}` : ''; + return path.join(dir, `${name}${suffix}${ext || '.json'}`);
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (1)
scripts/modules/commands.js(2 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
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.js
🧠 Learnings (15)
📓 Common learnings
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 : Export the registerCommands function and keep the CLI setup code clean and maintainable.
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 : Export the registerCommands function and keep the CLI setup code clean and maintainable.
Learnt from: mm-parthy
PR: eyaltoledano/claude-task-master#943
File: scripts/modules/task-manager/list-tasks.js:0-0
Timestamp: 2025-07-18T08:29:52.384Z
Learning: TODO comments about adding tag support to internal functions like readComplexityReport are obsolete in the boundary-first tag resolution pattern because report paths are already resolved at the CLI command boundary layer before reaching these functions.
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.
📚 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/commands.js : 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.
Applied to files:
scripts/modules/commands.js
📚 Learning: 2025-07-18T08:29:52.384Z
Learnt from: mm-parthy
PR: eyaltoledano/claude-task-master#943
File: scripts/modules/task-manager/list-tasks.js:0-0
Timestamp: 2025-07-18T08:29:52.384Z
Learning: TODO comments about adding tag support to internal functions like readComplexityReport are obsolete in the boundary-first tag resolution pattern because report paths are already resolved at the CLI command boundary layer before reaching these functions.
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 : Use kebab-case for command names (e.g., analyze-complexity) and descriptive, action-oriented names.
Applied to files:
scripts/modules/commands.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 : Export the registerCommands function and keep the CLI setup code clean and maintainable.
Applied to files:
scripts/modules/commands.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/commands.js : Follow the Commander.js model for subcommand structure in CLI commands.
Applied to files:
scripts/modules/commands.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/commands.js : Use consistent patterns for option naming and help text in CLI 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 : Follow the provided command template structure for all CLI commands using Commander.js, including descriptive command names, option definitions, and async action handlers.
Applied to files:
scripts/modules/commands.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:
scripts/modules/commands.js
📚 Learning: 2025-09-22T16:42:10.070Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: public/assets/.windsurfrules:0-0
Timestamp: 2025-09-22T16:42:10.070Z
Learning: Use the task-master CLI as the primary interface instead of node scripts/dev.js; install globally with npm -g or use npx; all commands accept the same options and include additional commands like init
Applied to files:
scripts/modules/commands.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: For CLI usage, install Taskmaster globally with `npm install -g task-master-ai` or use locally via `npx task-master-ai ...`.
Applied to files:
scripts/modules/commands.js
📚 Learning: 2025-09-03T12:15:03.208Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: apps/cli/src/commands/auth.command.ts:222-224
Timestamp: 2025-09-03T12:15:03.208Z
Learning: The CLI can be invoked using both "task-master" and "tm" as aliases - both forms are valid and acceptable in help text, documentation, and examples.
Applied to files:
scripts/modules/commands.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: Use the Taskmaster command set (`task-master` CLI or MCP tools) for all task management operations: listing, expanding, updating, tagging, and status changes.
Applied to files:
scripts/modules/commands.js
📚 Learning: 2025-07-18T17:10:53.657Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/glossary.mdc:0-0
Timestamp: 2025-07-18T17:10:53.657Z
Learning: Guidelines for implementing CLI commands using Commander.js (commands.mdc).
Applied to files:
scripts/modules/commands.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 : Follow the provided command template structure for all CLI commands using Commander.js, including use of .command(), .description(), .option(), and .action() methods.
Applied to files:
scripts/modules/commands.js
⏰ 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)
scripts/modules/commands.js (1)
6-6: LGTM: switch to Commander’s Command instance is correctNo issues with importing Command explicitly.
| const programInstance = new Command() | ||
| .name('dev') | ||
| .description('AI-driven development task management') |
There was a problem hiding this comment.
Fix CLI name: use 'task-master' instead of 'dev'
Current name shows as "dev" in help/usage. Set to 'task-master' to match docs and existing messages; keep "tm" as a documented alias.
- const programInstance = new Command()
- .name('dev')
+ const programInstance = new Command()
+ .name('task-master')📝 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 programInstance = new Command() | |
| .name('dev') | |
| .description('AI-driven development task management') | |
| const programInstance = new Command() | |
| .name('task-master') | |
| .description('AI-driven development task management') |
🤖 Prompt for AI Agents
In scripts/modules/commands.js around lines 5079 to 5081, the CLI is being
created with the name 'dev' which causes help/usage to show the wrong command;
change the command name to 'task-master' and add the documented alias 'tm'
(e.g., use the Command API to set name to "task-master" and call alias("tm")) so
help, usage, and generated messages match the docs.
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (5)
.changeset/pre.json(1 hunks)CHANGELOG.md(1 hunks)apps/extension/CHANGELOG.md(1 hunks)apps/extension/package.json(2 hunks)package.json(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
package.json
📄 CodeRabbit inference engine (.cursor/rules/test_workflow.mdc)
Add and update test scripts in package.json to include test, test:watch, test:coverage, test:unit, test:integration, test:e2e, and test:ci
Files:
package.json
.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/pre.json
🧠 Learnings (11)
📓 Common learnings
Learnt from: mm-parthy
PR: eyaltoledano/claude-task-master#943
File: scripts/modules/task-manager/list-tasks.js:0-0
Timestamp: 2025-07-18T08:29:52.384Z
Learning: TODO comments about adding tag support to internal functions like readComplexityReport are obsolete in the boundary-first tag resolution pattern because report paths are already resolved at the CLI command boundary layer before reaching these functions.
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 : Export the registerCommands function and keep the CLI setup code clean and maintainable.
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 : Export the registerCommands function and keep the CLI setup code clean and maintainable.
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.
📚 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: For CLI usage, install Taskmaster globally with `npm install -g task-master-ai` or use locally via `npx task-master-ai ...`.
Applied to files:
package.jsonapps/extension/package.json
📚 Learning: 2025-09-22T16:42:10.070Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: public/assets/.windsurfrules:0-0
Timestamp: 2025-09-22T16:42:10.070Z
Learning: Use the task-master CLI as the primary interface instead of node scripts/dev.js; install globally with npm -g or use npx; all commands accept the same options and include additional commands like init
Applied to files:
package.json
📚 Learning: 2025-09-22T19:45:13.301Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1232
File: packages/build-config/package.json:14-15
Timestamp: 2025-09-22T19:45:13.301Z
Learning: In the eyaltoledano/claude-task-master repository, Crunchyman-ralph intentionally omits version fields from internal packages (like tm/build-config) to prevent changesets from releasing new versions for these packages. This is the desired behavior for internal tooling packages that should not be published or versioned independently.
Applied to files:
package.jsonCHANGELOG.md
📚 Learning: 2025-07-31T20:49:04.638Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#997
File: apps/extension/package.publish.json:2-8
Timestamp: 2025-07-31T20:49:04.638Z
Learning: In the eyaltoledano/claude-task-master repository, the VS Code extension uses a 3-file packaging system where package.json (with name "extension") is for development within the monorepo, while package.publish.json (with name "task-master-hamster") contains the clean manifest for VS Code marketplace publishing. The different names are intentional and serve distinct purposes in the build and publishing workflow.
Applied to files:
apps/extension/package.json
📚 Learning: 2025-09-03T12:16:15.866Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/package.json:13-64
Timestamp: 2025-09-03T12:16:15.866Z
Learning: For internal packages in the claude-task-master project, Crunchyman-ralph prefers pointing package.json "types" entries to src .ts files rather than dist .d.ts files for better developer experience (DX), as the packages are not being exported as SDKs.
Applied to files:
apps/extension/package.json
📚 Learning: 2025-08-07T13:00:22.966Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1090
File: apps/extension/package.json:241-243
Timestamp: 2025-08-07T13:00:22.966Z
Learning: In monorepos, local packages should use "*" as the version constraint in package.json dependencies, as recommended by npm. This ensures the local version from within the same workspace is always used, rather than attempting to resolve from external registries. This applies to packages like task-master-ai within the eyaltoledano/claude-task-master monorepo.
Applied to files:
apps/extension/package.json
📚 Learning: 2025-09-17T19:09:08.882Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1211
File: jest.resolver.cjs:8-15
Timestamp: 2025-09-17T19:09:08.882Z
Learning: In the eyaltoledano/claude-task-master project, the team only uses .ts files and does not plan to use .tsx or .mts extensions, so Jest resolver and build tooling should focus on .js → .ts mapping only.
Applied to files:
apps/extension/package.json
📚 Learning: 2025-09-22T19:45:04.246Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1232
File: packages/tm-core/package.json:50-51
Timestamp: 2025-09-22T19:45:04.246Z
Learning: In the eyaltoledano/claude-task-master project, Crunchyman-ralph intentionally omits version fields from internal/private packages in package.json files to prevent changesets from releasing new versions of these packages while still allowing them to be processed for dependency updates. The changesets warnings about missing versions are acceptable as they don't break the process and achieve the desired behavior of only releasing public packages.
Applied to files:
CHANGELOG.mdapps/extension/CHANGELOG.md
📚 Learning: 2025-08-11T12:30:23.843Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-11T12:30:23.843Z
Learning: Import Task Master's development workflow commands and guidelines; treat the contents of ./.taskmaster/CLAUDE.md as if included in the main CLAUDE.md
Applied to files:
CHANGELOG.md
📚 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 .changeset/* : Create appropriate changesets for new features, use semantic versioning, include tagged system information in release notes, and document breaking changes if any.
Applied to files:
.changeset/pre.json
🔇 Additional comments (5)
package.json (2)
3-3: RC version bump looks good.Pre-release tag aligns with the RC flow introduced in this PR.
20-27: Test scripts meet repo guidelines.Required scripts (test, test:watch, test:coverage, test:unit, test:integration, test:e2e, test:ci) are present.
CHANGELOG.md (1)
3-8: Changelog entry for 0.27.1-rc.0 is consistent with the pre-release.Entry is scoped to the module-not-found fix; OK for an RC patch.
apps/extension/CHANGELOG.md (1)
3-9: Extension RC changelog entry looks correct.Dependency bump to task-master-ai@0.27.1-rc.0 is documented.
.changeset/pre.json (1)
1-12: Pre-release config LGTM — referenced changeset present.Found .changeset/fluffy-clocks-cross.md.
apps/extension/package.json
Outdated
| "displayName": "TaskMaster", | ||
| "description": "A visual Kanban board interface for TaskMaster projects in VS Code", | ||
| "version": "0.25.1", | ||
| "version": "0.25.2-rc.0", |
There was a problem hiding this comment.
🧩 Analysis chain
Version bump to 0.25.2-rc.0 looks fine; verify publish manifest is aligned.
Ensure apps/extension/package.publish.json (used for Marketplace publishing) carries the same RC version.
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Locate and show extension publish manifest version (if present)
fd -a --strip-cwd-prefix 'package.publish.json' apps/extension | while read -r f; do
echo "File: $f"
rg -n '"version"\s*:\s*".*"' -n -C0 "$f" || true
doneLength of output: 173
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Checking apps/extension/package.json"
if [ -f apps/extension/package.json ]; then
rg -n '"version"\s*:\s*".*"' apps/extension/package.json || true
else
echo "apps/extension/package.json not found"
fi
echo
echo "Searching for package.publish.json under apps/extension"
if command -v fd >/dev/null 2>&1; then
files=$(fd -a 'package.publish.json' apps/extension || true)
else
files=$(find apps/extension -type f -name 'package.publish.json' 2>/dev/null || true)
fi
if [ -z "$files" ]; then
echo "No package.publish.json found under apps/extension"
else
echo "$files" | while read -r f; do
echo "File: $f"
rg -n '"version"\s*:\s*".*"' "$f" || true
done
fiLength of output: 207
Mismatch: update apps/extension/package.publish.json to 0.25.2-rc.0
apps/extension/package.json has "version": "0.25.2-rc.0" but apps/extension/package.publish.json contains "version": "0.23.1" — update apps/extension/package.publish.json (line 5) to "version": "0.25.2-rc.0".
🤖 Prompt for AI Agents
In apps/extension/package.publish.json around line 5, the "version" field is
"0.23.1" but apps/extension/package.json declares "0.25.2-rc.0"; update the
"version" value in package.publish.json to "0.25.2-rc.0" so both files match,
save the file and run any project/version-related validation (if present) to
ensure consistency.
apps/extension/package.json
Outdated
| "task-master-ai": "0.27.1-rc.0" | ||
| }, |
There was a problem hiding this comment.
Avoid pinning workspace dependency; prefer local workspace resolution.
In this monorepo, use "" (or workspace:) for local packages to ensure dev uses the workspace build. Pin the version in package.publish.json instead if you need a specific published RC for the Marketplace.
Apply this diff to the extension’s dev manifest:
"dependencies": {
- "task-master-ai": "0.27.1-rc.0"
+ "task-master-ai": "*"
},And keep the pinned RC in apps/extension/package.publish.json (not shown here) so the Marketplace package depends on the intended released version.
📝 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.
| "task-master-ai": "0.27.1-rc.0" | |
| }, | |
| "task-master-ai": "*" | |
| }, |
🤖 Prompt for AI Agents
In apps/extension/package.json around lines 243-244 the dependency
"task-master-ai" is pinned to "0.27.1-rc.0"; change the workspace resolution to
a local workspace reference (e.g., "*" or "workspace:*") so local development
uses the monorepo package, and move/keep the pinned RC version only in
apps/extension/package.publish.json for Marketplace publishing.
There was a problem hiding this comment.
@coderabbitai it doesn't matter since it gets automatically updated everytime there is a release, but in general, you're right :D
There was a problem hiding this comment.
@Crunchyman-ralph Thanks for clarifying! That makes perfect sense - if your release automation handles updating these dependencies automatically, then the pinned version is just a temporary state that gets managed by the process. I appreciate you sharing that context about how your workflow handles the version management. The general principle still applies for other monorepos without that automation, but your setup sounds like it handles this nicely! 😊
🧠 Learnings used
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#997
File: apps/extension/package.publish.json:2-8
Timestamp: 2025-07-31T20:49:04.638Z
Learning: In the eyaltoledano/claude-task-master repository, the VS Code extension uses a 3-file packaging system where package.json (with name "extension") is for development within the monorepo, while package.publish.json (with name "task-master-hamster") contains the clean manifest for VS Code marketplace publishing. The different names are intentional and serve distinct purposes in the build and publishing workflow.
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/package.json:13-64
Timestamp: 2025-09-03T12:16:15.866Z
Learning: For internal packages in the claude-task-master project, Crunchyman-ralph prefers pointing package.json "types" entries to src .ts files rather than dist .d.ts files for better developer experience (DX), as the packages are not being exported as SDKs.
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1090
File: apps/extension/package.json:241-243
Timestamp: 2025-08-07T13:00:22.966Z
Learning: In monorepos, local packages should use "*" as the version constraint in package.json dependencies, as recommended by npm. This ensures the local version from within the same workspace is always used, rather than attempting to resolve from external registries. This applies to packages like task-master-ai within the eyaltoledano/claude-task-master monorepo.
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: For CLI usage, install Taskmaster globally with `npm install -g task-master-ai` or use locally via `npx task-master-ai ...`.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: public/assets/AGENTS.md:0-0
Timestamp: 2025-09-22T16:42:54.285Z
Learning: Applies to public/assets/**/.mcp.json : Configure the Task Master MCP server in .mcp.json under mcpServers.task-master-ai with command npx and the listed env keys
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1211
File: jest.resolver.cjs:8-15
Timestamp: 2025-09-17T19:09:08.882Z
Learning: In the eyaltoledano/claude-task-master project, the team only uses .ts files and does not plan to use .tsx or .mts extensions, so Jest resolver and build tooling should focus on .js → .ts mapping only.
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1232
File: packages/tm-core/package.json:50-51
Timestamp: 2025-09-22T19:45:04.246Z
Learning: In the eyaltoledano/claude-task-master project, Crunchyman-ralph intentionally omits version fields from internal/private packages in package.json files to prevent changesets from releasing new versions of these packages while still allowing them to be processed for dependency updates. The changesets warnings about missing versions are acceptable as they don't break the process and achieve the desired behavior of only releasing public packages.
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1213
File: .github/workflows/pre-release.yml:68-73
Timestamp: 2025-09-17T20:26:17.257Z
Learning: User Crunchyman-ralph clarified that not all packages in the monorepo need build steps, so adding turbo:build scripts to every workspace package.json is unnecessary and incorrect.
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1232
File: packages/build-config/package.json:14-15
Timestamp: 2025-09-22T19:45:13.301Z
Learning: In the eyaltoledano/claude-task-master repository, Crunchyman-ralph intentionally omits version fields from internal packages (like tm/build-config) to prevent changesets from releasing new versions for these packages. This is the desired behavior for internal tooling packages that should not be published or versioned independently.
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.
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 (1)
apps/cli/src/utils/auto-update.ts (1)
38-60: compareVersions doesn’t implement full SemVer prerelease rules; can misorder e.g. alpha.10 vs alpha.2.Since this is now public API and used for update checks, implement SemVer 2.0 prerelease comparison (numeric vs string identifiers, dot-separated segments).
Replace the function with a spec-compliant comparison:
-export function compareVersions(v1: string, v2: string): number { - const toParts = (v: string) => { - const [core, pre = ''] = v.split('-', 2); - const nums = core.split('.').map((n) => Number.parseInt(n, 10) || 0); - return { nums, pre }; - }; - - const a = toParts(v1); - const b = toParts(v2); - const len = Math.max(a.nums.length, b.nums.length); - - // Compare numeric parts - for (let i = 0; i < len; i++) { - const d = (a.nums[i] || 0) - (b.nums[i] || 0); - if (d !== 0) return d < 0 ? -1 : 1; - } - - // Handle pre-release comparison - if (a.pre && !b.pre) return -1; // prerelease < release - if (!a.pre && b.pre) return 1; // release > prerelease - if (a.pre === b.pre) return 0; // same or both empty - return a.pre < b.pre ? -1 : 1; // basic prerelease tie-break -} +export function compareVersions(v1: string, v2: string): number { + const parse = (v: string) => { + const [core, pre = ''] = v.split('-', 2); + const nums = core.split('.').map((n) => Number.parseInt(n, 10) || 0); + const preIds = pre ? pre.split('.').filter(Boolean) : []; + return { nums, preIds }; + }; + + const a = parse(v1); + const b = parse(v2); + + // Compare core numeric parts (pad with zeros) + const len = Math.max(a.nums.length, b.nums.length); + for (let i = 0; i < len; i++) { + const d = (a.nums[i] || 0) - (b.nums[i] || 0); + if (d !== 0) return d < 0 ? -1 : 1; + } + + // Handle prerelease precedence + const aPre = a.preIds; + const bPre = b.preIds; + const aHasPre = aPre.length > 0; + const bHasPre = bPre.length > 0; + if (!aHasPre && !bHasPre) return 0; // both releases + if (!aHasPre && bHasPre) return 1; // release > prerelease + if (aHasPre && !bHasPre) return -1; // prerelease < release + + // Compare prerelease identifiers per SemVer 2.0.0 + const max = Math.max(aPre.length, bPre.length); + for (let i = 0; i < max; i++) { + const idA = aPre[i]; + const idB = bPre[i]; + if (idA === undefined) return -1; // shorter set has lower precedence + if (idB === undefined) return 1; + const aNum = /^\d+$/.test(idA); + const bNum = /^\d+$/.test(idB); + if (aNum && bNum) { + const diff = Number(idA) - Number(idB); + if (diff !== 0) return diff < 0 ? -1 : 1; + } else if (aNum && !bNum) { + return -1; // numeric < non-numeric + } else if (!aNum && bNum) { + return 1; // non-numeric > numeric + } else { + if (idA < idB) return -1; + if (idA > idB) return 1; + } + } + return 0; +}Consider adding unit tests for prerelease cases: 1.0.0-alpha < 1.0.0, 1.0.0-alpha.1 < 1.0.0-alpha.2, 1.0.0-alpha < 1.0.0-alpha.1, 1.0.0-alpha < 1.0.0-beta.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (3)
apps/cli/src/index.ts(1 hunks)apps/cli/src/utils/auto-update.ts(2 hunks)tests/unit/commands.test.js(2 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
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/commands.test.js
tests/unit/*.js
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Each module should have a corresponding unit test file in tests/unit/ that reflects the module structure (one test file per module).
Files:
tests/unit/commands.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/commands.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/commands.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/commands.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/commands.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/commands.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/commands.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/commands.test.js
🧠 Learnings (26)
📓 Common learnings
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.
📚 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 : Implement semantic version comparison and display attractive update notifications using boxen.
Applied to files:
apps/cli/src/index.tstests/unit/commands.test.jsapps/cli/src/utils/auto-update.ts
📚 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 : Integrate version checking in the CLI run function, starting the update check in the background and displaying notifications after command execution.
Applied to files:
apps/cli/src/index.ts
📚 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 : Implement version checking to notify users of available updates, use non-blocking version checks, and display update notifications after command completion.
Applied to files:
apps/cli/src/index.ts
📚 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/commands.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/commands.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/commands.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/commands.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 rely on environment variables for API keys in tests; set mock environment variables in test setup.
Applied to files:
tests/unit/commands.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/commands.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/commands.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Mock console output and verify correct formatting in UI function tests. Use flexible assertions like toContain() or toMatch() for formatted output.
Applied to files:
tests/unit/commands.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/commands.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/commands.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/commands.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/commands.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/commands.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/commands.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/commands.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/commands.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/commands.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Always mock tests properly based on the way the tested functions are defined and used.
Applied to files:
tests/unit/commands.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/commands.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/commands.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/commands.test.js
📚 Learning: 2025-09-22T19:45:04.246Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1232
File: packages/tm-core/package.json:50-51
Timestamp: 2025-09-22T19:45:04.246Z
Learning: In the eyaltoledano/claude-task-master project, Crunchyman-ralph intentionally omits version fields from internal/private packages in package.json files to prevent changesets from releasing new versions of these packages while still allowing them to be processed for dependency updates. The changesets warnings about missing versions are acceptable as they don't break the process and achieve the desired behavior of only releasing public packages.
Applied to files:
apps/cli/src/utils/auto-update.ts
🧬 Code graph analysis (2)
tests/unit/commands.test.js (1)
index.js (4)
packageJson(37-37)program(68-68)version(64-64)version(64-64)
apps/cli/src/utils/auto-update.ts (1)
apps/cli/src/index.ts (1)
compareVersions(22-22)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: setup
- GitHub Check: Typecheck
- GitHub Check: Build
🔇 Additional comments (4)
apps/cli/src/utils/auto-update.ts (1)
18-18: Doc update aligns with new version source. LGTM.apps/cli/src/index.ts (1)
21-23: Re-exporting compareVersions is correct and helpful for tests/API.Public surface change looks good.
tests/unit/commands.test.js (2)
99-99: Good: use compareVersions from the public API.This aligns tests with the new export.
141-153: Prefer setting env to undefined over delete for consistency with your own pattern.Keeps env shape stable and mirrors your cleanup test below.
- delete process.env.TM_PUBLIC_VERSION; + process.env.TM_PUBLIC_VERSION = undefined;⛔ Skipped due to learnings
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.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 rely on environment variables for API keys in tests; set mock environment variables in test setup.
| // Version is injected at build time via TM_PUBLIC_VERSION | ||
| const version = process.env.TM_PUBLIC_VERSION; | ||
| if (version && version !== 'unknown') { | ||
| return version; | ||
| } | ||
|
|
||
| // Fallback for development or if injection failed | ||
| console.warn('Could not read version from TM_PUBLIC_VERSION, using fallback'); | ||
| return '0.0.0'; |
There was a problem hiding this comment.
🧹 Nitpick
Avoid noisy warnings in normal/dev runs.
Gate or downgrade this warning to reduce log noise (especially in CI). Suggest using console.debug or guarding by CI flag.
Apply this minimal change:
- console.warn('Could not read version from TM_PUBLIC_VERSION, using fallback');
+ if (!process.env.CI) {
+ console.debug('Could not read version from TM_PUBLIC_VERSION, using fallback');
+ }📝 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.
| // Version is injected at build time via TM_PUBLIC_VERSION | |
| const version = process.env.TM_PUBLIC_VERSION; | |
| if (version && version !== 'unknown') { | |
| return version; | |
| } | |
| // Fallback for development or if injection failed | |
| console.warn('Could not read version from TM_PUBLIC_VERSION, using fallback'); | |
| return '0.0.0'; | |
| // Version is injected at build time via TM_PUBLIC_VERSION | |
| const version = process.env.TM_PUBLIC_VERSION; | |
| if (version && version !== 'unknown') { | |
| return version; | |
| } | |
| // Fallback for development or if injection failed | |
| if (!process.env.CI) { | |
| console.debug('Could not read version from TM_PUBLIC_VERSION, using fallback'); | |
| } | |
| return '0.0.0'; |
🤖 Prompt for AI Agents
In apps/cli/src/utils/auto-update.ts around lines 21 to 29, the current
unconditional console.warn when TM_PUBLIC_VERSION isn't found is noisy; replace
that warn with a lower-visibility log (use console.debug) or wrap the
console.warn in a CI guard (e.g., only call console.warn if process.env.CI ===
'true') so normal/dev runs and CI noise are reduced while preserving visibility
in CI if desired.
| test('should return version that matches package.json when TM_PUBLIC_VERSION is set', () => { | ||
| // Read actual version from package.json | ||
| const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8')); | ||
| const expectedVersion = packageJson.version; | ||
|
|
||
| const program = setupCLI(); | ||
| const version = program._version(); | ||
| expect(mockReadFileSync).toHaveBeenCalledWith('package.json', 'utf8'); | ||
| expect(version).toBe('1.0.0'); | ||
| }); | ||
|
|
||
| test('should use default version when package.json is not available', () => { | ||
| mockExistsSync.mockReturnValue(false); | ||
| // Set environment variable to match package.json | ||
| const originalEnv = process.env.TM_PUBLIC_VERSION; | ||
| process.env.TM_PUBLIC_VERSION = expectedVersion; | ||
|
|
||
| const program = setupCLI(); | ||
| const version = program._version(); | ||
| expect(mockReadFileSync).not.toHaveBeenCalled(); | ||
| expect(version).toBe('unknown'); | ||
| const version = program.version(); | ||
| expect(version).toBe(expectedVersion); | ||
|
|
||
| // Restore original environment | ||
| if (originalEnv !== undefined) { | ||
| process.env.TM_PUBLIC_VERSION = originalEnv; | ||
| } else { | ||
| delete process.env.TM_PUBLIC_VERSION; | ||
| } |
There was a problem hiding this comment.
Test will fail: fs.readFileSync is mocked and returns undefined.
You mock fs at file top, so JSON.parse(fs.readFileSync(...)) throws. Also, version is now sourced from TM_PUBLIC_VERSION, not package.json—don’t read real files in unit tests.
Apply this diff to decouple from fs and fix the mock conflict:
- test('should return version that matches package.json when TM_PUBLIC_VERSION is set', () => {
- // Read actual version from package.json
- const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
- const expectedVersion = packageJson.version;
-
- // Set environment variable to match package.json
- const originalEnv = process.env.TM_PUBLIC_VERSION;
- process.env.TM_PUBLIC_VERSION = expectedVersion;
+ test('should use TM_PUBLIC_VERSION when set', () => {
+ // Use a controlled version value; avoid real filesystem access
+ const expectedVersion = '9.9.9-test';
+ const originalEnv = process.env.TM_PUBLIC_VERSION;
+ process.env.TM_PUBLIC_VERSION = expectedVersion;
const program = setupCLI();
const version = program.version();
expect(version).toBe(expectedVersion);
// Restore original environment
if (originalEnv !== undefined) {
process.env.TM_PUBLIC_VERSION = originalEnv;
} else {
delete process.env.TM_PUBLIC_VERSION;
}
});📝 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.
| test('should return version that matches package.json when TM_PUBLIC_VERSION is set', () => { | |
| // Read actual version from package.json | |
| const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8')); | |
| const expectedVersion = packageJson.version; | |
| const program = setupCLI(); | |
| const version = program._version(); | |
| expect(mockReadFileSync).toHaveBeenCalledWith('package.json', 'utf8'); | |
| expect(version).toBe('1.0.0'); | |
| }); | |
| test('should use default version when package.json is not available', () => { | |
| mockExistsSync.mockReturnValue(false); | |
| // Set environment variable to match package.json | |
| const originalEnv = process.env.TM_PUBLIC_VERSION; | |
| process.env.TM_PUBLIC_VERSION = expectedVersion; | |
| const program = setupCLI(); | |
| const version = program._version(); | |
| expect(mockReadFileSync).not.toHaveBeenCalled(); | |
| expect(version).toBe('unknown'); | |
| const version = program.version(); | |
| expect(version).toBe(expectedVersion); | |
| // Restore original environment | |
| if (originalEnv !== undefined) { | |
| process.env.TM_PUBLIC_VERSION = originalEnv; | |
| } else { | |
| delete process.env.TM_PUBLIC_VERSION; | |
| } | |
| test('should use TM_PUBLIC_VERSION when set', () => { | |
| // Use a controlled version value; avoid real filesystem access | |
| const expectedVersion = '9.9.9-test'; | |
| const originalEnv = process.env.TM_PUBLIC_VERSION; | |
| process.env.TM_PUBLIC_VERSION = expectedVersion; | |
| const program = setupCLI(); | |
| const version = program.version(); | |
| expect(version).toBe(expectedVersion); | |
| // Restore original environment | |
| if (originalEnv !== undefined) { | |
| process.env.TM_PUBLIC_VERSION = originalEnv; | |
| } else { | |
| delete process.env.TM_PUBLIC_VERSION; | |
| } | |
| }); |
🤖 Prompt for AI Agents
In tests/unit/commands.test.js around lines 120-138, the test reads package.json
via fs.readFileSync but fs is mocked so JSON.parse(fs.readFileSync(...)) throws
and is unnecessary because version is sourced from TM_PUBLIC_VERSION; change the
test to avoid reading the filesystem — set expectedVersion to a hard-coded
string (or load a mocked package.json via the test setup/mocks), assign that to
process.env.TM_PUBLIC_VERSION, call setupCLI().version(), assert it equals
expectedVersion, and keep the existing environment restore logic; do not call
fs.readFileSync in this unit test.
There was a problem hiding this comment.
Actionable comments posted: 3
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (3)
tests/integration/profiles/roo-files-inclusion.test.js(1 hunks)tests/integration/profiles/rules-files-inclusion.test.js(2 hunks)tsdown.config.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
tests/{unit,integration,e2e,fixtures}/**/*.js
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Test files must be organized as follows: unit tests in tests/unit/, integration tests in tests/integration/, end-to-end tests in tests/e2e/, and test fixtures in tests/fixtures/.
Files:
tests/integration/profiles/rules-files-inclusion.test.jstests/integration/profiles/roo-files-inclusion.test.js
**/*.{test,spec}.{js,ts,jsx,tsx}
📄 CodeRabbit inference engine (.cursor/rules/git_workflow.mdc)
**/*.{test,spec}.{js,ts,jsx,tsx}: Create a test file and ensure all tests pass when all subtasks are complete; commit tests if added or modified
When all subtasks are complete, run final testing using the appropriate test runner (e.g., npm test, jest, or manual testing)
Files:
tests/integration/profiles/rules-files-inclusion.test.jstests/integration/profiles/roo-files-inclusion.test.js
**/*.test.js
📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)
**/*.test.js: Never use asynchronous operations in tests. Make all mocks return synchronous values when possible.
Always mock tests properly based on the way the tested functions are defined and used.
Follow the test file organization: mocks must be set up before importing modules under test, and spies on mocked modules should be set up after imports.
Use fixtures from tests/fixtures/ for consistent sample data across tests.
Always declare mocks before importing the modules being tested in Jest test files.
Use jest.spyOn() after imports to create spies on mock functions and reference these spies in test assertions.
When testing functions with callbacks, get the callback from your mock's call arguments, execute it directly with test inputs, and verify the results.
For ES modules, use jest.mock() before static imports and jest.unstable_mockModule() before dynamic imports to mock dependencies.
Reset mock functions (mockFn.mockReset()) before dynamic imports if they might have been called previously.
When verifying console assertions, assert against the actual arguments passed (single formatted string), not multiple arguments.
Use mock-fs to mock file system operations in tests, and restore the file system after each test.
Mock API calls (e.g., Anthropic/Claude) by mocking the entire module and providing predictable responses.
Set mock environment variables in test setup and restore them after each test.
Maintain test fixtures separate from test logic.
Follow the mock-first-then-import pattern for all Jest mocks.
Do not define mock variables before jest.mock() calls (they won't be accessible due to hoisting).
Use test-specific file paths (e.g., 'test-tasks.json') for all file operations in tests.
Mock readJSON and writeJSON to avoid real file system interactions in tests.
Verify file operations use the correct paths in expect statements.
Use different file paths for each test to avoid test interdependence.
Verify modifications on the in-memory task objects passed to w...
Files:
tests/integration/profiles/rules-files-inclusion.test.jstests/integration/profiles/roo-files-inclusion.test.js
tests/integration/**/*.test.js
📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)
Integration tests must be located in tests/integration/, test interactions between modules, and focus on component interfaces rather than implementation details.
Files:
tests/integration/profiles/rules-files-inclusion.test.jstests/integration/profiles/roo-files-inclusion.test.js
tests/{unit,integration,e2e}/**/*.test.js
📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)
tests/{unit,integration,e2e}/**/*.test.js: When testing CLI commands built with Commander.js, test the command action handlers directly rather than trying to mock the entire Commander.js chain.
When mocking the Commander.js chain, mock ALL chainable methods (option, argument, action, on, etc.) and return this (or the mock object) from all chainable method mocks.
Explicitly handle all options, including defaults and shorthand flags (e.g., -p for --prompt), and include null/undefined checks in test implementations for parameters that might be optional.
Do not try to use the real action implementation without proper mocking, and do not mock Commander partially—either mock it completely or test the action directly.
Mock the action handlers for CLI commands and verify they're called with correct arguments.
Use sample task fixtures for consistent test data, mock file system operations, and test both success and error paths for task operations.
Mock console output and verify correct formatting in UI function tests. Use flexible assertions like toContain() or toMatch() for formatted output.
Mock chalk functions to return the input text to make testing easier while still verifying correct function calls.
Files:
tests/integration/profiles/rules-files-inclusion.test.jstests/integration/profiles/roo-files-inclusion.test.js
tests/{integration,e2e}/**/*.test.js
📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)
Properly mock session objects when required by functions, and reset environment variables between tests if modified.
Files:
tests/integration/profiles/rules-files-inclusion.test.jstests/integration/profiles/roo-files-inclusion.test.js
**/*.js
📄 CodeRabbit inference engine (.cursor/rules/tests.mdc)
**/*.js: Declare and initialize global variables at the top of modules to avoid hoisting issues.
Use proper function declarations to avoid hoisting issues and initialize variables before they are referenced.
Do not reference variables before their declaration in module scope.
Use dynamic imports (import()) to avoid initialization order issues in modules.
Files:
tests/integration/profiles/rules-files-inclusion.test.jstests/integration/profiles/roo-files-inclusion.test.js
**/*.{test,spec}.*
📄 CodeRabbit inference engine (.cursor/rules/test_workflow.mdc)
Test files should follow naming conventions: .test., .spec., or _test. depending on the language
Files:
tests/integration/profiles/rules-files-inclusion.test.jstests/integration/profiles/roo-files-inclusion.test.js
tests/{unit,integration,e2e}/**
📄 CodeRabbit inference engine (.cursor/rules/test_workflow.mdc)
Organize test directories by test type (unit, integration, e2e) and mirror source structure where possible
Files:
tests/integration/profiles/rules-files-inclusion.test.jstests/integration/profiles/roo-files-inclusion.test.js
🧠 Learnings (19)
📓 Common learnings
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.
📚 Learning: 2025-09-22T16:42:10.070Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: public/assets/.windsurfrules:0-0
Timestamp: 2025-09-22T16:42:10.070Z
Learning: Applies to public/assets/**/.windsurfrules : Maintain rules: update for new patterns, add examples from codebase, remove outdated patterns, and cross-reference related rules
Applied to files:
tests/integration/profiles/rules-files-inclusion.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/integration/profiles/rules-files-inclusion.test.jstests/integration/profiles/roo-files-inclusion.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/integration/profiles/rules-files-inclusion.test.jstests/integration/profiles/roo-files-inclusion.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 tests/{unit,integration,e2e,fixtures}/**/*.js : 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/.
Applied to files:
tests/integration/profiles/rules-files-inclusion.test.jstests/integration/profiles/roo-files-inclusion.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/integration/profiles/rules-files-inclusion.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/integration/profiles/rules-files-inclusion.test.jstests/integration/profiles/roo-files-inclusion.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/integration/profiles/rules-files-inclusion.test.jstests/integration/profiles/roo-files-inclusion.test.js
📚 Learning: 2025-09-22T16:42:10.070Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: public/assets/.windsurfrules:0-0
Timestamp: 2025-09-22T16:42:10.070Z
Learning: Applies to public/assets/**/.windsurfrules : When updating SELF_IMPROVE items, follow WINDSURF_RULES formatting and structure within .windsurfrules
Applied to files:
tests/integration/profiles/rules-files-inclusion.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/integration/profiles/rules-files-inclusion.test.js
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Applies to **/__tests__/**/*.ts : In JavaScript/TypeScript projects using Jest, test files should be located in __tests__ directories or match *.test.ts and *.spec.ts patterns
Applied to files:
tests/integration/profiles/rules-files-inclusion.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/integration/profiles/rules-files-inclusion.test.jstests/integration/profiles/roo-files-inclusion.test.js
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Applies to tests/{unit,integration,e2e}/** : Organize test directories by test type (unit, integration, e2e) and mirror source structure where possible
Applied to files:
tests/integration/profiles/rules-files-inclusion.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 tests/unit/*.js : Each module should have a corresponding unit test file in tests/unit/ that reflects the module structure (one test file per module).
Applied to files:
tests/integration/profiles/rules-files-inclusion.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Mock console output and verify correct formatting in UI function tests. Use flexible assertions like toContain() or toMatch() for formatted output.
Applied to files:
tests/integration/profiles/rules-files-inclusion.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/fixtures/**/* : Test fixtures must be located in tests/fixtures/, provide reusable test data, and be exported as named exports for reuse.
Applied to files:
tests/integration/profiles/rules-files-inclusion.test.js
📚 Learning: 2025-09-22T16:42:54.285Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: public/assets/AGENTS.md:0-0
Timestamp: 2025-09-22T16:42:54.285Z
Learning: Applies to public/assets/**/.mcp.json : Configure the Task Master MCP server in .mcp.json under mcpServers.task-master-ai with command npx and the listed env keys
Applied to files:
tsdown.config.ts
📚 Learning: 2025-08-12T01:22:48.873Z
Learnt from: olssonsten
PR: eyaltoledano/claude-task-master#1112
File: src/profiles/roo.js:0-0
Timestamp: 2025-08-12T01:22:48.873Z
Learning: In src/profiles/roo.js, the enhanceRooMCPConfiguration function was simplified to only set server.timeout = 300, removing problematic overwrites of server.env and alwaysAllow configurations that could interfere with user settings.
Applied to files:
tests/integration/profiles/roo-files-inclusion.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/integration/profiles/roo-files-inclusion.test.js
🧬 Code graph analysis (2)
tests/integration/profiles/rules-files-inclusion.test.js (2)
src/utils/profiles.js (1)
rulesDir(48-48)mcp-server/src/core/direct-functions/rules.js (1)
rulesDir(135-135)
tsdown.config.ts (1)
index.js (1)
packageJson(37-37)
🪛 GitHub Actions: CI
tests/integration/profiles/rules-files-inclusion.test.js
[error] 90-99: Biome format check failed. The formatter would have printed different content. Run 'biome format .' to fix code style issues.
tests/integration/profiles/roo-files-inclusion.test.js
[error] 104-114: Biome format check failed. The formatter would have printed different content. Run 'biome format .' to fix code style issues.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build
- GitHub Check: typecheck
🔇 Additional comments (4)
tests/integration/profiles/roo-files-inclusion.test.js (1)
103-115: Path update to assets/roocode verified — .roo and .roomodes presentBoth assets/roocode/.roo and assets/roocode/.roomodes exist on the PR branch; the test can remain as-is.
tests/integration/profiles/rules-files-inclusion.test.js (2)
19-22: Approve: assets/rules path and files verifiedVerified: assets/rules contains dev_workflow.mdc, taskmaster.mdc, self_improve.mdc, cursor_rules.mdc.
89-101: Roo assets path assertions mirror the Roo test — verified
assets/roocode/.roo and assets/roocode/.roomodes exist (OK). Consistent with the assets/roocode switch; keep in sync with roo-files-inclusion.test.js.tsdown.config.ts (1)
38-38: assets dir exists and is populated — no action requiredFound ./assets (contains config.json, AGENTS.md, scripts_README.md, rules/, kiro-hooks/, roocode/, etc.); copy: ['assets'] should succeed. Also present: ./apps/extension/assets (banner.png, icons) — add it to the copy list only if you intend to include those files.
| // Inject package.json version at build time | ||
| try { | ||
| const packageJson = JSON.parse( | ||
| require('fs').readFileSync('package.json', 'utf8') | ||
| ); | ||
| envs['TM_PUBLIC_VERSION'] = packageJson.version || 'unknown'; | ||
| } catch (error) { | ||
| console.warn('Could not read package.json version during build:', error); | ||
| envs['TM_PUBLIC_VERSION'] = 'unknown'; | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
Avoid require in ESM config; use fs import to prevent “require is not defined” at build time.
This config uses ESM import syntax; calling require('fs') here can break CI in ESM loaders. Read via fs import instead.
Apply this diff within this hunk:
- const packageJson = JSON.parse(
- require('fs').readFileSync('package.json', 'utf8')
- );
+ const packageJson = JSON.parse(
+ readFileSync('package.json', 'utf8')
+ );Add this import at the top of the file (outside this hunk):
import { readFileSync } from 'fs';Also verify no runtime reads of package.json remain (the new source of truth is TM_PUBLIC_VERSION). Run:
🏁 Script executed:
#!/bin/bash
# Find runtime package.json imports/requires
rg -nP -C2 --type=js --type=ts '(require\s*\([\'"][./\w-]*package\.json[\'"]\)|from\s+[\'"][./\w-]*package\.json[\'"])'Length of output: 206
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "---- Show tsdown.config.ts (if present) ----"
if [ -f tsdown.config.ts ]; then
sed -n '1,240p' tsdown.config.ts || true
else
echo "tsdown.config.ts not found at repo root; searching for file..."
rg -n --hidden --no-ignore -S "tsdown.config.ts" || true
fi
echo
echo "---- Search for package.json reads in .js/.ts files ----"
rg -nP -C2 --type=js --type=ts -g '!node_modules' \
-e "require\\s*\\(\\s*['\"][^'\"]*package\\.json['\"]\\)" \
-e "from\\s+['\"][^'\"]*package\\.json['\"]" \
-e "readFileSync\\s*\\(\\s*['\"][^'\"]*package\\.json['\"]\\)" \
-e "promises\\.readFile\\s*\\(\\s*['\"][^'\"]*package\\.json['\"]\\)" || echo "No matches found"Length of output: 1508
Replace require('fs') with an ESM import and use readFileSync in tsdown.config.ts
tsdown.config.ts currently calls require('fs').readFileSync — this will break under ESM loaders. Replace the snippet and add an import:
- const packageJson = JSON.parse(
- require('fs').readFileSync('package.json', 'utf8')
- );
+ const packageJson = JSON.parse(
+ readFileSync('package.json', 'utf8')
+ );Add at the top of the file:
import { readFileSync } from 'fs';Sandbox ripgrep did not reliably scan the repo for other package.json reads; run a local search to confirm no runtime package.json imports/requires remain, e.g.:
rg -n --hidden -S 'package\.json' --glob '!node_modules'🤖 Prompt for AI Agents
In tsdown.config.ts around lines 11 to 20, replace the dynamic CommonJS
require('fs').readFileSync usage with an ESM import and direct call: add an
import for readFileSync from 'fs' at the top of the file and use that
readFileSync(...) call where package.json is read; update the try/catch to use
the imported function and remove the require call. After making the change, run
a local repo search (e.g., ripgrep command suggested) to ensure no remaining
runtime package.json require/imports exist outside node_modules.
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.changeset/soft-dingos-grow.md (1)
1-6: Ignore MD041 for changeset files to avoid false positives.Changeset files intentionally start with front‑matter, not an H1.
Add this to .markdownlintignore:
.changeset/*.md
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
.changeset/soft-dingos-grow.md(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
.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/soft-dingos-grow.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/soft-dingos-grow.md
🧠 Learnings (1)
📓 Common learnings
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.
🪛 markdownlint-cli2 (0.18.1)
.changeset/soft-dingos-grow.md
5-5: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: build
- GitHub Check: Test
🔇 Additional comments (1)
.changeset/soft-dingos-grow.md (1)
1-4: Target package verified — "task-master-ai" exists in repo root package.jsonFound "task-master-ai" in package.json at the repository root (/package.json); the changeset target is correct.
| "task-master-ai": patch | ||
| --- | ||
|
|
||
| One last testing final final |
There was a problem hiding this comment.
🛠️ Refactor suggestion
❓ Verification inconclusive
Replace placeholder with a user‑facing, imperative summary.
Current text isn’t user‑facing and violates our changeset guidance.
Apply:
-One last testing final final
+Fix CLI version resolution via TM_PUBLIC_VERSION and expose compareVersions and resolveComplexityReportPath.If these user‑visible changes don’t apply to task-master-ai, replace with a single concise line that reflects what users of this package actually get.
Replace placeholder in .changeset/soft-dingos-grow.md with a user-facing, imperative changeset summary.
Current text isn’t user‑facing and violates changeset guidance.
Apply:
-One last testing final final
+Fix CLI version resolution via TM_PUBLIC_VERSION and expose compareVersions and resolveComplexityReportPath.If these user‑visible changes don’t apply to task-master-ai, replace with a single concise line that reflects what users of this package actually get.
📝 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.
| One last testing final final | |
| Fix CLI version resolution via TM_PUBLIC_VERSION and expose compareVersions and resolveComplexityReportPath. |
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)
5-5: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
🤖 Prompt for AI Agents
.changeset/soft-dingos-grow.md around line 5: the file currently contains a
placeholder line "One last testing final final" which is not a user-facing,
imperative changeset summary; replace that placeholder with a short, imperative
sentence describing the user-facing change (e.g., "Fix X to do Y" or "Add
support for Z"), written in present-tense imperative form and reflecting what
consumers of task-master-ai will observe; if no user-visible changes apply,
replace it with a single concise line stating that (for example, "No user-facing
changes") so the changeset follows guidance and is clear to release notes
consumers.
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
.changeset/pre.json(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
.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/pre.json
🧠 Learnings (3)
📓 Common learnings
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.
📚 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 .changeset/* : Create appropriate changesets for new features, use semantic versioning, include tagged system information in release notes, and document breaking changes if any.
Applied to files:
.changeset/pre.json
📚 Learning: 2025-09-22T19:45:04.246Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1232
File: packages/tm-core/package.json:50-51
Timestamp: 2025-09-22T19:45:04.246Z
Learning: In the eyaltoledano/claude-task-master project, Crunchyman-ralph intentionally omits version fields from internal/private packages in package.json files to prevent changesets from releasing new versions of these packages while still allowing them to be processed for dependency updates. The changesets warnings about missing versions are acceptable as they don't break the process and achieve the desired behavior of only releasing public packages.
Applied to files:
.changeset/pre.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: Test
- GitHub Check: build
- GitHub Check: typecheck
🔇 Additional comments (2)
.changeset/pre.json (2)
1-12: Pre-release config looks valid.Structure matches Changesets pre mode; using tag "rc" is fine.
9-11: Referenced changeset exists — no action required.
The changeset "fluffy-clocks-cross" exists at .changeset/fluffy-clocks-cross.md.
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 (6)
src/profiles/zed.js (1)
133-157: Always inject "source": "custom" even when settings.json is already in Zed formatEarly return on Line 139 skips adding the required source field when context_servers already exists, leaving configs non-compliant. Convert-or-not, we should ensure the field is present before writing back.
Apply this diff to handle both cases and guard against non-object entries:
- // Check if it's already in Zed format (has context_servers) - if (mcpConfig['context_servers']) { - log( - 'info', - '[Zed] settings.json already in Zed format, skipping transformation' - ); - return; - } - - // Transform to Zed format - const zedConfig = transformToZedFormat(mcpConfig); + // Produce a Zed-shaped object in both cases + let zedConfig; + if (mcpConfig['context_servers']) { + log('info', '[Zed] settings.json already in Zed format'); + zedConfig = mcpConfig; + } else { + // Transform to Zed format + zedConfig = transformToZedFormat(mcpConfig); + } - // Add "source": "custom" to task-master-ai server for Zed - if ( - zedConfig['context_servers'] && - zedConfig['context_servers']['task-master-ai'] - ) { - zedConfig['context_servers']['task-master-ai'].source = 'custom'; - } + // Add/ensure "source": "custom" on task-master-ai + if ( + zedConfig['context_servers'] && + zedConfig['context_servers']['task-master-ai'] + ) { + const server = zedConfig['context_servers']['task-master-ai']; + if (server && typeof server === 'object' && server.source !== 'custom') { + server.source = 'custom'; + } + }.changeset/loose-poems-tickle.md (1)
5-8: Make the changeset a single user‑facing summary line and exclude .changeset from markdownlint
- Update .changeset/loose-poems-tickle.md to a single plain summary line (no bullets or H1): Fix Zed MCP configuration by adding required "source" property.
- Add ".changeset/**" to markdownlint ignore (update coderabbit.markdownlint-cli2.jsonc or add .markdownlintignore) so MD041 is not applied to changeset files.
scripts/init.js (4)
59-63: Invalid TASKMASTER_LOG_LEVEL values silence all logs; add a safe fallback.If the env var is set to an unknown value,
LOG_LEVELbecomesundefined, and no logs emit. Default toinfofor unknown values.Apply this diff:
-// Determine log level from environment variable or default to 'info' -const LOG_LEVEL = process.env.TASKMASTER_LOG_LEVEL - ? LOG_LEVELS[process.env.TASKMASTER_LOG_LEVEL.toLowerCase()] - : LOG_LEVELS.info; // Default to info +// Determine log level from environment variable or default to 'info' +const rawLogLevel = process.env.TASKMASTER_LOG_LEVEL?.toLowerCase(); +const LOG_LEVEL = + rawLogLevel && Object.prototype.hasOwnProperty.call(LOG_LEVELS, rawLogLevel) + ? LOG_LEVELS[rawLogLevel] + : LOG_LEVELS.info; // Default to info
415-415: ReferenceError risk: rl is block-scoped inside try but used in catch.
rlis declared withconstinsidetryand referenced incatch, which will throw if an error occurs before declaration. Hoistrlto the outer scope.Apply this diff:
- try { - const rl = readline.createInterface({ + let rl; + try { + rl = readline.createInterface({ input: process.stdin, output: process.stdout }); @@ - } catch (error) { - if (rl) { - rl.close(); - } + } catch (error) { + if (rl) { + rl.close(); + } log('error', `Error during initialization process: ${error.message}`); process.exit(1); }Also applies to: 416-421, 535-537
684-699: Dependencies are never installed; add the missing npm install call.You show an “Installing dependencies…” message and prepare options, but there’s no
execSync('npm install', ...).Apply this diff:
if (isSilentMode()) { // If silent (MCP mode), suppress npm install output npmInstallOptions.stdio = 'ignore'; log('info', 'Running npm install silently...'); // Log our own message } else { // Interactive mode, show the boxen message console.log( boxen(chalk.cyan('Installing dependencies...'), { padding: 0.5, margin: 0.5, borderStyle: 'round', borderColor: 'blue' }) ); } + // Perform installation (skip in dry run) + if (!dryRun) { + try { + execSync('npm install', npmInstallOptions); + log('success', 'Dependencies installed'); + } catch (error) { + log('warn', `Dependency installation failed: ${error.message}`); + log('warn', 'You can run "npm install" manually.'); + } + } else { + log('info', 'DRY RUN: Skipping dependency installation.'); + }
617-624: Add asset existence guard and ensure .gitignore is published
- Guard readAsset with assetExists('gitignore') (log a warning and skip) before calling readAsset in scripts/init.js (around line ~617). assetExists/readAsset are available in src/utils/asset-resolver.js.
- Repo has assets/gitignore, but repo root package.json 'files' does not include assets (currently: dist/**, README-task-master.md, README.md, LICENSE). Ensure the asset is shipped — add 'assets' to package.json "files" or copy the asset into dist and include it in the published files.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (7)
.changeset/loose-poems-tickle.md(1 hunks).changeset/pre.json(1 hunks)scripts/init.js(1 hunks)scripts/modules/commands.js(3 hunks)src/profiles/zed.js(1 hunks)src/utils/path-utils.js(1 hunks)tests/unit/commands.test.js(2 hunks)
🧰 Additional context used
📓 Path-based instructions (16)
.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/pre.json.changeset/loose-poems-tickle.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.jsscripts/init.jstests/unit/commands.test.jssrc/utils/path-utils.jssrc/profiles/zed.js
.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/loose-poems-tickle.md
tests/{unit,integration,e2e,fixtures}/**/*.js
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Test files must be organized as follows: unit tests in tests/unit/, integration tests in tests/integration/, end-to-end tests in tests/e2e/, and test fixtures in tests/fixtures/.
Files:
tests/unit/commands.test.js
tests/unit/*.js
📄 CodeRabbit inference engine (.cursor/rules/architecture.mdc)
Each module should have a corresponding unit test file in tests/unit/ that reflects the module structure (one test file per module).
Files:
tests/unit/commands.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/commands.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/commands.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/commands.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/commands.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/commands.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/commands.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/path-utils.js
🧠 Learnings (50)
📓 Common learnings
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.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: public/assets/.windsurfrules:0-0
Timestamp: 2025-09-22T16:42:10.070Z
Learning: Use the task-master CLI as the primary interface instead of node scripts/dev.js; install globally with npm -g or use npx; all commands accept the same options and include additional commands like init
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.
📚 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 .changeset/* : Create appropriate changesets for new features, use semantic versioning, include tagged system information in release notes, and document breaking changes if any.
Applied to files:
.changeset/pre.json
📚 Learning: 2025-09-22T19:45:04.246Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1232
File: packages/tm-core/package.json:50-51
Timestamp: 2025-09-22T19:45:04.246Z
Learning: In the eyaltoledano/claude-task-master project, Crunchyman-ralph intentionally omits version fields from internal/private packages in package.json files to prevent changesets from releasing new versions of these packages while still allowing them to be processed for dependency updates. The changesets warnings about missing versions are acceptable as they don't break the process and achieve the desired behavior of only releasing public packages.
Applied to files:
.changeset/pre.json
📚 Learning: 2025-09-22T19:45:13.301Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1232
File: packages/build-config/package.json:14-15
Timestamp: 2025-09-22T19:45:13.301Z
Learning: In the eyaltoledano/claude-task-master repository, Crunchyman-ralph intentionally omits version fields from internal packages (like tm/build-config) to prevent changesets from releasing new versions for these packages. This is the desired behavior for internal tooling packages that should not be published or versioned independently.
Applied to files:
.changeset/pre.json
📚 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/commands.js : 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.
Applied to files:
scripts/modules/commands.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/commands.js : Use consistent patterns for option naming and help text in CLI 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 : Follow the provided command template structure for all CLI commands using Commander.js, including descriptive command names, option definitions, and async action handlers.
Applied to files:
scripts/modules/commands.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/commands.js : Follow the Commander.js model for subcommand structure in CLI commands.
Applied to files:
scripts/modules/commands.js
📚 Learning: 2025-07-18T17:10:53.657Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/glossary.mdc:0-0
Timestamp: 2025-07-18T17:10:53.657Z
Learning: Guidelines for implementing CLI commands using Commander.js (commands.mdc).
Applied to files:
scripts/modules/commands.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 : Follow the provided command template structure for all CLI commands using Commander.js, including use of .command(), .description(), .option(), and .action() methods.
Applied to files:
scripts/modules/commands.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 : Export the registerCommands function and keep the CLI setup code clean and maintainable.
Applied to files:
scripts/modules/commands.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:
scripts/modules/commands.jstests/unit/commands.test.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 : Integrate version checking in the CLI run function, starting the update check in the background and displaying notifications after command execution.
Applied to files:
scripts/modules/commands.js
📚 Learning: 2025-09-03T12:15:03.208Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: apps/cli/src/commands/auth.command.ts:222-224
Timestamp: 2025-09-03T12:15:03.208Z
Learning: The CLI can be invoked using both "task-master" and "tm" as aliases - both forms are valid and acceptable in help text, documentation, and examples.
Applied to files:
scripts/modules/commands.js
📚 Learning: 2025-09-22T16:42:10.070Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: public/assets/.windsurfrules:0-0
Timestamp: 2025-09-22T16:42:10.070Z
Learning: Use the task-master CLI as the primary interface instead of node scripts/dev.js; install globally with npm -g or use npx; all commands accept the same options and include additional commands like init
Applied to files:
scripts/modules/commands.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: For CLI usage, install Taskmaster globally with `npm install -g task-master-ai` or use locally via `npx task-master-ai ...`.
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 : Follow established naming conventions for task files, such as task_001.txt.
Applied to files:
scripts/modules/commands.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:
scripts/modules/commands.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 : The default tag 'master' must be used for all existing and new tasks unless otherwise specified.
Applied to files:
scripts/modules/commands.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: Use the Taskmaster command set (`task-master` CLI or MCP tools) for all task management operations: listing, expanding, updating, tagging, and status changes.
Applied to files:
scripts/modules/commands.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 : When implementing project initialization commands, support both CLI and MCP, support non-interactive modes with sensible defaults, handle project metadata, and create necessary files and directories.
Applied to files:
scripts/modules/commands.js
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/task-manager/*.js : Do not import or call anything from the old `ai-services.js`, `ai-client-factory.js`, or `ai-client-utils.js` files.
Applied to files:
scripts/init.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:
scripts/init.js
📚 Learning: 2025-07-17T21:33:57.585Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1002
File: .changeset/puny-friends-give.md:2-3
Timestamp: 2025-07-17T21:33:57.585Z
Learning: In the eyaltoledano/claude-task-master repository, the MCP server code in mcp-server/src/ is part of the main "task-master-ai" package, not a separate "mcp-server" package. When creating changesets for MCP server changes, use "task-master-ai" as the package name.
Applied to files:
.changeset/loose-poems-tickle.md
📚 Learning: 2025-09-22T16:42:54.285Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: public/assets/AGENTS.md:0-0
Timestamp: 2025-09-22T16:42:54.285Z
Learning: Applies to public/assets/**/.mcp.json : Configure the Task Master MCP server in .mcp.json under mcpServers.task-master-ai with command npx and the listed env keys
Applied to files:
.changeset/loose-poems-tickle.mdsrc/profiles/zed.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/commands.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/commands.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/commands.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/commands.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/commands.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/commands.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/commands.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/commands.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/commands.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 rely on environment variables for API keys in tests; set mock environment variables in test setup.
Applied to files:
tests/unit/commands.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/commands.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/commands.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/commands.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/commands.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/commands.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/commands.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/commands.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/commands.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/commands.test.js
📚 Learning: 2025-07-18T17:10:53.657Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/glossary.mdc:0-0
Timestamp: 2025-07-18T17:10:53.657Z
Learning: Guidelines for implementing and maintaining tests for Task Master CLI (tests.mdc).
Applied to files:
tests/unit/commands.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Mock console output and verify correct formatting in UI function tests. Use flexible assertions like toContain() or toMatch() for formatted output.
Applied to files:
tests/unit/commands.test.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 : Implement semantic version comparison and display attractive update notifications using boxen.
Applied to files:
tests/unit/commands.test.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 : Implement version checking to notify users of available updates, use non-blocking version checks, and display update notifications after command completion.
Applied to files:
tests/unit/commands.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/tools/*.js : Create tool definitions in 'mcp-server/src/tools/', use Zod for parameter validation, include optional tag parameter for multi-context support, and follow established naming conventions.
Applied to files:
src/profiles/zed.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/*.js : MCP tools must follow a specific structure: use server.addTool with snake_case tool names, define parameters using Zod, and implement the execute function as an async function.
Applied to files:
src/profiles/zed.js
🧬 Code graph analysis (3)
scripts/init.js (1)
src/utils/asset-resolver.js (1)
readAsset(89-92)
tests/unit/commands.test.js (1)
index.js (3)
packageJson(37-37)version(64-64)version(64-64)
src/utils/path-utils.js (4)
scripts/modules/task-manager/expand-task.js (2)
projectRoot(322-322)logger(325-331)scripts/modules/utils.js (2)
projectRoot(576-578)projectRoot(671-671)scripts/modules/task-manager/expand-all-tasks.js (2)
projectRoot(47-47)logger(53-70)mcp-server/src/core/utils/path-utils.js (4)
projectRoot(61-63)projectRoot(96-98)projectRoot(132-134)projectRoot(167-167)
🪛 markdownlint-cli2 (0.18.1)
.changeset/loose-poems-tickle.md
5-5: First line in a file should be a top-level heading
(MD041, first-line-heading, first-line-h1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: build
- GitHub Check: typecheck
- GitHub Check: Test
🔇 Additional comments (12)
tests/unit/commands.test.js (4)
99-99: LGTM: Import alignment with new architecture.The import correctly follows the updated API surface that exports
compareVersionsfrom@tm/cli, aligning with the broader architectural change to source versioning externally.
117-117: LGTM: CLI name updated correctly.The program name expectation correctly updated from 'dev' to 'task-master' to match the proper CLI identity.
141-153: LGTM: Environment-driven version fallback test.This test correctly verifies the fallback behavior when
TM_PUBLIC_VERSIONis not set, returning 'unknown' as expected. The environment cleanup logic is properly implemented.
120-139: Critical Issue: Test conflicts with mocked fs and attempts to read real filesystem.This test will fail because:
fs.readFileSyncis mocked at line 10 to returnundefinedJSON.parse(fs.readFileSync(...))will throw since it's trying to parseundefined- The test attempts to read the real
package.jsonfile, which contradicts unit testing principlesThe version is now sourced from
TM_PUBLIC_VERSIONenvironment variable, so readingpackage.jsonis unnecessary.Apply this fix to decouple from filesystem and use environment-driven approach:
- test('should return version that matches package.json when TM_PUBLIC_VERSION is set', () => { - // Read actual version from package.json - const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8')); - const expectedVersion = packageJson.version; - - // Set environment variable to match package.json - const originalEnv = process.env.TM_PUBLIC_VERSION; - process.env.TM_PUBLIC_VERSION = expectedVersion; + test('should use TM_PUBLIC_VERSION when set', () => { + // Use a controlled version value + const expectedVersion = '1.2.3-test'; + const originalEnv = process.env.TM_PUBLIC_VERSION; + process.env.TM_PUBLIC_VERSION = expectedVersion; const program = setupCLI(); const version = program.version(); expect(version).toBe(expectedVersion); - // Restore original environment - if (originalEnv !== undefined) { - process.env.TM_PUBLIC_VERSION = originalEnv; - } else { - delete process.env.TM_PUBLIC_VERSION; - } + // Restore original environment + if (originalEnv !== undefined) { + process.env.TM_PUBLIC_VERSION = originalEnv; + } else { + delete process.env.TM_PUBLIC_VERSION; + } });scripts/modules/commands.js (5)
6-6: LGTM: Command-based CLI architecture.The import of
Commandfrom 'commander' enables the new architecture that usesnew Command()instead of the legacy approach. This aligns with the modern Commander.js patterns.
5082-5082: LGTM: Environment-driven version resolution.The version handling correctly uses
process.env.TM_PUBLIC_VERSION || 'unknown'instead of reading frompackage.json, which aligns with the build-time version injection pattern described in the PR objectives.
5111-5115: LGTM: Enhanced banner logic for init command.The conditional banner display correctly detects the init command and skips the general banner, allowing the init command to handle its own banner display appropriately.
5256-5269: LGTM: New utility function with clear documentation.The
resolveComplexityReportPathfunction is well-documented with clear rules for path resolution based on output options and tags. The logic correctly handles absolute paths, user-specified outputs, and tag-specific naming conventions.
5079-5082: CLI Identity: Use 'task-master' instead of 'dev'.The current CLI name shows as "dev" in help/usage messages. Update to use the proper CLI identity that matches documentation and user expectations.
- const programInstance = new Command() - .name('task-master') + const programInstance = new Command() + .name('task-master')Wait, I see this is already correctly set to 'task-master' on line 5080. Let me check the version handling instead...
Actually, reviewing the existing comment and the code, line 5080 already shows
.name('task-master')which is correct. The existing comment may be outdated..changeset/pre.json (3)
1-13: Automate pre enter/exit to avoid leaving pre.json in main.Ensure release CI runs: changeset pre enter (for RC), version, publish; and on promotion: changeset pre exit, version (which removes pre.json), publish.
9-12: Referenced changesets validated — no missing files.
All IDs listed in .changeset/pre.json have matching .changeset/*.md files; no stale IDs detected.
4-8: Remove stale entries from .changeset/pre.json initialVersionsRemove "docs" and "extension" from .changeset/pre.json (initialVersions); keep only "task-master-ai" and confirm its version is a non-prerelease baseline (e.g. 0.27.0).
| "mode": "exit", | ||
| "tag": "rc", |
There was a problem hiding this comment.
Inconsistent prerelease state: mode is "exit" but tag is "rc". Pick one.
If you intend to continue RC prereleases, switch mode to "pre". If you are promoting to stable, remove pre.json after versioning.
Apply this diff to remain in RC prerelease:
- "mode": "exit",
+ "mode": "pre",📝 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.
| "mode": "exit", | |
| "tag": "rc", | |
| "mode": "pre", | |
| "tag": "rc", |
🤖 Prompt for AI Agents
.changeset/pre.json lines 2-3: the prerelease configuration is inconsistent — it
sets "mode": "exit" while providing a "tag": "rc". To continue RC prereleases
change "mode" to "pre" (so the file becomes consistent with tag "rc"), or if you
intend to promote to stable either remove the pre.json file entirely after
versioning or delete the "tag" key and keep "mode":"exit". Make the change that
matches your intent.
| // Only warn once per command execution to prevent spam during init | ||
| const warningKey = `config_warning_${projectRoot}`; | ||
|
|
||
| if (!global._tmConfigWarningsThisRun) { | ||
| global._tmConfigWarningsThisRun = new Set(); | ||
| } | ||
|
|
||
| if (!global._tmConfigWarningsThisRun.has(warningKey)) { | ||
| global._tmConfigWarningsThisRun.add(warningKey); | ||
| logger.warn?.(`No configuration file found in project: ${projectRoot}`); | ||
| } | ||
|
|
There was a problem hiding this comment.
🧹 Nitpick
Consider alternatives to global state for per-run warning deduplication.
The use of global._tmConfigWarningsThisRun as a global Set to track warnings is a simple solution but goes against Node.js best practices which recommend avoiding global variables and using environment variables for configuration parameters without exposing them in your codebase. Consider these alternatives:
- Module-level cache: Use a module-level WeakMap or Map that doesn't pollute the global namespace
- Context-based approach: Pass a warning context object through the call chain
- Process-based tracking: Use process-scoped variables or environment flags
Apply this diff for a module-level approach:
+// Module-level warning tracking to avoid global namespace pollution
+const _configWarningsThisRun = new Set();
+
export function findConfigPath(explicitPath = null, args = null, log = null) {
const logger = getLoggerOrDefault(log);
// ... existing code ...
- // Only warn once per command execution to prevent spam during init
- const warningKey = `config_warning_${projectRoot}`;
-
- if (!global._tmConfigWarningsThisRun) {
- global._tmConfigWarningsThisRun = new Set();
- }
-
- if (!global._tmConfigWarningsThisRun.has(warningKey)) {
- global._tmConfigWarningsThisRun.add(warningKey);
+ // Only warn once per command execution to prevent spam during init
+ const warningKey = `config_warning_${projectRoot}`;
+
+ if (!_configWarningsThisRun.has(warningKey)) {
+ _configWarningsThisRun.add(warningKey);
logger.warn?.(`No configuration file found in project: ${projectRoot}`);
}📝 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.
| // Only warn once per command execution to prevent spam during init | |
| const warningKey = `config_warning_${projectRoot}`; | |
| if (!global._tmConfigWarningsThisRun) { | |
| global._tmConfigWarningsThisRun = new Set(); | |
| } | |
| if (!global._tmConfigWarningsThisRun.has(warningKey)) { | |
| global._tmConfigWarningsThisRun.add(warningKey); | |
| logger.warn?.(`No configuration file found in project: ${projectRoot}`); | |
| } | |
| // Module-level warning tracking to avoid global namespace pollution | |
| const _configWarningsThisRun = new Set(); | |
| export function findConfigPath(explicitPath = null, args = null, log = null) { | |
| const logger = getLoggerOrDefault(log); | |
| // ... existing code ... | |
| // Only warn once per command execution to prevent spam during init | |
| const warningKey = `config_warning_${projectRoot}`; | |
| if (!_configWarningsThisRun.has(warningKey)) { | |
| _configWarningsThisRun.add(warningKey); | |
| logger.warn?.(`No configuration file found in project: ${projectRoot}`); | |
| } | |
| } |
🤖 Prompt for AI Agents
In src/utils/path-utils.js around lines 466 to 477, replace the use of
global._tmConfigWarningsThisRun with a module-level Set to avoid polluting
global namespace: declare a file-scoped Set (e.g., const
_tmConfigWarningsThisRun = new Set()) near the top of the module, remove all
reads/writes to global._tmConfigWarningsThisRun, and update the code to
check/add warningKey on the module-level Set and call logger.warn once per run;
keep the Set unexported so it remains private to the module and retains
per-process lifetime.
…x.ci.failure.main
What type of PR is this?
Description
Related Issues
How to Test This
# Example commands or stepsExpected result:
Contributor Checklist
npm run changesetnpm testnpm run format-check(ornpm run formatto fix)Changelog Entry
For Maintainers
Summary by CodeRabbit
New Features
Refactor
Fixes / Behavior
Chores