Skip to content

feat/Implement a new AgentLLM provider to Delegate Task Master LLM calls to an MCP client without requiring API keys#933

Closed
rtmcrc wants to merge 97 commits intoeyaltoledano:nextfrom
rtmcrc:mcp-agent
Closed

feat/Implement a new AgentLLM provider to Delegate Task Master LLM calls to an MCP client without requiring API keys#933
rtmcrc wants to merge 97 commits intoeyaltoledano:nextfrom
rtmcrc:mcp-agent

Conversation

@rtmcrc
Copy link
Copy Markdown

@rtmcrc rtmcrc commented Jul 7, 2025

Add AgentLLM Provider for Delegated AI Operations

📋 Overview

This PR introduces new AgentLLM Provider, a new delegation system that allows Taskmaster to offload Large Language Model (LLM) calls to connected agents through the MCP (Model Context Protocol) interface. Instead of making direct API calls to LLM providers, Taskmaster can now delegate AI operations to MCP clients that manage their own LLM infrastructure and credentials.

🚀 Key Features

Agent-Delegated LLM Calls

  • Seamless Delegation: Taskmaster operations (parse_prd, analyze_project_complexity, expand_task, expand_all, update, update_task, update_subtask, add_task, research) tools can now delegate LLM calls to MCP clients.
  • Provider Abstraction: New AgentLLMProvider class that implements the same interface as existing LLM providers
  • Interaction Management: Robust correlation system using interactionId to track request-response cycles

MCP Tool Integration

  • New agent_llm MCP Tool: Dedicated communication channel for LLM delegation
  • Bidirectional Communication: Supports both Taskmaster→Agent and Agent→Taskmaster calls
  • Status Tracking: Comprehensive status reporting for pending interactions and completion

Flexible Architecture

  • Role-Based Delegation: Supports delegation for different AI roles (main, research, fallback)
  • Mixed Provider Support: Can be used alongside traditional LLM providers in the same project
  • Error Handling: Robust error propagation and recovery mechanisms

🔧 Technical Implementation

Core Components

1. AgentLLMProvider Class

  • Implements standard LLM provider interface
  • Generates unique interaction IDs for correlation
  • Returns delegation signals instead of direct LLM calls

2. Enhanced MCP Server Logic

  • Detects pending agent interactions
  • Pauses operations during delegation
  • Resumes operations upon agent response

3. Agent Communication Protocol

  • Structured request/response format
  • Support for generateText, streamText, and generateObject operations
  • Comprehensive error handling and status reporting

Workflow Overview

T as Taskmaster
A as Agent
L as Agent's LLM

T->>T: Operation requires LLM call
T->>A: TaskMaster tool (delegation request)
A->>L: Perform LLM call
L->>A: LLM response
A->>T: agent_llm (response with data)
T->>T: Resume operation with LLM result

📖 Usage Examples

Configuration

json{
  "models": {
    "main": {
      "provider": "agentllm",
      "modelId": "agent-delegated-model",
      "maxTokens": 1048000,
      "temperature": 0.2
     },
    "research": {
      "provider": "agentllm",
      "modelId": "agent-delegated-model",
      "maxTokens": 8700,
      "temperature": 0.1
    },
  }
}

Agent Response Handling

javascript// Success response

{
  "interactionId": "uuid-string",
  "agentLLMResponse": {
    "status": "success",
    "data": {
      "text": "Generated response",
      "usage": { "inputTokens": 10, "outputTokens": 5 }
    }
  }
}

// Error response

{
  "interactionId": "uuid-string", 
  "agentLLMResponse": {
    "status": "error",
    "errorDetails": {
      "message": "Rate limit exceeded",
      "type": "rate_limit_error"
    }
  }
}

🎯 Benefits

For Users

  • Simplified Setup: No need to manage multiple API keys in Taskmaster
  • Cost Control: Agents handle their own LLM billing and rate limiting
  • Flexibility: Use any LLM provider or local models through the agent
  • Unified Interface: Same Taskmaster commands work regardless of LLM source

For Developers

  • Clean Separation: Clear boundary between task orchestration and LLM execution
  • Extensibility: Easy to add support for new LLM providers through agents
  • Debugging: Improved visibility into LLM call delegation and responses

🧪 Testing

  • Tests: All tests are passing
  • Error Scenarios: Coverage for network failures, timeouts, and invalid responses
  • Provider Compatibility: Ensures AgentLLM works alongside existing providers
  • Tested MCP Clients: Successfully tested with Claude Desktop, Roocode, Cline, VSCode Copilot, Cursor, Windsurf and Gemini-CLI. Among all Claude Desktop is the best it does not need any rules and understands the Taskmaster LLM call delegations on its own. All tests were conducted with free models. Cline/grok3, Claude Desktop/Sonnet4, Roocode/Gemini Flash 2.5, VScode Copilot/Gpt 4.1, Cursor/Gemini 2.5 Flash, Windsurf/SWE-1, Gemini-CLI/Gemini 2.5 pro

📚 Documentation

  • Added docs/agent-llm-workflow.md to outline the complete workflow.
  • Rules: Added rules assets/rules/agent_llm.mdc for the agent_llm MCP tool. (Note: These rules are crucial for MCP clients to understand the correct workflow.) Once a Taskmaster is initialized rules has to be added with a rule tool for the desired client, or they maybe added manually to a client that is not in the list).

🔄 Backward Compatibility

  • Non-Breaking: Existing configurations continue to work unchanged
  • Opt-In: AgentLLM is used only when explicitly configured
  • Fallback Support: Can be combined with traditional providers for redundancy

🎉 Impact

This feature significantly expands Taskmaster's deployment flexibility, allowing it to work in environments where:

Direct LLM API access is restricted
Custom LLM infrastructure is preferred
Local or specialized models in MCP context need to be integrated

Taskmaster_Cline_MCP
Claude_Desktop
Gemini_CLI
Cursor
Windsurf
VSCode_Copilot

Summary by CodeRabbit

  • New Features
    • Delegate LLM calls to an external agent with a pending-interaction flow and an agent-managed model option.
    • Agent-driven workflows for task creation, expansion, research, complexity reports, updates, and scope adjustments; optional auto-saving of research/results.
  • Bug Fixes
    • Subtask status now includes an "in-progress" state.
  • Documentation
    • Added Agent LLM workflow guide, rules, and updated model listings/timestamps.

Note

Introduces AgentLLM provider and agent_llm MCP tool to delegate LLM calls, with end-to-end pending-interaction handling and post-processing across core tools.

  • AgentLLM Delegation (Core/Server):
    • Add AgentLLMProvider and integrate into provider registry; treat as no-API-key provider.
    • Enhance MCP server with AgentLLMProviderToolExecutor, pending-interaction tracking, and resume-on-response.
    • Add post-processing savers for delegated results: parse PRD, expand task, add task, research, update task/subtask(s), scope up/down, complexity report.
  • MCP Tools:
    • New agent_llm tool (Taskmaster→Agent request, Agent→Taskmaster response) and tooling updates to auto-propagate delegation via createAgentDelegationResponse.
    • Update existing tools/direct-functions to detect, propagate, and handle delegation; enrich logs and messages (e.g., expand_all now returns delegatedTaskIds).
  • Task/Logic Enhancements:
    • add-task: synthesize prompt when AgentLLM is preferred; support provider checks.
    • research: normalize saveTo, improved validation, optional auto-save to task/subtask/file.
    • Allow subtask status in-progress.
  • Utils/Config:
    • Add createLogger; harden writeJSON for tagged data; tag-aware task file generation and dependency manager uses tag getters/setters.
    • Recognize agentllm in config; ai-services-unified surfaces delegation signals.
  • Docs/Rules/Models:
    • Add apps/docs/archive/agent-llm-workflow.mdx and assets/rules/agentllm.mdc.
    • Update model listings (date bump; add agentllm/agent-delegated-model; Gemini ID refresh).
  • Tests:
    • New unit tests for AgentLLM provider/tool and broad test updates to accommodate delegation, logging, and tag-aware changes.

Written by Cursor Bugbot for commit c034605. This will update automatically on new commits. Configure here.

This commit introduces a new "AgentLLM" provider and associated MCP tool to delegate LLM calls to an agent. This allows Taskmaster MCP sever to offload LLM operations to the agent calling it.

Key changes include:

-   **New `AgentLLMProvider`:** An AI provider that, instead of calling an LLM directly, returns a delegation signal with an `interactionId` and LLM request details.
-   **New `agent_llm` MCP Tool:**  A tool that facilitates communication between Taskmaster and the agent. Taskmaster uses it to request LLM calls, and the agent uses it to return the LLM response.
-   **TaskMasterMCPServer Enhancements:** The server now manages pending agent interactions, pausing the original operation and resuming it upon receiving the agent's response.
-   **Documentation:** Added `docs/agent-llm-workflow.md` to outline the complete workflow.
-   **Rules:** Added rules `assets/rules/agent_llm.mdc`for the `agent_llm` MCP tool and `AgentLLMProvider`.

The workflow involves Taskmaster initiating a delegated LLM call, the agent performing the LLM call, and the agent calling `agent_llm` back to Taskmaster with the results.  An `interactionId` is used to correlate requests and responses.
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Jul 7, 2025

🦋 Changeset detected

Latest commit: c034605

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

@Crunchyman-ralph Crunchyman-ralph changed the base branch from main to next July 7, 2025 16:58
@Crunchyman-ralph
Copy link
Copy Markdown
Collaborator

Potentially duplicate of #863

@rtmcrc rtmcrc marked this pull request as ready for review July 7, 2025 17:14
@rtmcrc
Copy link
Copy Markdown
Author

rtmcrc commented Jul 8, 2025

Tested with Windsurf and now it works with Cursor also

@hobbytp
Copy link
Copy Markdown

hobbytp commented Jul 9, 2025

This is an excellent improvement, saving windsurf and cursor users some money ;-)
Hope it can be merged asap.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jul 11, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds AgentLLM delegation: new AgentLLM provider that emits delegation signals, an agent_llm MCP tool to manage pending interactions and callbacks, server-side pending-interaction tracking and wrapped tool execution, saver utilities to persist agent results, and tag-aware persistence plus delegation-aware control flow across many modules.

Changes

Cohort / File(s) Summary
Agent LLM provider & models
src/ai-providers/agent-llm.js, src/ai-providers/index.js, scripts/modules/supported-models.json, docs/models.md, packages/tm-core/src/common/constants/providers.ts
Add AgentLLMProvider export; register agentllm provider and agent-delegated-model; provider returns agent_llm_delegation payloads for text/object generation.
MCP agent_llm tool & registry
mcp-server/src/tools/agent-llm.js, mcp-server/src/tools/tool-registry.js, mcp-server/src/tools/utils.js, mcp-server/src/index.js
New agent_llm MCP tool for delegation and agent callbacks; helper createAgentDelegationResponse; TaskMasterMCPServer gains pendingAgentLLMInteractions and registeredTools, tool registration wrapped to use AgentLLM executor.
Provider executor & post-processing
mcp-server/src/providers/agentllm-provider-tool-executor.js
Executor wrapper detects delegation, stores per-interaction promise/timeout, dispatches agent_llm calls, and routes agent callbacks to _handlePostProcessing which invokes saver utilities.
AgentLLM saver framework & implementations
mcp-server/src/core/utils/agentllm-base-tool-saver.js, mcp-server/src/core/utils/*agentllm-*-tool-saver.js
Add AgentLLMToolSaver base class and multiple saver modules (add/expand/parse-prd/research/update/update-subtask/complexity-report/scope) to validate/process agent outputs, mutate per-tag tasks, and regenerate markdown.
Direct functions: delegation propagation
mcp-server/src/core/direct-functions/* (e.g., add-task.js, analyze-task-complexity.js, expand-task.js, expand-all-tasks.js, parse-prd.js, research.js, update-*.js, scope-up.js, scope-down.js)
Direct functions forward tag/context, accept some optional args (e.g., tag, complexityReportPath) and early-return when core results include needsAgentDelegation === true.
MCP tools: centralized delegation handling
mcp-server/src/tools/* (e.g., add-task.js, analyze.js, expand-task.js, parse-prd.js, research.js, update-task.js, update-subtask.js, update.js, scope-up.js, scope-down.js)
Tools call createAgentDelegationResponse after direct calls and short-circuit by returning delegation responses when present; research tool param renamed saveTosaveToTask (internally mapped).
Task-manager delegation & tag-awareness
scripts/modules/task-manager/*, scripts/modules/task-manager/llm-delegation.js, scripts/modules/task-manager/parse-prd/parse-prd-non-streaming.js
Add handleAgentLLMDelegation used across AI call sites to detect delegation and short-circuit flows; many task-manager flows become tag-aware and support save-to-task/save-to-file behaviors.
Tag-aware persistence & utilities
scripts/modules/dependency-manager.js, scripts/modules/utils.js, scripts/modules/task-manager/generate-task-files.js
Dependency manager moved to per-tag task access (getTasksForTag/setTasksForTag); writeJSON made defensive; add createLogger and slugifyTagForFilePath; task file naming uses slugified tags.
AI services unified & config
scripts/modules/ai-services-unified.js, scripts/modules/config-manager.js
Unified AI services registers agentllm provider and handles agent_llm_delegation responses; config-manager treats AGENTLLM as a no‑API‑key provider and maps AGENTLLM_API_KEY.
Expand flows & telemetry
scripts/modules/task-manager/expand-all-tasks.js, scripts/modules/task-manager/expand-task.js, mcp-server/src/core/direct-functions/expand-all-tasks.js
Track delegationSignaledCount and delegatedTaskIds; skip local expansion when delegation signaled; include delegation info in summaries/telemetry.
Profiles, rules & docs
assets/rules/agentllm.mdc, src/profiles/base-profile.js, apps/docs/archive/agent-llm-workflow.mdx
Add AgentLLM rule doc, map rule in base profile, and add archived workflow doc describing delegation flow.
Schemas & tests
src/schemas/base-schemas.js, many tests/*
Add in-progress to Subtask status enum; extensive tests added/updated for AgentLLM provider, agent_llm tool, savers, delegation flows, tag utilities, and updated mocks (createLogger, getTasksForTag, setTasksForTag, slugifyTagForFilePath); tool counts updated.
Changesets & release config
.changeset/*.md, .changeset/pre.json
New changeset files and pre-release config added documenting the changes.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Client as Client
    participant MCP as MCP Server
    participant Tool as Tool (e.g., expand_task)
    participant Executor as AgentLLMProviderExecutor
    participant AgentTool as agent_llm Tool
    participant Agent as Agent Client
    participant Saver as AgentLLM Saver

    Client->>MCP: call tool
    MCP->>Tool: execute
    Tool->>Executor: execute wrapped provider -> provider returns delegation (agent_llm_delegation)
    Executor-->>Tool: initial pending response (needsAgentDelegation / pendingInteraction)
    Executor->>AgentTool: dispatch pendingInteraction (interactionId, llmRequestForAgent)
    AgentTool-->>Agent: pendingInteraction payload (out-of-band)
    Note right of Agent: Agent performs external LLM call using provided details
    Agent->>AgentTool: POST agent_llm (interactionId + agentLLMResponse)
    AgentTool->>Executor: deliver agent response
    Executor->>Saver: _handlePostProcessing(finalLLMOutput)
    Saver->>MCP: persist updates (tasks.json, md files)
    Executor-->>Tool: resolve pending promise with mainResult
    Tool-->>Client: return final result
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

  • Pay special attention to:
    • AgentLLMProviderToolExecutor: pending promise lifecycle, timeouts, concurrency, map cleanup, and error propagation.
    • AgentLLM saver modules: validation schemas, merge semantics, id generation/deduplication, file I/O, and markdown regeneration.
    • Delegation propagation consistency across direct functions and MCP tools (silent-mode handling, tag/projectRoot forwarding).
    • Tag-aware persistence changes in dependency-manager and defensive read/write logic in writeJSON.
    • Test updates and mock adjustments to ensure test contracts match runtime behavior.

Possibly related PRs

Suggested reviewers

  • Crunchyman-ralph

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title accurately summarizes the main change: implementing a new AgentLLM provider that delegates Task Master LLM calls to an MCP client without requiring API keys.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

@rtmcrc rtmcrc force-pushed the mcp-agent branch 2 times, most recently from 715c1a7 to 0e5abb5 Compare July 13, 2025 12:14
…g systems, especially Windows, where backslashes are used as path separators.

fix: vscode does not see rules without .instructions.md extension

Merge. Format
@rtmcrc rtmcrc marked this pull request as draft July 13, 2025 12:31
@rtmcrc rtmcrc marked this pull request as ready for review July 13, 2025 14:40
github-actions Bot and others added 13 commits July 14, 2025 11:28
* fix: prevent CLAUDE.md overwrite by using imports

- Copy Task Master instructions to .taskmaster/CLAUDE.md
- Add import section to user's CLAUDE.md instead of overwriting
- Preserve existing user content
- Clean removal of Task Master content on uninstall

Closes eyaltoledano#929

* chore: add changeset for Claude import fix
…edano#968)

* feat: add task master (tm) custom slash commands

Add comprehensive task management system integration via custom slash commands.
Includes commands for:
- Project initialization and setup
- Task parsing from PRD documents
- Task creation, update, and removal
- Subtask management
- Dependency tracking and validation
- Complexity analysis and task expansion
- Project status and reporting
- Workflow automation

This provides a complete task management workflow directly within Claude Code.

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

Co-Authored-By: Claude <noreply@anthropic.com>

* chore: add changeset

---------

Co-authored-by: neno-is-ooo <204701868+neno-is-ooo@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
* chore: create extension scaffolding

* chore: fix workspace for changeset

* chore: fix package-lock
…ano#980)

* add .mcp.json with claude profile

* add changeset

* update changeset

* update test
…oledano#978)

* feat: complete Groq provider integration and add Kimi K2 model

- Add missing getRequiredApiKeyName() method to GroqProvider class
- Register GroqProvider in ai-services-unified.js PROVIDERS object
- Add Groq API key handling to config-manager.js (isApiKeySet and getMcpApiKeyStatus)
- Add GROQ_API_KEY to env.example with format hint
- Add moonshotai/kimi-k2-instruct model to Groq provider ($1/$3 per 1M tokens, 16k max)
- Fix import sorting for linting compliance
- Add GroqProvider mock to ai-services-unified tests

Fixes missing implementation pieces that prevented Groq provider from working.

* chore: improve changeset

---------

Co-authored-by: Ben Vargas <ben@example.com>
Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
…#973)

* Amp profile + tests

* generatlize to Agent instead of Claude Code to support any agent

* add changeset

* unnecessary tab formatting

* fix exports

* fix formatting
…#972)

* add OLLAMA_API_KEY

* add missing API keys

* add changeset

* update keys and fix OpenAI comment

* chore: create extension scaffolding (eyaltoledano#989)

* chore: create extension scaffolding

* chore: fix workspace for changeset

* chore: fix package-lock

* feat(profiles): Add MCP configuration to Claude Code rules (eyaltoledano#980)

* add .mcp.json with claude profile

* add changeset

* update changeset

* update test

* fix: show command no longer requires complexity report to exist (eyaltoledano#979)

Co-authored-by: Ben Vargas <ben@example.com>

* feat: complete Groq provider integration and add Kimi K2 model (eyaltoledano#978)

* feat: complete Groq provider integration and add Kimi K2 model

- Add missing getRequiredApiKeyName() method to GroqProvider class
- Register GroqProvider in ai-services-unified.js PROVIDERS object
- Add Groq API key handling to config-manager.js (isApiKeySet and getMcpApiKeyStatus)
- Add GROQ_API_KEY to env.example with format hint
- Add moonshotai/kimi-k2-instruct model to Groq provider ($1/$3 per 1M tokens, 16k max)
- Fix import sorting for linting compliance
- Add GroqProvider mock to ai-services-unified tests

Fixes missing implementation pieces that prevented Groq provider from working.

* chore: improve changeset

---------

Co-authored-by: Ben Vargas <ben@example.com>
Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>

* docs: Auto-update and format models.md

* feat: Add Amp rule profile with AGENT.md and MCP config (eyaltoledano#973)

* Amp profile + tests

* generatlize to Agent instead of Claude Code to support any agent

* add changeset

* unnecessary tab formatting

* fix exports

* fix formatting

* feat: Add Zed editor rule profile with agent rules and MCP config (eyaltoledano#974)

* zed profile

* add changeset

* update changeset

---------

Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
Co-authored-by: Ben Vargas <ben@vargas.com>
Co-authored-by: Ben Vargas <ben@example.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
…ledano#970)

* add opencode to profile lists

* add opencode profile / modify mcp config after add

* add changeset

* not necessary; main config being updated

* add issue link

* add/fix tests

* fix url and docsUrl

* update test for new urls

* fix formatting

* update/fix tests
* chore: add coderabbit configuration

* chore: fix coderabbit config

* chore: improve coderabbit config

* chore: more coderabbit reviews

* chore: remove all defaults
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

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

⚠️ Outside diff range comments (1)
scripts/modules/dependency-manager.js (1)

62-70: Fix tag-aware task loading before aborting

readJSON returns the tagged root object, so data.tasks is undefined under the standard multi-tag layout. This guard therefore trips on every tagged project and exits before any dependency work happens, breaking the command. Resolve the tag first and validate the resulting array instead.

-	const data = readJSON(tasksPath, context.projectRoot, context.tag);
-	if (!data || !data.tasks) {
-		log('error', 'No valid tasks found in tasks.json');
-		process.exit(1);
-	}
-
-	const tag = context.tag || 'master';
-	const tasks = getTasksForTag(data, tag);
+	const data = readJSON(tasksPath, context.projectRoot, context.tag);
+	const tag = context.tag || 'master';
+
+	if (!data) {
+		log('error', 'No valid tasks found in tasks.json');
+		process.exit(1);
+	}
+
+	const tasks = getTasksForTag(data, tag);
+	if (!Array.isArray(tasks)) {
+		log('error', `No valid tasks found for tag '${tag}' in tasks.json`);
+		process.exit(1);
+	}

Based on learnings

♻️ Duplicate comments (1)
mcp-server/src/core/direct-functions/research.js (1)

68-288: Restore canonical error codes in researchDirect.

The direct-function guidelines require all responses to use the shared codes (INPUT_VALIDATION_ERROR, FILE_NOT_FOUND_ERROR, CORE_FUNCTION_ERROR, UNEXPECTED_ERROR). This block still returns bespoke values (MISSING_PARAMETER, INVALID_PARAMETER, INVALID_CORE_RESPONSE, RESEARCH_ERROR), so clients relying on the standardized codes can’t interpret failures correctly. Please swap each return to the canonical constants and normalize the catch path, e.g.:

-				error: {
-					code: 'MISSING_PARAMETER',
+				error: {
+					code: 'INPUT_VALIDATION_ERROR',
 					message:
 						'The query parameter is required and must be a non-empty string'
 				}
...
-				error: {
-					code: 'INVALID_PARAMETER',
+				error: {
+					code: 'INPUT_VALIDATION_ERROR',
 					message: `Detail level must be one of: ${validDetailLevels.join(', ')}`
 				}
...
-				error: {
-					code: 'INVALID_CORE_RESPONSE',
+				error: {
+					code: 'CORE_FUNCTION_ERROR',
 					message: 'Core research function returned invalid data.'
 				}
...
-			error: {
-				code: error.code || 'RESEARCH_ERROR',
-				message: error.message
-			}
+			const validCodes = new Set([
+				'INPUT_VALIDATION_ERROR',
+				'FILE_NOT_FOUND_ERROR',
+				'CORE_FUNCTION_ERROR',
+				'UNEXPECTED_ERROR'
+			]);
+			error: {
+				code: validCodes.has(error.code) ? error.code : 'CORE_FUNCTION_ERROR',
+				message: error.message
+			}

This preserves compatibility with other tools and satisfies the direct-function contract. As per coding guidelines.

🧹 Nitpick comments (1)
.changeset/four-bugs-occur.md (1)

5-7: Refocus changeset summary on user-facing impact.

The current description emphasizes internal implementation details (removal of file and parameter, complexity reduction for AI agents) rather than the user-facing benefit. Per coding guidelines, changesets should describe what changed in the released version that is relevant to users or consumers of the package.

Additionally, line 7 could be more concise—consider removing the verbose explanation or making it user-centric.

Consider this revision:

- remove file and complexity report parameter from get-tasks and get-task mcp tool
-
- - In an effort to reduce complexity and context bloat for ai coding agents, we simplified the parameters of these tools
+ Simplify get-tasks and get-task MCP tools for improved clarity

If the removed file or parameter change is significant to document, add a brief user-facing note explaining the impact (e.g., "improves response clarity" or "reduces unnecessary data").

As per coding guidelines.

@@ -0,0 +1,5 @@
---
"task-master-ai": patch
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Reconsider semantic versioning: should be minor, not patch.

The PR introduces a substantial new feature (AgentLLM provider for delegating LLM calls to MCP clients), which warrants a minor version bump, not patch. Patch releases are for bug fixes and non-breaking maintenance; new features require at least a minor version increment. Additionally, the PR comments from the reviewer explicitly requested the changeset be marked as "minor" to avoid bumping to v1.0.

Apply this diff:

-"task-master-ai": patch
+"task-master-ai": minor

Based on coding guidelines and PR review context.

📝 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.

Suggested change
"task-master-ai": patch
"task-master-ai": minor
🤖 Prompt for AI Agents
.changeset/lazy-suits-smell.md around line 2: the changeset currently marks the
release as "patch" but the PR adds a significant new feature (AgentLLM
provider), so update the changeset to use "minor" instead of "patch". Edit the
file to change the version bump line from `"task-master-ai": patch` to
`"task-master-ai": minor` (preserve YAML/changeset format and surrounding
content) so the release level correctly reflects a feature addition.

"task-master-ai": patch
---

Improve session persistence reliability No newline at end of file
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot Oct 30, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Rewrite description to be user-facing and match the PR scope.

The description "Improve session persistence reliability" is generic and does not reflect the actual feature being added. Changesets should describe user-facing impact in imperative mood, typically a single line. The PR introduces an AgentLLM provider that enables delegating LLM calls to connected MCP agents, eliminating the need for direct API keys.

Apply this diff:

-Improve session persistence reliability
+Add AgentLLM provider for delegating LLM calls to MCP agents without requiring API keys

As per coding guidelines: changesets should describe user-facing impact rather than internal implementation details.

📝 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.

Suggested change
Improve session persistence reliability
Add AgentLLM provider for delegating LLM calls to MCP agents without requiring API keys
🤖 Prompt for AI Agents
In .changeset/lazy-suits-smell.md around line 5, the changeset description is
generic; replace it with a concise, user-facing imperative sentence that
reflects the PR scope — e.g. "Add AgentLLM provider to delegate LLM calls to
connected MCP agents so users can operate without direct API keys." Ensure the
changeset is a single-line, imperative description and remove
internal-implementation phrasing.

Copy link
Copy Markdown
Author

@rtmcrc rtmcrc Oct 30, 2025

Choose a reason for hiding this comment

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

The lazy-suits-smell.md does not apply to AgentLLM

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@rtmcrc, understood! You're absolutely right—lazy-suits-smell.md is for session persistence improvements and is separate from the AgentLLM feature.

I can see that the AgentLLM provider implementation is documented in the quiet-ties-battle.md changeset, which correctly describes adding the AgentLLM provider for delegating LLM calls to MCP agents without requiring API keys.

Thank you for the clarification!


🧠 Learnings used
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: assets/claude/agents/task-orchestrator.md:69-78
Timestamp: 2025-08-06T21:13:05.240Z
Learning: For Claude agent instruction files in .claude/agents/ and assets/claude/agents/ directories, ignore markdownlint issues (like MD031 blanks-around-fences, MD040 fenced-code-language, MD041 missing top-level heading) as these files follow Claude's specific agent format requirements rather than standard markdown documentation conventions.

Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/changeset.mdc:0-0
Timestamp: 2025-07-18T17:07:53.100Z
Learning: Applies to .changeset/*.md : The changeset summary should be user-facing, describing what changed in the released version that is relevant to users or consumers of the package.

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

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.

Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/changeset.mdc:0-0
Timestamp: 2025-07-18T17:07:53.100Z
Learning: Every pull request containing new features, bug fixes, breaking changes, performance improvements, significant refactoring, user-facing documentation updates, dependency updates, or impactful build/tooling changes should include a changeset file.

Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/changeset.mdc:0-0
Timestamp: 2025-07-18T17:07:53.100Z
Learning: Do not add a changeset for trivial chores such as very minor code cleanup, adding comments that don't clarify behavior, or typo fixes in non-user-facing code or internal docs.

Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/changeset.mdc:0-0
Timestamp: 2025-07-18T17:07:53.100Z
Learning: Always stage and commit the generated `.changeset/*.md` file along with your relevant code changes.

Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: CLAUDE.md:0-0
Timestamp: 2025-10-27T17:16:25.430Z
Learning: Applies to .changeset/*.md : Changesets should describe user-facing impact rather than internal implementation details

Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1091
File: .changeset/wide-actors-report.md:0-0
Timestamp: 2025-08-06T21:14:23.071Z
Learning: For changeset files (.changeset/*.md), the first line after the frontmatter must be a plain, unstyled summary line that gets integrated directly into the changelog. Do not add markdown headings or styling as this would interfere with the changelog generation process. Ignore markdownlint MD041 rule for these files.

Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/changeset.mdc:0-0
Timestamp: 2025-07-18T17:07:53.100Z
Learning: Do not add a changeset for non-impactful test updates, such as minor refactoring of tests or adding tests for existing functionality without fixing bugs.

Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1285
File: .changeset/nice-ways-hope.md:5-17
Timestamp: 2025-10-08T12:21:14.455Z
Learning: For changeset files (.changeset/*.md): The first line should be concise and in imperative mood, but the body after the first line can include as many user-facing details as desired (bullets, explanations, links, etc.) to provide context for the CHANGELOG.md.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
mcp-server/src/tools/scope-up.js (2)

94-100: Agent delegation logic looks correct, but consider logging.

The delegation handling follows the new pattern introduced in this PR: calling createAgentDelegationResponse after the direct function completes and short-circuiting if delegation is triggered. The guidance message appropriately instructs the agent to reanalyze project complexity after scoping up.

However, per coding guidelines, successful completion should be logged with a result summary. Consider adding a log statement when delegation occurs:

 const delegation = createAgentDelegationResponse(
 	result,
 	log,
 	'scope_up_task',
 	"Your Next Action: After you have scoped the task reanalyze the project complexity with 'analyze_project_complexity' tool including this task ID in 'ids' parameter."
 );
-if (delegation.delegated) return delegation.response;
+if (delegation.delegated) {
+	log.info('Delegation triggered for scope_up_task');
+	return delegation.response;
+}

102-108: Response handling is correct; consider adding success logging.

The fallback to handleApiResult is appropriate and follows guidelines. However, per coding guidelines, successful operations should be logged with a result summary. Consider adding:

+	log.info('Scope-up completed successfully');
 	return handleApiResult(
 		result,
 		log,
 		'Error scoping up task',
 		undefined,
 		args.projectRoot
 	);
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aa3c0ae and 6f96865.

📒 Files selected for processing (10)
  • docs/models.md (6 hunks)
  • mcp-server/src/tools/scope-down.js (2 hunks)
  • mcp-server/src/tools/scope-up.js (2 hunks)
  • packages/tm-core/src/common/constants/providers.ts (1 hunks)
  • scripts/modules/ai-services-unified.js (4 hunks)
  • scripts/modules/config-manager.js (4 hunks)
  • scripts/modules/supported-models.json (2 hunks)
  • scripts/modules/task-manager/analyze-task-complexity.js (2 hunks)
  • src/ai-providers/index.js (1 hunks)
  • tests/unit/ai-services-unified.test.js (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • scripts/modules/config-manager.js
  • scripts/modules/task-manager/analyze-task-complexity.js
  • mcp-server/src/tools/scope-down.js
  • tests/unit/ai-services-unified.test.js
🧰 Additional context used
📓 Path-based instructions (13)
scripts/modules/ai-services-unified.js

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

Integrate the new provider module with scripts/modules/ai-services-unified.js by importing it and adding an entry to the PROVIDER_FUNCTIONS map.

scripts/modules/ai-services-unified.js: Centralize all LLM calls through generateTextService or generateObjectService.
Do not import or call anything from the old ai-services.js, ai-client-factory.js, or ai-client-utils.js files.
Do not fetch AI-specific parameters (model ID, max tokens, temp) using config-manager.js getters for the AI call. Pass the role instead.
Do not implement fallback or retry logic outside ai-services-unified.js.
Do not handle API key resolution outside the service layer (it uses utils.js internally).

The telemetryData object returned by ai-services-unified.js must include the fields: timestamp, userId, commandName, modelUsed, providerName, inputTokens, outputTokens, totalTokens, totalCost, and currency.

Files:

  • scripts/modules/ai-services-unified.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/ai-services-unified.js
scripts/modules/**

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

When using the MCP server, restart it if core logic in scripts/modules or MCP tool/direct function definitions change.

Files:

  • scripts/modules/ai-services-unified.js
  • scripts/modules/supported-models.json
scripts/modules/ai-services*.js

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

Ensure AI calls correctly handle and propagate telemetryData as described in 'telemetry.mdc'.

Files:

  • scripts/modules/ai-services-unified.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/ai-services-unified.js
  • scripts/modules/supported-models.json
**/*.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/ai-services-unified.js
  • src/ai-providers/index.js
  • mcp-server/src/tools/scope-up.js
src/ai-providers/*.js

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

src/ai-providers/*.js: Create a new provider module file in src/ai-providers/ named .js when adding a new AI provider.
Provider modules must export three functions: generateText, streamText, and generateObject.
Provider modules must import the provider's create function from @ai-sdk/, and import generateText, streamText, generateObject from the core ai package, as well as the log utility from ../../scripts/modules/utils.js.
Implement generateText, streamText, and generateObject functions in provider modules with basic validation and try/catch error handling.

Provider-specific wrappers for Vercel AI SDK functions must be implemented in src/ai-providers/*.js, each file corresponding to a provider.

Files:

  • src/ai-providers/index.js
mcp-server/src/tools/*.js

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

MCP server tools in mcp-server/src/tools/*.js must have their execute methods wrapped with the withNormalizedProjectRoot higher-order function from tools/utils.js to ensure consistent path handling.

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.
All MCP tool execute methods that require access to the project root MUST be wrapped with the withNormalizedProjectRoot Higher-Order Function (HOF) from mcp-server/src/tools/utils.js.
MCP tools should always call *Direct wrappers instead of executeTaskMasterCommand, except as a fallback if a direct function is not yet implemented.
Use camelCase with Tool suffix for tool registration functions in mcp-server/src/tools/.
Use snake_case for tool names exposed to MCP clients in server.addTool definitions.
Log the start of execution with arguments (sanitized if sensitive), log successful completion with result summary, log all error conditions with appropriate log levels, and include the cache status in result logs in MCP tool files.
Do not log entire large data structures or sensitive information in MCP tool files.
Use handleApiResult to format and return the response from MCP tools.

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.
For long-running operations that should not block the client, use the AsyncOperationManager in MCP tools and implement progress reporting.

Files:

  • mcp-server/src/tools/scope-up.js
mcp-server/src/{tools,core/direct-functions}/*.js

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

mcp-server/src/{tools,core/direct-functions}/*.js: Use kebab-case for all file names in mcp-server/src/tools/ and mcp-server/src/core/direct-functions/.
Use helpers from mcp-server/src/tools/utils.js, mcp-server/src/core/utils/path-utils.js, and mcp-server/src/core/utils/ai-client-utils.js for centralized utilities.

Files:

  • mcp-server/src/tools/scope-up.js
mcp-server/src/tools/**/*.js

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

MCP tool files in mcp-server/src/tools/ must call the corresponding direct function wrapper and pass the result to handleApiResult(result, log) from mcp-server/src/tools/utils.js, ensuring telemetryData is included in the final MCP response.

Files:

  • mcp-server/src/tools/scope-up.js
mcp-server/src/{core/utils,tools}/**/*.js

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

Place utilities specifically designed to support the MCP server implementation into the appropriate subdirectories within mcp-server/src/ (e.g., path/core logic helpers in mcp-server/src/core/utils/, tool execution/response helpers in mcp-server/src/tools/utils.js).

Files:

  • mcp-server/src/tools/scope-up.js
scripts/modules/supported-models.json

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

Add a new key for the provider and an array of model objects under it in scripts/modules/supported-models.json, including id, name, allowed_roles, and optionally swe_score, cost_per_1m_tokens, and max_tokens.

Files:

  • scripts/modules/supported-models.json
docs/**/*

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

Add feature documentation to '/docs' folder, include tagged system usage examples, update command reference documentation, and provide migration notes if relevant.

Files:

  • docs/models.md
🧠 Learnings (65)
📓 Common learnings
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/glossary.mdc:0-0
Timestamp: 2025-07-18T17:10:53.657Z
Learning: Guidelines for implementing and interacting with the Task Master MCP Server (mcp.mdc).
Learnt from: rtmcrc
Repo: eyaltoledano/claude-task-master PR: 933
File: mcp-server/src/tools/agent-llm.js:1-3
Timestamp: 2025-10-12T11:06:36.374Z
Learning: The agent_llm MCP tool in mcp-server/src/tools/agent-llm.js is an exception to the standard MCP tool pattern. It should NOT use handleApiResult because it handles delegated LLM calls rather than direct API calls. Using createErrorResponse for error messages is the correct approach for this tool.
Learnt from: rtmcrc
Repo: eyaltoledano/claude-task-master PR: 933
File: assets/rules/agentllm.mdc:57-60
Timestamp: 2025-10-15T18:18:36.402Z
Learning: In agentllm delegation mode, the `expand_all` tool returns a list of `delegatedTaskIds` that are eligible for expansion, and the MCP client must then call `expand_task` individually for each returned task ID. This differs from normal mode where `expand_all` automatically submits all eligible tasks for expansion without requiring subsequent `expand_task` calls.
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/glossary.mdc:0-0
Timestamp: 2025-07-18T17:10:53.657Z
Learning: Comprehensive reference for Taskmaster MCP tools and CLI commands with tagged task lists information (taskmaster.mdc).
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 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.
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/task-manager/*.js : Centralize all LLM calls through `generateTextService` or `generateObjectService`.
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: Applies to scripts/modules/ai-services-unified.js : Integrate the new provider module with scripts/modules/ai-services-unified.js by importing it and adding an entry to the PROVIDER_FUNCTIONS map.

Applied to files:

  • scripts/modules/ai-services-unified.js
  • src/ai-providers/index.js
  • packages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/ai-services-unified.js : Centralize all LLM calls through `generateTextService` or `generateObjectService`.

Applied to files:

  • scripts/modules/ai-services-unified.js
  • src/ai-providers/index.js
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: Applies to src/ai-providers/*.js : Provider modules must import the provider's create<ProviderName> function from ai-sdk/<provider-name>, and import generateText, streamText, generateObject from the core ai package, as well as the log utility from ../../scripts/modules/utils.js.

Applied to files:

  • scripts/modules/ai-services-unified.js
  • src/ai-providers/index.js
  • packages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/ai-services-unified.js : Do not fetch AI-specific parameters (model ID, max tokens, temp) using `config-manager.js` getters for the AI call. Pass the `role` instead.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/ai-services*.js : Ensure AI calls correctly handle and propagate telemetryData as described in 'telemetry.mdc'.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:18:17.759Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/utilities.mdc:0-0
Timestamp: 2025-07-18T17:18:17.759Z
Learning: Applies to scripts/modules/task-manager/**/*.js : Do not call AI-specific getters (like `getMainModelId`, `getMainMaxTokens`) from core logic functions in `scripts/modules/task-manager/*`; instead, pass the `role` to the unified AI service.

Applied to files:

  • scripts/modules/ai-services-unified.js
  • scripts/modules/supported-models.json
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/ai-services-unified.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/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/task-manager/*.js : Centralize all LLM calls through `generateTextService` or `generateObjectService`.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: Applies to src/ai-providers/*.js : Implement generate<ProviderName>Text, stream<ProviderName>Text, and generate<ProviderName>Object functions in provider modules with basic validation and try/catch error handling.

Applied to files:

  • scripts/modules/ai-services-unified.js
  • src/ai-providers/index.js
  • packages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/ai-services.js : Features that use AI models belong in 'scripts/modules/ai-services.js'.

Applied to files:

  • scripts/modules/ai-services-unified.js
  • src/ai-providers/index.js
📚 Learning: 2025-07-18T17:14:54.131Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/telemetry.mdc:0-0
Timestamp: 2025-07-18T17:14:54.131Z
Learning: Applies to scripts/modules/commands.js : CLI command definitions in scripts/modules/commands.js must call the appropriate core logic function with outputFormat: 'text', and must not call displayAiUsageSummary directly if the core logic function already handles it.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:14:54.131Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/telemetry.mdc:0-0
Timestamp: 2025-07-18T17:14:54.131Z
Learning: Applies to scripts/modules/task-manager/**/*.js : If the core logic function handles CLI output (outputFormat === 'text' or 'cli'), and aiServiceResponse.telemetryData is available, it must call displayAiUsageSummary(aiServiceResponse.telemetryData, 'cli') from scripts/modules/ui.js.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/*.js : Core functions should check outputFormat === 'text' before displaying UI elements and use internal logging that respects silent mode.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:11:36.732Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/mcp.mdc:0-0
Timestamp: 2025-07-18T17:11:36.732Z
Learning: Applies to mcp-server/src/core/direct-functions/*.js : Do not wrap calls to the unified AI service (generateTextService, generateObjectService) in silent mode; their logging is handled internally.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:14:54.131Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/telemetry.mdc:0-0
Timestamp: 2025-07-18T17:14:54.131Z
Learning: Applies to scripts/modules/task-manager/**/*.js : Functions in scripts/modules/task-manager/ that invoke AI services must call the appropriate AI service function (e.g., generateObjectService), passing commandName and outputType in the params object.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 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/ai-services-unified.js
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/commands.js : Do not fetch AI-specific parameters (model ID, max tokens, temp) using `config-manager.js` getters for the AI call. Pass the `role` instead.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-10-12T11:06:36.374Z
Learnt from: rtmcrc
Repo: eyaltoledano/claude-task-master PR: 933
File: mcp-server/src/tools/agent-llm.js:1-3
Timestamp: 2025-10-12T11:06:36.374Z
Learning: The agent_llm MCP tool in mcp-server/src/tools/agent-llm.js is an exception to the standard MCP tool pattern. It should NOT use handleApiResult because it handles delegated LLM calls rather than direct API calls. Using createErrorResponse for error messages is the correct approach for this tool.

Applied to files:

  • scripts/modules/ai-services-unified.js
  • mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: When assigning a model to a role using the MCP tool or CLI, do not include the provider: prefix in the model ID; use only the model ID itself.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-21T02:41:13.453Z
Learnt from: rtmcrc
Repo: eyaltoledano/claude-task-master PR: 933
File: scripts/modules/task-manager/expand-all-tasks.js:0-0
Timestamp: 2025-07-21T02:41:13.453Z
Learning: In scripts/modules/task-manager/expand-all-tasks.js, the success flag should always be true when the expansion process completes successfully, even if individual tasks fail due to LLM errors. Failed tasks are designed to be expanded on subsequent iterations, so individual task failures don't constitute overall operation failure.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-21T17:51:07.239Z
Learnt from: joedanz
Repo: eyaltoledano/claude-task-master PR: 748
File: scripts/modules/task-manager/parse-prd.js:726-733
Timestamp: 2025-07-21T17:51:07.239Z
Learning: In CLI contexts within task-manager modules like scripts/modules/task-manager/parse-prd.js, using process.exit(1) for validation failures and error conditions is correct and preferred over throwing errors, as it provides immediate termination with appropriate exit codes for scripting. The code should distinguish between MCP contexts (throw errors) and CLI contexts (use process.exit).

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-10-11T22:32:11.922Z
Learnt from: rtmcrc
Repo: eyaltoledano/claude-task-master PR: 933
File: mcp-server/src/providers/agentllm-provider-tool-executor.js:289-329
Timestamp: 2025-10-11T22:32:11.922Z
Learning: In the Taskmaster codebase, when detecting agent-llm pending-interaction signals in tool results (agentllm-provider-tool-executor.js), the data is always stored in content[0], so there's no need to loop through all content items.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/task-manager/*.js : Determine the appropriate `role` (`main`, `research`, `fallback`) in your core logic and pass it to the service.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 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 implement fallback or retry logic outside `ai-services-unified.js`.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:09:13.815Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/context_gathering.mdc:0-0
Timestamp: 2025-07-18T17:09:13.815Z
Learning: Commands such as `analyze-complexity`, `expand-task`, `update-task`, and `add-task` should consider adopting the context gathering pattern for improved AI-powered assistance.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 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 fetch AI-specific parameters (model ID, max tokens, temp) using `config-manager.js` getters for the AI call. Pass the `role` instead.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:13:11.229Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/self_improve.mdc:0-0
Timestamp: 2025-07-18T17:13:11.229Z
Learning: Patterns should be consistently enforced

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:07:39.336Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/architecture.mdc:0-0
Timestamp: 2025-07-18T17:07:39.336Z
Learning: Applies to src/ai-providers/*.js : Provider-specific wrappers for Vercel AI SDK functions must be implemented in src/ai-providers/*.js, each file corresponding to a provider.

Applied to files:

  • scripts/modules/ai-services-unified.js
  • src/ai-providers/index.js
  • packages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: Applies to src/ai-providers/*.js : Provider modules must export three functions: generate<ProviderName>Text, stream<ProviderName>Text, and generate<ProviderName>Object.

Applied to files:

  • scripts/modules/ai-services-unified.js
  • src/ai-providers/index.js
  • packages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: Applies to tests/unit/ai-providers/*.test.js : Create unit tests for the new provider in tests/unit/ai-providers/<provider-name>.test.js, mocking ai-sdk/<provider-name> and core ai module functions, and testing all exported functions for correct behavior and error handling.

Applied to files:

  • scripts/modules/ai-services-unified.js
  • src/ai-providers/index.js
  • packages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-09-29T13:33:46.952Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1246
File: src/ai-providers/claude-code.js:40-42
Timestamp: 2025-09-29T13:33:46.952Z
Learning: Claude Code provider should use environment variable isolation to control API key access, temporarily managing ANTHROPIC_API_KEY during client creation to prevent the ai-sdk-provider-claude-code package from automatically picking up API keys intended for other providers, while allowing explicit CLAUDE_CODE_API_KEY usage as a fallback to OAuth authentication.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: Applies to src/ai-providers/*.js : Create a new provider module file in src/ai-providers/ named <provider-name>.js when adding a new AI provider.

Applied to files:

  • scripts/modules/ai-services-unified.js
  • src/ai-providers/index.js
  • packages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-09-29T13:33:46.952Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1246
File: src/ai-providers/claude-code.js:40-42
Timestamp: 2025-09-29T13:33:46.952Z
Learning: Claude Code provider should use CLAUDE_CODE_API_KEY environment variable instead of automatically picking up ANTHROPIC_API_KEY to avoid conflicts, since the ai-sdk-provider-claude-code package follows standard Anthropic patterns and prioritizes API keys over OAuth authentication, which can cause unexpected API charges.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-10-31T18:07:17.384Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1360
File: src/ai-providers/glm.js:0-0
Timestamp: 2025-10-31T18:07:17.384Z
Learning: In src/ai-providers/glm.js, the GLM provider's getClient method should allow defaulting to the 'coding' endpoint when an invalid or unspecified route parameter is provided, as this is the correct behavior per Z.ai's OpenAI-compatible API documentation. Do not enforce strict route validation that throws errors for unknown routes.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:06:57.833Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_services.mdc:0-0
Timestamp: 2025-07-18T17:06:57.833Z
Learning: Applies to scripts/modules/commands.js : Determine the appropriate `role` (`main`, `research`, `fallback`) in your core logic and pass it to the service.

Applied to files:

  • scripts/modules/ai-services-unified.js
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: Applies to scripts/modules/config-manager.js : Update scripts/modules/config-manager.js to add the new provider to MODEL_MAP, ensure it is included in VALID_PROVIDERS, and update API key handling logic.

Applied to files:

  • src/ai-providers/index.js
  • scripts/modules/supported-models.json
  • packages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-09-26T19:05:47.555Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1252
File: packages/ai-sdk-provider-grok-cli/package.json:11-13
Timestamp: 2025-09-26T19:05:47.555Z
Learning: In the eyaltoledano/claude-task-master repository, internal tm/ packages use a specific export pattern where the "exports" field points to TypeScript source files (./src/index.ts) while "main" points to compiled output (./dist/index.js) and "types" points to source files (./src/index.ts). This pattern is used consistently across internal packages like tm/core and tm/ai-sdk-provider-grok-cli because they are consumed directly during build-time bundling with tsdown rather than being published as separate packages.

Applied to files:

  • src/ai-providers/index.js
📚 Learning: 2025-07-18T17:14:54.131Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/telemetry.mdc:0-0
Timestamp: 2025-07-18T17:14:54.131Z
Learning: Applies to mcp-server/src/tools/**/*.js : MCP tool files in mcp-server/src/tools/ must call the corresponding direct function wrapper and pass the result to handleApiResult(result, log) from mcp-server/src/tools/utils.js, ensuring telemetryData is included in the final MCP response.

Applied to files:

  • mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:11:36.732Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/mcp.mdc:0-0
Timestamp: 2025-07-18T17:11:36.732Z
Learning: Applies to mcp-server/src/core/direct-functions/*.js : Check that all helper functions your direct function needs are properly exported from their source modules and import these dependencies explicitly at the top of your file in direct functions.

Applied to files:

  • mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:11:36.732Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/mcp.mdc:0-0
Timestamp: 2025-07-18T17:11:36.732Z
Learning: Applies to mcp-server/src/{tools,core/direct-functions}/*.js : Use helpers from mcp-server/src/tools/utils.js, mcp-server/src/core/utils/path-utils.js, and mcp-server/src/core/utils/ai-client-utils.js for centralized utilities.

Applied to files:

  • mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to mcp-server/src/core/direct-functions/*.js : Create direct function wrappers in 'mcp-server/src/core/direct-functions/' for MCP tool implementation, following silent mode patterns and using findTasksJsonPath for consistent path resolution.

Applied to files:

  • mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:11:36.732Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/mcp.mdc:0-0
Timestamp: 2025-07-18T17:11:36.732Z
Learning: Applies to mcp-server/src/tools/*.js : All MCP tool execute methods that require access to the project root MUST be wrapped with the withNormalizedProjectRoot Higher-Order Function (HOF) from mcp-server/src/tools/utils.js.

Applied to files:

  • mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:07:39.336Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/architecture.mdc:0-0
Timestamp: 2025-07-18T17:07:39.336Z
Learning: Applies to mcp-server/src/tools/*.js : MCP server tools in mcp-server/src/tools/*.js must have their execute methods wrapped with the withNormalizedProjectRoot higher-order function from tools/utils.js to ensure consistent path handling.

Applied to files:

  • mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:18:17.759Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/utilities.mdc:0-0
Timestamp: 2025-07-18T17:18:17.759Z
Learning: Applies to mcp-server/src/tools/utils.js : Use `normalizeProjectRoot(rawPath, log)`, `getRawProjectRootFromSession(session, log)`, and `withNormalizedProjectRoot(executeFn)` in `mcp-server/src/tools/utils.js` to ensure project root paths are normalized for MCP tools.

Applied to files:

  • mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:11:36.732Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/mcp.mdc:0-0
Timestamp: 2025-07-18T17:11:36.732Z
Learning: Applies to mcp-server/src/core/direct-functions/*.js : The *Direct function is responsible for finding the exact tasks.json path using findTasksJsonPath, relying on the projectRoot passed in args.

Applied to files:

  • mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:13:30.188Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/tags.mdc:0-0
Timestamp: 2025-07-18T17:13:30.188Z
Learning: Applies to scripts/modules/task-manager/* : All core functions in scripts/modules/task-manager/ must use readJSON(tasksPath, projectRoot, tag) and writeJSON(tasksPath, data, projectRoot, tag)

Applied to files:

  • mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:18:17.759Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/utilities.mdc:0-0
Timestamp: 2025-07-18T17:18:17.759Z
Learning: Applies to mcp-server/src/core/utils/path-utils.js : Call `findTasksJsonPath(args, log)` from within direct function wrappers in `mcp-server/src/core/direct-functions/` to get the absolute path to the relevant `tasks.json`.

Applied to files:

  • mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:14:54.131Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/telemetry.mdc:0-0
Timestamp: 2025-07-18T17:14:54.131Z
Learning: Applies to scripts/modules/task-manager/**/*.js : Core logic functions in scripts/modules/task-manager/ must return an object that includes aiServiceResponse.telemetryData.

Applied to files:

  • mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:13:30.188Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/tags.mdc:0-0
Timestamp: 2025-07-18T17:13:30.188Z
Learning: Applies to scripts/modules/* : All commands must find projectRoot with error handling before proceeding

Applied to files:

  • mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T05:38:17.352Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 943
File: scripts/modules/task-manager/move-task.js:24-24
Timestamp: 2025-07-18T05:38:17.352Z
Learning: In the Claude Task Master system, core task-manager functions are designed with fallback mechanisms for missing projectRoot parameters using the pattern `const projectRoot = providedProjectRoot || findProjectRoot();`. The readJSON and writeJSON functions have default parameters (projectRoot = null, tag = null) and handle missing parameters gracefully. Adding strict validation to these core functions would break the established flexible architecture pattern.

Applied to files:

  • mcp-server/src/tools/scope-up.js
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: Applies to scripts/modules/supported-models.json : Add a new key for the provider and an array of model objects under it in scripts/modules/supported-models.json, including id, name, allowed_roles, and optionally swe_score, cost_per_1m_tokens, and max_tokens.

Applied to files:

  • scripts/modules/supported-models.json
  • docs/models.md
📚 Learning: 2025-07-21T14:14:48.694Z
Learnt from: rtmcrc
Repo: eyaltoledano/claude-task-master PR: 933
File: scripts/modules/supported-models.json:238-238
Timestamp: 2025-07-21T14:14:48.694Z
Learning: Model version updates in scripts/modules/supported-models.json may be included in feature PRs if they provide practical improvements like reduced error rates, even if not directly related to the main feature being implemented.

Applied to files:

  • scripts/modules/supported-models.json
  • docs/models.md
📚 Learning: 2025-08-08T11:34:45.482Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1105
File: .changeset/vast-weeks-fetch.md:5-5
Timestamp: 2025-08-08T11:34:45.482Z
Learning: In this repo, supported-models.md is auto-generated by CI from supported-models.json; do not request manual edits to that file—ensure JSON entries are correct instead.

Applied to files:

  • scripts/modules/supported-models.json
  • docs/models.md
📚 Learning: 2025-08-08T11:34:45.482Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1105
File: .changeset/vast-weeks-fetch.md:5-5
Timestamp: 2025-08-08T11:34:45.482Z
Learning: This repo’s supported models list is CI-generated into docs/models.md from scripts/modules/supported-models.json (workflow: .github/workflows/update-models-md.yml using docs/scripts/models-json-to-markdown.js). Don’t request manual edits to the Markdown; ensure the JSON is correct instead. README links to docs/models.md.

Applied to files:

  • scripts/modules/supported-models.json
  • docs/models.md
📚 Learning: 2025-08-08T11:34:45.482Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1105
File: .changeset/vast-weeks-fetch.md:5-5
Timestamp: 2025-08-08T11:34:45.482Z
Learning: In this repo, the supported models list is auto-generated by CI into docs/models.md from scripts/modules/supported-models.json via .github/workflows/update-models-md.yml and docs/scripts/models-json-to-markdown.js. Don’t request manual edits to the Markdown; ensure the JSON is correct instead.

Applied to files:

  • scripts/modules/supported-models.json
  • docs/models.md
📚 Learning: 2025-07-18T17:10:53.657Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/glossary.mdc:0-0
Timestamp: 2025-07-18T17:10:53.657Z
Learning: Guidelines for integrating new features into the Task Master CLI with tagged system considerations (new_features.mdc).

Applied to files:

  • scripts/modules/supported-models.json
📚 Learning: 2025-10-15T18:18:36.402Z
Learnt from: rtmcrc
Repo: eyaltoledano/claude-task-master PR: 933
File: assets/rules/agentllm.mdc:57-60
Timestamp: 2025-10-15T18:18:36.402Z
Learning: In agentllm delegation mode, the `expand_all` tool returns a list of `delegatedTaskIds` that are eligible for expansion, and the MCP client must then call `expand_task` individually for each returned task ID. This differs from normal mode where `expand_all` automatically submits all eligible tasks for expansion without requiring subsequent `expand_task` calls.

Applied to files:

  • scripts/modules/supported-models.json
📚 Learning: 2025-07-18T17:06:04.909Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/ai_providers.mdc:0-0
Timestamp: 2025-07-18T17:06:04.909Z
Learning: Update relevant documentation files (such as README.md) to mention the new provider and its configuration.

Applied to files:

  • packages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-08-06T21:12:20.981Z
Learnt from: Crunchyman-ralph
Repo: eyaltoledano/claude-task-master PR: 1091
File: assets/claude/agents/task-executor.md:1-6
Timestamp: 2025-08-06T21:12:20.981Z
Learning: In the eyaltoledano/claude-task-master repository, agent files in assets/claude/agents/ are intended for distribution to users (for copying), while identical files in .claude/agents/ are for internal project use. This intentional duplication serves different purposes and is not a DRY violation.

Applied to files:

  • packages/tm-core/src/common/constants/providers.ts
📚 Learning: 2025-07-18T17:13:11.229Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/self_improve.mdc:0-0
Timestamp: 2025-07-18T17:13:11.229Z
Learning: Document breaking changes

Applied to files:

  • docs/models.md
📚 Learning: 2025-09-24T15:12:58.855Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: assets/AGENTS.md:0-0
Timestamp: 2025-09-24T15:12:58.855Z
Learning: Applies to assets/.taskmaster/config.json : Never manually edit .taskmaster/config.json; use task-master models to change AI model settings

Applied to files:

  • docs/models.md
📚 Learning: 2025-07-18T17:10:12.881Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/dev_workflow.mdc:0-0
Timestamp: 2025-07-18T17:10:12.881Z
Learning: Applies to .taskmaster/config.json : Do not manually edit `.taskmaster/config.json` unless you are certain of the changes; use the `task-master models` command or `models` MCP tool for configuration.

Applied to files:

  • docs/models.md
📚 Learning: 2025-09-24T15:12:58.855Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: assets/AGENTS.md:0-0
Timestamp: 2025-09-24T15:12:58.855Z
Learning: Applies to assets/.taskmaster/tasks/tasks.json : Never manually edit .taskmaster/tasks/tasks.json; use task-master commands to modify tasks

Applied to files:

  • docs/models.md
📚 Learning: 2025-07-31T22:08:16.039Z
Learnt from: CR
Repo: eyaltoledano/claude-task-master PR: 0
File: .cursor/rules/taskmaster.mdc:0-0
Timestamp: 2025-07-31T22:08:16.039Z
Learning: Applies to {.taskmaster/tasks/tasks.json,.taskmaster/reports/task-complexity-report.json,.taskmaster/docs/research/**} : Do not manually edit generated files such as .taskmaster/tasks/tasks.json, .taskmaster/reports/task-complexity-report.json, or files in .taskmaster/docs/research/. Always use Taskmaster commands to modify these files.

Applied to files:

  • docs/models.md
🧬 Code graph analysis (2)
scripts/modules/ai-services-unified.js (5)
scripts/modules/config-manager.js (1)
  • providerName (718-718)
scripts/modules/commands.js (1)
  • commandName (148-148)
mcp-server/src/core/direct-functions/add-task.js (1)
  • tagInfo (146-146)
mcp-server/src/tools/utils.js (1)
  • tagInfo (298-298)
scripts/modules/task-manager/research.js (1)
  • tagInfo (315-315)
mcp-server/src/tools/scope-up.js (1)
mcp-server/src/core/direct-functions/scope-up.js (1)
  • result (82-97)
⏰ 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: Cursor Bugbot
🔇 Additional comments (12)
mcp-server/src/tools/scope-up.js (4)

8-17: LGTM!

Imports follow the established patterns and include the new createAgentDelegationResponse utility needed for agent delegation support.


23-55: LGTM!

Tool registration follows MCP conventions with snake_case naming, Zod parameter validation, and clear parameter descriptions.


56-92: LGTM!

The execute function correctly uses withNormalizedProjectRoot, logs execution start, resolves the tag context, finds the tasks path with proper error handling, and calls the direct function wrapper.


109-112: LGTM!

Error handling is appropriate with proper logging and use of createErrorResponse helper.

docs/models.md (1)

1-1: Do not manually edit this auto-generated file.

This file is automatically generated by CI from scripts/modules/supported-models.json. All changes should be made to the JSON source file instead, not directly to this Markdown file.

Based on learnings

Also applies to: 39-39, 107-107, 153-153, 183-183, 246-246

scripts/modules/ai-services-unified.js (3)

40-40: LGTM!

The AgentLLMProvider import and registration follow the established pattern for provider integration in this module.

Also applies to: 86-86


595-613: LGTM!

The enhanced skip logic with inline documentation clearly explains the workaround for agentllm in non-MCP contexts. The addition of the explanatory comment addresses maintainability concerns.


705-728: LGTM!

The delegation handling includes proper type validation, conditional debug logging, and returns a consistent structure with tagInfo. The implementation correctly propagates the delegation signal for MCP tool processing.

src/ai-providers/index.js (1)

18-18: LGTM!

The AgentLLMProvider export follows the established pattern for provider exports in this central index file.

packages/tm-core/src/common/constants/providers.ts (1)

33-33: LGTM!

The AGENTLLM provider constant addition follows the established naming convention and pattern for custom providers.

scripts/modules/supported-models.json (2)

381-381: LGTM!

The Gemini model version update to the May 20 preview provides practical error-reduction improvements as previously discussed.

Based on learnings


1199-1215: LGTM!

The agentllm provider entry is well-structured with comprehensive metadata:

  • Properly explains the delegation mechanism in description and notes fields
  • Correctly sets cost_per_1m_tokens to 0 (agent-determined costs)
  • Uses null for context_window and max_tokens (agent-determined capabilities)
  • Includes all three roles in allowed_roles for maximum flexibility
  • Extended metadata fields (supports_tools, supports_image_input) appropriately indicate agent-determined capabilities

The structure follows the required pattern and provides clear guidance for users about delegation behavior.

As per coding guidelines

@rtmcrc
Copy link
Copy Markdown
Author

rtmcrc commented Nov 2, 2025

Ok guys, i've made the corrections and resolved the conflicts and it is functional just like it was functional from the day this pr was created.
Unfortunately i won't be able to keep it up with the constantly evolving project so i leave it here now and you decide whether you merge it or recreate with a redesigned taskmaster architecture.
And as for those who want to test it you may always clone it from this branch in the current state.

@Crunchyman-ralph
Copy link
Copy Markdown
Collaborator

Hey @rtmcrc I've been seeing your efforts, and I'm impressed, let me give this a test, maybe we include it as part of next release. Thanks a ton! I've already created a branch locally for it, and will be testing it tomorrow. GGs!

}

// If both title+description are provided and AgentLLM is not preferred, take manual path as before.
const finalIsManualCreation = !isAgentLLMPreferred && isManualCreation;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Unwanted AI-Driven Creation Overrides Manual Task Intent

Silent behavior change when AgentLLM is configured: When a user calls add-task with title and description (intending manual task creation without AI), the code now synthesizes a prompt and forces AI-driven creation if AgentLLM is detected as the provider. This changes the intended behavior from manual to AI-driven creation without user consent. Lines 100-112 synthesize a prompt from title/description when AgentLLM is preferred, and line 115 sets finalIsManualCreation = false, overriding the user's explicit choice to create a task manually. This violates the principle of least surprise - users explicitly providing title/description without a prompt expect manual creation, not AI generation. The correct behavior would be to respect the user's original intent (manual vs AI-driven) regardless of which LLM provider is configured.

Fix in Cursor Fix in Web

Copy link
Copy Markdown
Author

@rtmcrc rtmcrc Nov 2, 2025

Choose a reason for hiding this comment

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

This may be discarded during the review. From my personal experience i was surprised that when i was making a add task requests i every time expected that when agentllm is set as a provider a prompt is generated but as it turned out llms were going manual path by default without even my realization. This workaround was made specially to agentllm only because when a user asks to add a task an llm may create a basic task filling those fields manually, but if a system prompt is passed in the response of add_task tool the result of a users request is going to be better.
This workaround maybe discarded and a rule created in agentllm.mdc for add_task tool to take AI driven path by default.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

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

⚠️ Outside diff range comments (6)
mcp-server/src/tools/add-task.js (1)

94-94: Fix typo in comment.

The comment contains a typo: "functionP" should be "function".

Apply this diff to fix the typo:

-				// Call the direct functionP
+				// Call the direct function
scripts/modules/utils.js (1)

760-769: Fix metadata merge: don’t spread metadata fields into tag root

Current merge flattens tag.metadata into root and may drop/duplicate fields (“updated” stays at root). Preserve tag object and overwrite only tasks (and metadata if provided).

- finalData = {
-   ...rawFullData,
-   [resolvedTag]: {
-     // Preserve existing tag metadata if it exists, otherwise use what's passed
-     ...(rawFullData[resolvedTag]?.metadata || {}),
-     ...(data.metadata ? { metadata: data.metadata } : {}),
-     tasks: data.tasks
-   }
- };
+ const existingTag = rawFullData[resolvedTag] || {};
+ finalData = {
+   ...rawFullData,
+   [resolvedTag]: {
+     ...existingTag,
+     tasks: data.tasks,
+     ...(data.metadata ? { metadata: data.metadata } : {})
+   }
+ };
scripts/modules/task-manager/generate-task-files.js (1)

67-75: Default tag handling: compute targetTag once and reuse safeTag

If options.tag is undefined, tagData = rawData[tag] is undefined. Derive targetTag = tag || resolvedData.tag || 'master' and reuse safeTag = slugifyTagForFilePath(targetTag) across logs/regex/filenames.

- const tagData = rawData[tag];
+ const targetTag = tag || resolvedData.tag || 'master';
+ const tagData = rawData[targetTag];
@@
- `Preparing to regenerate ${tasksForGeneration.length} task files for tag '${slugifyTagForFilePath(tag)}'`
+ `Preparing to regenerate ${tasksForGeneration.length} task files for tag '${slugifyTagForFilePath(targetTag)}'`
@@
- `Checking for orphaned task files to clean up for tag '${slugifyTagForFilePath(tag)}'...`
+ `Checking for orphaned task files to clean up for tag '${slugifyTagForFilePath(targetTag)}'...`
@@
- const taggedFilePattern = new RegExp(
-   `^task_(\\d+)_${slugifyTagForFilePath(tag)}\\.txt$`
- );
+ const taggedFilePattern = new RegExp(
+   `^task_(\\d+)_${slugifyTagForFilePath(targetTag)}\\.txt$`
+ );
@@
- `Found ${orphanedFiles.length} orphaned task files to remove for tag '${slugifyTagForFilePath(tag)}'`
+ `Found ${orphanedFiles.length} orphaned task files to remove for tag '${slugifyTagForFilePath(targetTag)}'`
@@
- `Generating individual task files for tag '${slugifyTagForFilePath(tag)}'...`
+ `Generating individual task files for tag '${slugifyTagForFilePath(targetTag)}'...`
@@
- tag === 'master'
+ targetTag === 'master'
@@
- : `task_${task.id.toString().padStart(3, '0')}_${slugifyTagForFilePath(tag)}.txt`;
+ : `task_${task.id.toString().padStart(3, '0')}_${slugifyTagForFilePath(targetTag)}.txt`;
@@
- `All ${tasksForGeneration.length} tasks for tag '${slugifyTagForFilePath(tag)}' have been generated into '${outputDir}'.`
+ `All ${tasksForGeneration.length} tasks for tag '${slugifyTagForFilePath(targetTag)}' have been generated into '${outputDir}'.`

Also applies to: 80-84, 97-103, 107-109, 156-160, 164-167, 224-228

scripts/modules/dependency-manager.js (2)

62-70: Make the initial validation tag-aware (don’t check root data.tasks).

The check can fail for tagged data. Validate the tag-scoped array instead and include the tag in the error.

Based on learnings

- const data = readJSON(tasksPath, context.projectRoot, context.tag);
- if (!data || !data.tasks) {
-   log('error', 'No valid tasks found in tasks.json');
-   process.exit(1);
- }
-
- const tag = context.tag || 'master';
- const tasks = getTasksForTag(data, tag);
+ const data = readJSON(tasksPath, context.projectRoot, context.tag);
+ const tag = context.tag || 'master';
+ const tasks = getTasksForTag(data, tag);
+ if (!data || !Array.isArray(tasks)) {
+   log('error', `No valid tasks found for tag '${tag}' in tasks.json`);
+   process.exit(1);
+ }

1334-1338: Fix logger wiring for traverseDependencies (current code falls back to console.warn).

log is a function, so log.warn is undefined. Pass a wrapper.

- return traverseDependencies(sourceTasks, allTasks, {
-   ...options,
-   direction: 'forward',
-   logger: { warn: log.warn || console.warn }
- });
+ return traverseDependencies(sourceTasks, allTasks, {
+   ...options,
+   direction: 'forward',
+   logger: { warn: (...args) => log('warn', ...args) }
+ });

Apply the same wrapper in other calls (e.g., reverse traversal).

Also applies to: 1538-1542

mcp-server/src/tools/research.js (1)

55-66: Restore backward compatibility for saveTo

Renaming the public parameter to saveToTask without keeping saveTo in the schema will reject every existing MCP client that still sends the old field—the Zod validator fails before the fallback args.saveTo ever runs. Please accept both keys (mark the legacy one deprecated in docs if needed) so previously working clients don’t break.

 			saveToTask: z
 				.string()
 				.optional()
 				.describe(
 					'Automatically save research results to specified task/subtask ID (e.g., "15" or "15.2")'
 				),
+			// Back-compat: accept legacy saveTo until all clients migrate.
+			saveTo: z
+				.string()
+				.optional()
+				.describe(
+					'(Deprecated) Legacy alias for saveToTask; kept for backward compatibility.'
+				),

As per coding guidelines

♻️ Duplicate comments (2)
tests/unit/mcp-server/src/tools/agent_llm.tool.test.js (1)

292-299: Don’t spy on a literal { execute } object; remove or rewrite schema tests

This spy pattern doesn’t track the real function and was flagged earlier; schema validation happens before execute.

- const executeSpy = jest.spyOn({ execute }, 'execute');
- try {
-   await execute(args, { log: mockLog, session: mockSession });
- } catch (e) {}
- expect(executeSpy).not.toHaveBeenCalled();
+ // Schema validation is handled by the MCP framework pre-execute.
+ // Placeholder to document expected rejection.
+ expect(true).toBe(true);

Also applies to: 310-317

mcp-server/src/core/direct-functions/research.js (1)

68-288: Switch to the shared error codes

The direct-function rules still require the canonical codes (INPUT_VALIDATION_ERROR, CORE_FUNCTION_ERROR, FILE_NOT_FOUND_ERROR, UNEXPECTED_ERROR). This file continues to emit custom strings (MISSING_PARAMETER, INVALID_PARAMETER, INVALID_CORE_RESPONSE, RESEARCH_ERROR), so callers can’t rely on the standardized contract. Please map each branch to the shared constants (and do the same for the catch block).

-				error: {
-					code: 'MISSING_PARAMETER',
+				error: {
+					code: 'INPUT_VALIDATION_ERROR',
 					message:
 						'The query parameter is required and must be a non-empty string'
 				}
 ...
-				error: {
-					code: 'INVALID_PARAMETER',
+				error: {
+					code: 'INPUT_VALIDATION_ERROR',
 					message: `Detail level must be one of: ${validDetailLevels.join(', ')}`
 				}
 ...
-				error: {
-					code: 'INVALID_CORE_RESPONSE',
+				error: {
+					code: 'CORE_FUNCTION_ERROR',
 					message: 'Core research function returned invalid data.'
 				}
 ...
-			error: {
-				code: error.code || 'RESEARCH_ERROR',
+			error: {
+				code:
+					error.code === 'INPUT_VALIDATION_ERROR' ||
+					error.code === 'FILE_NOT_FOUND_ERROR' ||
+					error.code === 'CORE_FUNCTION_ERROR'
+						? error.code
+						: 'UNEXPECTED_ERROR',
 				message: error.message
 			}

As per coding guidelines

🧹 Nitpick comments (4)
tests/unit/scripts/modules/task-manager/generate-task-files.test.js (1)

49-52: Align slugifyTagForFilePath mock with prod behavior to avoid test drift

Mirror prod: trim leading/trailing dashes, collapse repeats, cap length, default 'unknown-tag'.

- slugifyTagForFilePath: jest.fn((tag) =>
-   tag ? tag.replace(/[^a-zA-Z0-9_-]/g, '-').toLowerCase() : 'master'
- )
+ slugifyTagForFilePath: jest.fn((tag) => {
+   if (!tag || typeof tag !== 'string') return 'unknown-tag';
+   return tag
+     .replace(/[^a-zA-Z0-9_-]/g, '-')
+     .replace(/^-+|-+$/g, '')
+     .replace(/-+/g, '-')
+     .toLowerCase()
+     .substring(0, 50);
+ })
tests/unit/mcp-server/src/tools/agent_llm.tool.test.js (1)

270-281: Avoid asserting exact error strings; assert general properties

Per testing guidelines, prefer shape over exact text.

- expect(utilsModule.createErrorResponse).toHaveBeenCalledWith(
-   "Invalid parameters for agent_llm tool: Must provide either 'delegatedCallDetails' or 'agentLLMResponse'.",
-   { mcpToolError: true }
- );
- expect(result.isError).toBe(true);
- expect(result.errorDetails).toContain(
-   'Invalid parameters for agent_llm tool'
- );
+ expect(utilsModule.createErrorResponse).toHaveBeenCalled();
+ expect(result.isError).toBe(true);
+ expect(result.mcpToolError).toBe(true);

As per coding guidelines

mcp-server/src/core/utils/agentllm-update-tool-saver.js (1)

10-43: Optional: normalize logger methods to no-ops for cleaner debug usage

Avoid guarded calls by binding fallbacks once.

- if (typeof agentOutput === 'string') {
+ if (typeof agentOutput === 'string') {
+   const dbg =
+     logWrapper && typeof logWrapper.debug === 'function'
+       ? logWrapper.debug.bind(logWrapper)
+       : () => {};
@@
-  logWrapper.debug &&
-    logWrapper.debug(`${this.toolName}: Direct JSON.parse failed: ${e.message}`);
+  dbg(`${this.toolName}: Direct JSON.parse failed: ${e.message}`);
@@
-  logWrapper.debug &&
-    logWrapper.debug(`${this.toolName}: Substring array parse failed: ${e.message}`);
+  dbg(`${this.toolName}: Substring array parse failed: ${e.message}`);
@@
-  logWrapper.debug &&
-    logWrapper.debug(`${this.toolName}: Substring object parse failed: ${e.message}`);
+  dbg(`${this.toolName}: Substring object parse failed: ${e.message}`);

Also applies to: 55-61, 75-83

mcp-server/src/providers/agentllm-provider-tool-executor.js (1)

22-25: Use computed tag for default tagInfo to avoid mismatches.

If agent didn’t return tagInfo, prefer the computed tag instead of hardcoding 'master'.

- return {
+ return {
   mainResult: mainResultMessage,
   telemetryData: null,
-  tagInfo: llmRequestForAgent?.requestParameters?.tagInfo || {
-    currentTag: 'master',
-    availableTags: ['master']
-  }
+  tagInfo:
+    llmRequestForAgent?.requestParameters?.tagInfo || {
+      currentTag: tag,
+      availableTags: [tag]
+    }
 }

Also applies to: 333-341

Comment thread scripts/modules/dependency-manager.js
Comment thread scripts/modules/task-manager/research.js Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

Caution

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

⚠️ Outside diff range comments (1)
scripts/modules/dependency-manager.js (1)

62-66: Validate tasks array from getTasksForTag, not data.tasks directly.

The check !data || !data.tasks at line 63 assumes legacy format and doesn't work with tagged data structure. Line 69 correctly uses getTasksForTag, but the validation should check the returned tasks array instead.

Apply this fix:

 	const data = readJSON(tasksPath, context.projectRoot, context.tag);
-	if (!data || !data.tasks) {
-		log('error', 'No valid tasks found in tasks.json');
-		process.exit(1);
-	}
-
 	const tag = context.tag || 'master';
 	const tasks = getTasksForTag(data, tag);
+	if (!data || !Array.isArray(tasks) || tasks.length === 0) {
+		log('error', 'No valid tasks found in tasks.json');
+		process.exit(1);
+	}

This pattern aligns with how fixDependenciesCommand validates at lines 744-746.

Also applies to: 254-260

♻️ Duplicate comments (1)
tests/unit/mcp-server/src/tools/agent_llm.tool.test.js (1)

278-313: Schema validation tests need revision or removal.

These tests create spies on object literals which doesn't properly track the execute function. Since validation occurs in the MCP framework before execute is called, these tests don't meaningfully verify behavior in this isolated environment.

Consider either:

  1. Removing these tests with a comment explaining validation is handled by the MCP framework
  2. Rewriting to actually test validation behavior if that's possible
🧹 Nitpick comments (3)
mcp-server/src/providers/agentllm-provider-tool-executor.js (1)

13-341: Post-processing handles diverse tool outputs.

The function properly:

  • Resolves tags with getCurrentTag fallback and guard against undefined projectRoot (line 24)
  • Routes to appropriate savers with normalized inputs
  • Handles special cases like research text extraction (lines 211-236) and saveTo sanitization (lines 243-256)
  • Validates IDs for scope tools (lines 282-286, 308-312)

The if-else chain is verbose but each branch has distinct normalization needs. Extracting to a handler map would require significant refactoring and may not improve clarity given the heterogeneous requirements.

Optional: Consider handler map for maintainability.

If this function grows further, extracting tool-specific logic into a handler mapping could improve maintainability:

const toolHandlers = {
  parse_prd: async (params) => { /* ... */ },
  expand_task: async (params) => { /* ... */ },
  // ...
};

This is optional as the current structure is functional and each branch has unique logic.

scripts/modules/task-manager/research.js (1)

278-327: Consider debug level for verbose logging in production.

Lines 278-327 use info level for detailed type checks, object inspection, and content previews. While valuable during development, this verbosity may clutter production logs.

Optionally adjust log levels for detail-heavy messages:

-		logFn.info(`performResearch: generateTextService call completed.`);
-		logFn.info(`performResearch: aiResult raw: ${JSON.stringify(aiResult)}`);
+		logFn.debug(`performResearch: generateTextService call completed.`);
+		logFn.debug(`performResearch: aiResult raw: ${JSON.stringify(aiResult)}`);

Apply similar changes to lines 281-299, 317-327 to reduce production log volume while preserving debug capability.

tests/unit/dependency-manager.test.js (1)

1037-1040: Consider removing unused tag property for clarity.

The mock returns { tasks: [...], tag: 'master' }, but the tag property at the root level doesn't appear to be used by getTasksForTag or other code. The mock works correctly because getTasksForTag checks data.tasks first, but including the unused property may cause confusion.

Apply this diff to simplify the mock:

-mockReadJSON.mockImplementation(() => ({
-    tasks: structuredClone(crossLevelDependencyTasks.tasks),
-    tag: 'master'
-}));
+mockReadJSON.mockImplementation(() => ({
+    tasks: structuredClone(crossLevelDependencyTasks.tasks)
+}));

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
scripts/modules/task-manager/research.js (1)

149-176: Preserve subtask identifiers when displaying sorted task IDs.

Sorting via parseInt strips everything after the dot (parseInt('15.2') === 15), so subtask IDs are shown as their parent task. Users will see “15” even if the match was “15.2”, which is misleading when they try to act on the referenced subtask.

Switch to a numeric-aware string compare so the full ID survives:

-					const sortedTaskIds = finalTaskIds
-						.map((id) => parseInt(id))
-						.sort((a, b) => a - b)
-						.map((id) => id.toString());
+					const sortedTaskIds = finalTaskIds
+						.map((id) => id.toString())
+						.sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
@@
-						const sortedProvidedIds = taskIds
-							.map((id) => parseInt(id))
-							.sort((a, b) => a - b)
-							.map((id) => id.toString());
+						const sortedProvidedIds = taskIds
+							.map((id) => id.toString())
+							.sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
@@
-							const sortedAutoIds = uniqueAutoDiscovered
-								.map((id) => parseInt(id))
-								.sort((a, b) => a - b)
-								.map((id) => id.toString());
+							const sortedAutoIds = uniqueAutoDiscovered
+								.map((id) => id.toString())
+								.sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
♻️ Duplicate comments (1)
tests/unit/mcp-server/src/tools/agent_llm.tool.test.js (1)

280-322: Schema validation tests are correctly implemented.

Contrary to the past review comment, these tests appropriately use safeParse to directly test the Zod schema validation. Since schema validation occurs in the MCP framework before execute is invoked, testing the schema itself (rather than trying to spy on execute) is the correct unit testing approach. These tests effectively document expected validation behavior.

🧹 Nitpick comments (1)
tests/unit/mcp-server/src/tools/agent_llm.tool.test.js (1)

82-322: Consider adding test coverage for the optional tag parameter.

The current tests provide strong coverage of core delegation flows. As an optional enhancement, consider adding a test that includes the tag parameter to verify it's properly handled in both Taskmaster-to-Agent and Agent-to-Taskmaster flows, ensuring the multi-context routing feature is testable.

Comment thread tests/unit/dependency-manager.test.js Outdated
…deduplication.

research: correct numerical sorting of task IDs
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
tests/unit/dependency-manager.test.js (2)

20-53: Consider adding getTasksForTag and setTasksForTag to the global mock setup.

The cross-level dependency test suite (lines 1010–1021) mocks getTasksForTag and setTasksForTag, but these are absent from the global mock setup. If the module under test or other test suites invoke these utilities, they will encounter undefined function errors. For consistency and to prevent fragile test ordering, export these mocks at the top level alongside the other utility mocks.

Apply this diff to add the missing mocks to the global setup:

 	isEmpty: jest.fn((v) =>
 		v == null
 			? true
 			: Array.isArray(v)
 				? v.length === 0
 				: typeof v === 'object'
 					? Object.keys(v).length === 0
 					: false
 	),
 	// Common extras
 	enableSilentMode: jest.fn(),
 	disableSilentMode: jest.fn(),
 	getTaskManager: jest.fn(async () => ({})),
 	getTagAwareFilePath: jest.fn((basePath, _tag, projectRoot = '.') => basePath),
 	readComplexityReport: jest.fn(() => null),
 	createLogger: jest.fn(() => ({
 		debug: jest.fn(),
 		error: jest.fn(),
 		info: jest.fn(),
 		success: jest.fn(),
 		warn: jest.fn()
-	}))
+	})),
+	getTasksForTag: jest.fn((data, tag) => {
+		if (data.tasks && Array.isArray(data.tasks)) {
+			return data.tasks;
+		}
+		return data[tag]?.tasks || [];
+	}),
+	setTasksForTag: jest.fn((data, tag, tasks) => {
+		if (!data[tag]) data[tag] = {};
+		data[tag].tasks = tasks;
+	})
 }));

1034-1036: Data structure inconsistency between test suites may cause confusion.

The cross-level dependency tests use a flat { tasks: [...] } structure (line 1034), while other tests in this file use the tagged { master: { tasks: [...] } } structure (e.g., lines 651–669). The getTasksForTag mock (lines 1010–1017) bridges both formats with fallback logic, but this dual-mode approach can make it harder to reason about test behavior and could mask issues where code incorrectly assumes one structure or the other.

Consider standardizing all tests to use the tagged structure for consistency, or document why the cross-level tests require the flat structure.

Also applies to: 1010-1017

…sertion

- Add mocks for getTasksForTag and setTasksForTag functions
- Update test to include independent subtask and correct assertion for deduplicated dependencies
- Format research.js sort function for readability
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
scripts/modules/task-manager/research.js (1)

277-299: Verbose logging persists at info level.

The detailed logging of AI result types and content previews remains at info level, which can be too verbose for production. This was flagged in a previous review.

Consider changing these detailed log statements from logFn.info to logFn.debug:

-		logFn.debug(`performResearch: generateTextService call completed.`);
-		logFn.debug(`performResearch: aiResult raw: ${JSON.stringify(aiResult)}`);
+		logFn.debug(`performResearch: generateTextService call completed.`);
+		logFn.debug(`performResearch: aiResult raw: ${JSON.stringify(aiResult)}`);

The logFn.debug calls are already at debug level, but consider whether the content preview logging (lines 290-293) should also be at debug level for production.

🧹 Nitpick comments (2)
tests/unit/dependency-manager.test.js (1)

1013-1032: Consider extracting duplicate mock setup to reduce maintenance burden.

The mock factory functions (createLogger, getTasksForTag, setTasksForTag) are duplicated between the top-level jest.mock() (lines 46-62) and this beforeEach block. Extract them to a shared factory:

+// Shared mock factory
+const createUtilsMockFactory = () => ({
+  createLogger: jest.fn(() => ({
+    debug: jest.fn(),
+    error: jest.fn(),
+    info: jest.fn(),
+    success: jest.fn(),
+    warn: jest.fn()
+  })),
+  getTasksForTag: jest.fn((data, tag) => {
+    if (data.tasks && Array.isArray(data.tasks)) {
+      return data.tasks;
+    }
+    return data[tag]?.tasks || [];
+  }),
+  setTasksForTag: jest.fn((data, tag, tasks) => {
+    if (!data[tag]) data[tag] = {};
+    data[tag].tasks = tasks;
+  }),
+  readComplexityReport: jest.fn(() => null)
+});

 jest.mock('../../scripts/modules/utils.js', () => ({
   log: mockLog,
   ...
-  createLogger: jest.fn(() => ({ ... })),
-  getTasksForTag: jest.fn(...),
+  ...createUtilsMockFactory()
 }));

Then reuse in the unstable_mockModule call.

scripts/modules/task-manager/research.js (1)

1101-1101: Optional: Remove unused timestamp variable.

The timestamp variable is defined but not used in the output string (line 1102 inline constructs the timestamp again).

Consider removing the unused variable:

-	// const timestamp = new Date().toISOString(); // Not currently used in output string
 	let formatted = `## Research Session - ${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}\n\n`;

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

This PR is being reviewed by Cursor Bugbot

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

// Indicates successful non-delegated expansion
const subtasksAdded = coreResult.task.subtasks
? coreResult.task.subtasks.length - subtasksCountBefore
: 0 - subtasksCountBefore; // If subtasks became undefined (unlikely)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Arithmetic Error: Negative Instead of Zero

Incorrect arithmetic calculation: when coreResult.task.subtasks is falsy, subtasksAdded is set to 0 - subtasksCountBefore. This produces a negative number instead of 0. For example, if subtasksCountBefore is 2 and subtasks become undefined, the result is -2, which is semantically incorrect for counting added subtasks. It should be 0.

Fix in Cursor Fix in Web

@Crunchyman-ralph
Copy link
Copy Markdown
Collaborator

@rtmcrc I'm handling the conflicts, don't worry about it

@Crunchyman-ralph
Copy link
Copy Markdown
Collaborator

This was an ambitious contribution, delegating LLM calls via MCP is a cool concept.

The codebase has changed dramatically since this was opened (92 files touched tells the story), and it would need a ground-up rewrite to align with the current architecture.

Going to close this, but the idea has merit. If you're still interested, we'd be happy to discuss the approach in an issue before you invest time in a new PR. Thanks for the effort!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants