Skip to content

fix: resolve deprecated transitive dependencies#1671

Open
withsivram wants to merge 2 commits intoeyaltoledano:mainfrom
withsivram:fix/deprecated-dependencies-issue-1624
Open

fix: resolve deprecated transitive dependencies#1671
withsivram wants to merge 2 commits intoeyaltoledano:mainfrom
withsivram:fix/deprecated-dependencies-issue-1624

Conversation

@withsivram
Copy link
Copy Markdown

@withsivram withsivram commented Mar 22, 2026

Summary

  • Adds npm overrides for gaxios (^7.1.4) and rimraf (^6.0.0) to eliminate deprecated transitive dependency warnings during npm install
  • gaxios@7.1.4 drops rimraf from its dependencies, which removes the rimraf@5 -> glob@10.5.0 chain
  • koa-router, keygrip, and node-domexception were already absent in the current dependency tree (mcp-proxy@5 has no pipenet dependency, and the existing node-fetch@2 override prevents node-domexception)

Fixes #1624

Test plan

  • Verified npm ls shows no koa-router, keygrip, node-domexception, or rimraf in the dependency tree
  • Verified glob@10.5.0 is no longer present in production dependencies (only remains in dev-only packages like jest, mocha, @vscode/test-cli)
  • Verified gaxios resolves to 7.1.4 (which has no rimraf dependency)
  • Build passes (npm run build)
  • No new test failures (pre-existing test failures are identical to main)
  • Fresh npm install -g task-master-ai produces no deprecated warnings for the four packages listed in the issue

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Tasks can now be moved across tags even with conflicting IDs—the system automatically renumbers conflicts and updates all related dependencies accordingly.
  • Bug Fixes

    • Task dependencies are now properly reconciled and updated when renumbering occurs during cross-tag moves.
  • Chores

    • Updated package overrides for additional dependencies.

withsivram and others added 2 commits March 20, 2026 12:47
…ixes eyaltoledano#1647)

When moving tasks between tags, if a task's ID already exists in the
target tag, the task is now automatically renumbered to the next
available ID instead of throwing an error. Dependencies within the
moved batch are updated to reflect the new IDs.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
)

Add npm overrides for `gaxios` (>=7.1.4) and `rimraf` (>=6.0.0) to
eliminate deprecated transitive dependencies that produce warnings
during installation:

- glob@10.5.0: removed by upgrading gaxios to 7.1.4 (drops rimraf dep)
- rimraf@5.0.10: no longer pulled in transitively
- koa-router@14.0.0 and keygrip@1.1.0: already absent in current
  mcp-proxy@5.x (no pipenet dependency)
- node-domexception@1.0.0: already resolved by existing node-fetch@2
  override

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 22, 2026 06:54
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 22, 2026

⚠️ No Changeset found

Latest commit: 8f39ee0

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

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

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 22, 2026

📝 Walkthrough

Walkthrough

The PR implements automatic ID collision resolution during cross-tag task moves. When a task's ID conflicts with an existing task in the target tag, the system now renumbers the moved task to the next available ID instead of throwing an error, updates all dependency references accordingly, and reports the changes in the response message. Package overrides for gaxios and rimraf are added to address deprecated transitive dependencies.

Changes

Cohort / File(s) Summary
Core move-task logic
scripts/modules/task-manager/move-task.js
Implements automatic ID collision resolution: adds getNextAvailableId() function to compute next available ID, replaces TASK_ALREADY_EXISTS error with renumbering logic, records id remappings in result structure, updates dependency references in moved tasks and subtasks, performs batch-wide dependency reconciliation, and enhances finalizeMove() to include renumbering summary and validation tip in response.
Direct function response formatting
mcp-server/src/core/direct-functions/move-task-cross-tag.js
Updates success response message to dynamically include renumbering information with "Renumbered to avoid ID collisions" suffix and originalId → newId mappings when applicable.
Integration test
tests/integration/move-task-cross-tag.integration.test.js
Refactors collision test to expect successful renumbering instead of TASK_ALREADY_EXISTS error; verifies result contains renumbering info, validates movedTasks includes originalId/newId entries, and confirms target tag contains both existing and renumbered tasks.
Package configuration
package.json
Adds gaxios@^7.1.4 and rimraf@^6.0.0 to overrides to resolve deprecated transitive dependencies.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • Crunchyman-ralph
🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (2 warnings, 1 inconclusive)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title only addresses deprecated transitive dependencies, but the changeset includes substantial task renumbering logic unrelated to dependency fixes. Update the title to reflect both changes, such as: 'fix: prevent task ID collisions and resolve deprecated transitive dependencies'
Out of Scope Changes check ⚠️ Warning The PR includes extensive task renumbering logic (move-task.js +123/-16 lines, test changes) that is not mentioned in the PR objectives about resolving deprecated dependencies. Either document how task renumbering relates to the deprecated dependencies objective, or separate it into a different PR aligned with issue #1647.
Linked Issues check ❓ Inconclusive Package.json changes directly address #1624 by adding gaxios and rimraf overrides. However, the task renumbering changes (move-task.js, move-task-cross-tag.js, tests) appear unrelated to the linked issue about deprecated dependencies. Clarify whether the task renumbering changes should be part of this PR or split into a separate PR addressing issue #1647.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR aims to eliminate deprecated transitive dependency warnings during npm install by adding npm overrides, and it also changes cross-tag move behavior to auto-renumber tasks on ID collisions (with corresponding test/MCP response updates).

Changes:

  • Add npm overrides for gaxios and rimraf in package.json.
  • Auto-renumber tasks during cross-tag moves when the target tag already contains the requested ID, and attempt to remap dependencies accordingly.
  • Update integration test expectations for ID-collision behavior.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 5 comments.

File Description
package.json Adds dependency overrides intended to remove deprecated transitive packages from the install tree.
scripts/modules/task-manager/move-task.js Implements auto-renumbering on ID collisions and post-move dependency remapping.
mcp-server/src/core/direct-functions/move-task-cross-tag.js Adjusts MCP direct-function response message to include renumbering details.
tests/integration/move-task-cross-tag.integration.test.js Updates integration test to expect successful move with renumbering instead of an error.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +955 to +963
if (movedTask && Array.isArray(movedTask.dependencies)) {
movedTask.dependencies = movedTask.dependencies.map((dep) => {
const normalizedDep = normalizeDependency(dep);
if (
Number.isFinite(normalizedDep) &&
idRemapping.has(normalizedDep)
) {
return idRemapping.get(normalizedDep);
}
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

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

When updating dependencies after renumbering, this mapping loses information for dotted subtask references. For example, a dependency like "5.2" normalizes to parent 5, matches idRemapping, and then gets replaced with the numeric new ID only—dropping the ".2" suffix and changing the dependency meaning. The remap logic should preserve dotted dependencies by rewriting only the parent portion (and ideally preserve original string/number format).

Copilot uses AI. Check for mistakes.
Comment on lines +971 to +978
subtask.dependencies = subtask.dependencies.map((dep) => {
const normalizedDep = normalizeDependency(dep);
if (
Number.isFinite(normalizedDep) &&
idRemapping.has(normalizedDep)
) {
return idRemapping.get(normalizedDep);
}
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

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

Subtask dependency remapping has the same issue as task-level dependencies: normalizeDependency("5.2") returns 5, so a remap will replace the entire string with the numeric new ID and drop the subtask portion. This can corrupt subtask-to-subtask or task-to-subtask dependency references after renumbering; update logic should rewrite the parent task ID while keeping any subtask suffix intact (and keep string deps as strings where applicable).

Copilot uses AI. Check for mistakes.
Comment on lines +120 to +129
// Check if any tasks were renumbered during the move
const renumberedTasks = (result.movedTasks || []).filter(
(t) => t.newId !== undefined
);
let message = `Successfully moved ${sourceIds.length} task(s) from "${args.sourceTag}" to "${args.targetTag}"`;
if (renumberedTasks.length > 0) {
const renumberDetails = renumberedTasks
.map((t) => `${t.originalId} → ${t.newId}`)
.join(', ');
message += `. Renumbered to avoid ID collisions: ${renumberDetails}`;
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

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

This success message uses sourceIds.length, which will be incorrect when --with-dependencies expands the move set (core can move more tasks than were explicitly requested). Consider using result.movedTasks.length (or just result.message from core) so the MCP response stays accurate.

Copilot uses AI. Check for mistakes.
Comment on lines 149 to +153
"overrides": {
"node-fetch": "^2.6.12",
"whatwg-url": "^11.0.0"
"whatwg-url": "^11.0.0",
"gaxios": "^7.1.4",
"rimraf": "^6.0.0"
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

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

The PR title/description focus on dependency override cleanup, but this change set also introduces functional behavior changes (auto-renumbering tasks on cross-tag ID collisions) and updates related tests/MCP responses. Please either update the PR description/title to cover the move-task behavior change (and its user-facing impact) or split the functional change into a separate PR to keep scope clear.

Copilot uses AI. Check for mistakes.
"node-fetch": "^2.6.12",
"whatwg-url": "^11.0.0"
"whatwg-url": "^11.0.0",
"gaxios": "^7.1.4",
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

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

Adding a top-level override for gaxios forces version selection even for transitive dependents that declare an incompatible major range (e.g., package-lock shows gcp-metadata declares "gaxios": "^6.1.1"). This can cause subtle runtime breakage despite a clean install. Prefer a more targeted override (scoped to the specific dependency chain) or bump the direct dependency that brings in gaxios, and ensure the lockfile is regenerated/committed so CI/users resolve the same tree.

Suggested change
"gaxios": "^7.1.4",

Copilot uses AI. Check for mistakes.
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.

🧹 Nitpick comments (4)
mcp-server/src/core/direct-functions/move-task-cross-tag.js (2)

204-215: Error handler for TASK_ALREADY_EXISTS is now unreachable for cross-tag moves.

With the auto-renumbering behavior, cross-tag moves no longer throw TASK_ALREADY_EXISTS. This error handling block (lines 204-215) is effectively dead code for the moveTaskCrossTagDirect function.

Consider removing or updating these suggestions since the primary advice ("Choose a different target tag without conflicting IDs") no longer applies — conflicts are now resolved automatically.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mcp-server/src/core/direct-functions/move-task-cross-tag.js` around lines 204
- 215, The TASK_ALREADY_EXISTS error branch in moveTaskCrossTagDirect is now
dead due to auto-renumbering; remove or update the branch that checks error.code
=== 'TASK_ALREADY_EXISTS' || error.message?.includes('already exists in target
tag') and stop setting errorCode = 'TASK_ALREADY_EXISTS' and the suggestions
array there; either delete the entire conditional block or replace it with a
note/suggestion reflecting that conflicts are auto-resolved (e.g., inform users
about auto-renumbering behavior), and update any callers that rely on errorCode
or suggestions from this branch accordingly.

120-136: Duplicated message construction may diverge from core logic.

The direct function rebuilds the success message (lines 120-130) instead of using result.message returned by moveTasksBetweenTags. The core function at scripts/modules/task-manager/move-task.js:1016-1022 already constructs an identical message with renumbering details.

Consider using result.message directly to avoid duplication and ensure consistency:

-			// Check if any tasks were renumbered during the move
-			const renumberedTasks = (result.movedTasks || []).filter(
-				(t) => t.newId !== undefined
-			);
-			let message = `Successfully moved ${sourceIds.length} task(s) from "${args.sourceTag}" to "${args.targetTag}"`;
-			if (renumberedTasks.length > 0) {
-				const renumberDetails = renumberedTasks
-					.map((t) => `${t.originalId} → ${t.newId}`)
-					.join(', ');
-				message += `. Renumbered to avoid ID collisions: ${renumberDetails}`;
-			}
-
 			return {
 				success: true,
 				data: {
 					...result,
-					message,
+					// result.message already includes renumbering details from core function
 					moveOptions,
 					sourceTag: args.sourceTag,
 					targetTag: args.targetTag
 				}
 			};
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@mcp-server/src/core/direct-functions/move-task-cross-tag.js` around lines 120
- 136, The success message is being reconstructed in move-task-cross-tag.js
instead of using the canonical message from moveTasksBetweenTags; replace the
manual message build (the renumberedTasks mapping and concatenation that sets
`message`) and instead use `result.message` returned by `moveTasksBetweenTags`
(i.e., ensure the returned payload sets data.message = result.message or spreads
result including its message) so the direct function relies on the core
`result.message` for consistency with the logic in move-task.js.
tests/integration/move-task-cross-tag.integration.test.js (1)

553-610: Consider adding test for batch collision with dependency remapping.

The current test covers a single task collision. To validate the batch dependency update logic (lines 943-985 in move-task.js), consider adding a test where:

  1. Task A (id: 1) depends on Task B (id: 2)
  2. Both collide with existing IDs in the target tag
  3. Both get renumbered (e.g., 1→3, 2→4)
  4. A's dependency is updated from 2 to 4

This would ensure the cross-reference update path is exercised.

Would you like me to generate this additional test case?

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/integration/move-task-cross-tag.integration.test.js` around lines 553 -
610, Add a new integration test for moveTasksBetweenTags that simulates a batch
collision with dependency remapping: create source tag tasks A(id:1,
dependsOn:[2]) and B(id:2) and a target tag already containing ids 1 and 2 so
both A and B must be renumbered (e.g., 1→3, 2→4); mockUtils.readJSON should
return this dataset, call moveTasksBetweenTags with both IDs, then assert
result.movedTasks contains the originalId→newId mappings for both tasks, assert
the moved task A's dependency was updated from 2 to 4 in the saved payload
(inspect mockUtils.writeJSON mock.calls[0][1]), assert the target tag now has
both original and renumbered tasks with correct ids/titles/deps and the source
tag is empty; reference moveTasksBetweenTags and the dependency remapping path
in move-task.js to locate logic to test.
scripts/modules/task-manager/move-task.js (1)

899-913: Subtask dependency string handling is unreachable for schema-validated data.

The SubtaskSchema enforces dependencies: z.array(z.number().int().positive()) — numeric only. The code at lines 903–907 checks for string dependencies with dot notation (e.g., "1.2"), which cannot appear in subtask dependency arrays that pass schema validation.

This is defensive code that won't cause problems, but it's not reachable. If validation is strictly enforced during task deserialization, consider removing this unreachable branch.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/modules/task-manager/move-task.js` around lines 899 - 913, The
string-dot dependency handling inside the taskToMove.subtasks mapping is
unreachable because SubtaskSchema enforces numeric-only dependencies; remove the
typeof dep === 'string' && dep.includes('.') branch and replace it with
numeric-only handling: inside the subtask.dependencies =
subtask.dependencies.map(...) check for typeof dep === 'number' and if dep ===
normalizedTaskId return assignedId (otherwise return dep). Update the mapping
logic around taskToMove.subtasks and variables normalizedTaskId and assignedId
accordingly and delete the unreachable string-splitting code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@mcp-server/src/core/direct-functions/move-task-cross-tag.js`:
- Around line 204-215: The TASK_ALREADY_EXISTS error branch in
moveTaskCrossTagDirect is now dead due to auto-renumbering; remove or update the
branch that checks error.code === 'TASK_ALREADY_EXISTS' ||
error.message?.includes('already exists in target tag') and stop setting
errorCode = 'TASK_ALREADY_EXISTS' and the suggestions array there; either delete
the entire conditional block or replace it with a note/suggestion reflecting
that conflicts are auto-resolved (e.g., inform users about auto-renumbering
behavior), and update any callers that rely on errorCode or suggestions from
this branch accordingly.
- Around line 120-136: The success message is being reconstructed in
move-task-cross-tag.js instead of using the canonical message from
moveTasksBetweenTags; replace the manual message build (the renumberedTasks
mapping and concatenation that sets `message`) and instead use `result.message`
returned by `moveTasksBetweenTags` (i.e., ensure the returned payload sets
data.message = result.message or spreads result including its message) so the
direct function relies on the core `result.message` for consistency with the
logic in move-task.js.

In `@scripts/modules/task-manager/move-task.js`:
- Around line 899-913: The string-dot dependency handling inside the
taskToMove.subtasks mapping is unreachable because SubtaskSchema enforces
numeric-only dependencies; remove the typeof dep === 'string' &&
dep.includes('.') branch and replace it with numeric-only handling: inside the
subtask.dependencies = subtask.dependencies.map(...) check for typeof dep ===
'number' and if dep === normalizedTaskId return assignedId (otherwise return
dep). Update the mapping logic around taskToMove.subtasks and variables
normalizedTaskId and assignedId accordingly and delete the unreachable
string-splitting code.

In `@tests/integration/move-task-cross-tag.integration.test.js`:
- Around line 553-610: Add a new integration test for moveTasksBetweenTags that
simulates a batch collision with dependency remapping: create source tag tasks
A(id:1, dependsOn:[2]) and B(id:2) and a target tag already containing ids 1 and
2 so both A and B must be renumbered (e.g., 1→3, 2→4); mockUtils.readJSON should
return this dataset, call moveTasksBetweenTags with both IDs, then assert
result.movedTasks contains the originalId→newId mappings for both tasks, assert
the moved task A's dependency was updated from 2 to 4 in the saved payload
(inspect mockUtils.writeJSON mock.calls[0][1]), assert the target tag now has
both original and renumbered tasks with correct ids/titles/deps and the source
tag is empty; reference moveTasksBetweenTags and the dependency remapping path
in move-task.js to locate logic to test.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 3d6d9b13-c8d7-4965-a890-8525cae48669

📥 Commits

Reviewing files that changed from the base of the PR and between 2d1211b and 8f39ee0.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • mcp-server/src/core/direct-functions/move-task-cross-tag.js
  • package.json
  • scripts/modules/task-manager/move-task.js
  • tests/integration/move-task-cross-tag.integration.test.js

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.

Deprecated transitive dependencies: koa-router, node-domexception, glob

2 participants