Skip to content

chore: move to tsdown#1211

Merged
Crunchyman-ralph merged 13 commits intonextfrom
ralph/chore/move.to.tsdown
Sep 17, 2025
Merged

chore: move to tsdown#1211
Crunchyman-ralph merged 13 commits intonextfrom
ralph/chore/move.to.tsdown

Conversation

@Crunchyman-ralph
Copy link
Collaborator

@Crunchyman-ralph Crunchyman-ralph commented Sep 17, 2025

What type of PR is this?

  • 🐛 Bug fix
  • ✨ Feature
  • 🔌 Integration
  • 📝 Docs
  • 🧹 Refactor
  • Other:

Description

Related Issues

How to Test This

# Example commands or steps

Expected result:

Contributor Checklist

  • Created changeset: npm run changeset
  • Tests pass: npm test
  • Format check passes: npm run format-check (or npm run format to fix)
  • Addressed CodeRabbit comments (if any)
  • Linked related issues (if any)
  • Manually tested the changes

Changelog Entry


For Maintainers

  • PR title follows conventional commits
  • Target branch correct
  • Labels added
  • Milestone assigned (if applicable)

Summary by CodeRabbit

  • Chores
    • Switched build tooling (tsup → tsdown), updated dev/build scripts, removed legacy build scripts, and updated dev/test dependencies (added ts-jest).
  • Refactor
    • Simplified and modernized shared build configuration to align with the new bundler and packaging metadata.
  • New Features
    • Build now injects TM_PUBLIC_* env vars at build time; added "completed" task status with green checkmark across CLI/UI and core types.
  • Tests
    • Jest configured for TypeScript ESM with a custom resolver fallback for .js→.ts.
  • CI
    • CI cancels duplicate runs, uploads build artifacts, and tests consume prebuilt dist artifacts.

@changeset-bot
Copy link

changeset-bot bot commented Sep 17, 2025

⚠️ No Changeset found

Latest commit: 8c6b7a8

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
Contributor

coderabbitai bot commented Sep 17, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Replaces TSUP with TSDOWN across build tooling and package configs, adds tsdown.config.ts and tsdown.base.ts, removes tsup.config.ts, updates Jest to ts-jest ESM with a custom resolver, adds TaskStatus "completed" across types/constants/UI, adjusts CLI tsconfig, CI artifact flow, and an integration test to use built artifacts.

Changes

Cohort / File(s) Summary of changes
Root scripts & deps
package.json
Replace tsuptsdown in build/dev scripts, remove several dev/build scripts, add tsdown & ts-jest to devDependencies, remove tsup.
Build-config base (new)
packages/build-config/src/tsdown.base.ts
New tsdown base: exports env, baseConfig: Partial<UserConfig>, and mergeConfig; adopts tsdown semantics (format/platform/dts/minify/externals) and removes esbuild/watch hooks.
Build-config migration (updated)
packages/build-config/src/tsup.base.ts, packages/build-config/package.json
Migrate API from tsup→tsdown: update signatures/types (Options → UserConfig), remove commonExternals, update package.json exports/entry/type paths to tsdown artifacts.
Project tsdown config (new)
tsdown.config.ts
New project config: dotenv-mono load, collect TM_PUBLIC_* envs, entries for task-master and mcp-server, outDir dist, copy public, noExternal: [/^@tm/], exported via defineConfig(mergeConfig(...)).
TSUP config removed
tsup.config.ts
Deleted previous tsup.config.ts (entrypoints, env injection, externals, esbuild aliasing removed).
Jest ESM & resolver
jest.config.js, jest.resolver.cjs
Switch to ts-jest ESM preset, treat .ts as ESM, add ts-jest transform, and add custom resolver that falls back from relative .js.ts resolution.
CLI TypeScript config
apps/cli/tsconfig.json
Change module → NodeNext, moduleResolution → NodeNext, add moduleDetection: "force", enable esModuleInterop, isolatedModules, resolveJsonModule, adjust strict flags and excludes.
CLI UI tweaks
apps/cli/src/ui/components/header.component.ts, apps/cli/src/utils/ui.ts
Remove unused imports (figlet, gradient-string); add completed status to UI status config (green check/tick).
Core types & constants
packages/tm-core/src/types/index.ts, packages/tm-core/src/constants/index.ts
Add completed to TaskStatus union and isTaskStatus; add completed icon/color to STATUS_ICONS/STATUS_COLORS.
Integration test update
tests/integration/cli/complex-cross-tag-scenarios.test.js
Test now invokes built artifact dist/task-master.js instead of bin/task-master.js.
CI workflow
.github/workflows/ci.yml
Add concurrency/cancel-in-progress block; Build job uploads dist/ artifact; Test job downloads dist/ and removes pre-test build step.

Sequence Diagram(s)

sequenceDiagram
  participant Dev as Developer (npm scripts)
  participant TSDown as tsdown
  participant Config as tsdown.config.ts
  participant Base as tsdown.base.ts
  participant DotEnv as dotenv-mono
  participant Bundler as Bundler (esbuild/tsdown)

  Dev->>TSDown: run build / dev
  TSDown->>Config: load config
  Config->>DotEnv: dotenvLoad()
  Config->>Config: collect TM_PUBLIC_* envs
  Config->>Base: mergeConfig(baseConfig, overrides)
  Config-->>TSDown: provide merged UserConfig (entries,outDir,env,noExternal)
  TSDown->>Bundler: bundle entries -> dist/
  Bundler-->>Dev: produce artifacts (dist/, copied public/)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • eyaltoledano

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "chore: move to tsdown" is concise, uses a conventional-commit prefix, and accurately summarizes the main change (migration from tsup to tsdown across configs and scripts) without unnecessary detail; it is clear enough for a reviewer scanning PR history.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6cfd3b7 and 8c6b7a8.

📒 Files selected for processing (2)
  • .github/workflows/ci.yml (3 hunks)
  • packages/build-config/package.json (1 hunks)

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0e8c42c and 9799ec3.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • package.json (2 hunks)
  • packages/build-config/src/tsup.base.ts (2 hunks)
  • tsdown.config.ts (1 hunks)
  • tsup.config.ts (0 hunks)
💤 Files with no reviewable changes (1)
  • tsup.config.ts
🧰 Additional context used
📓 Path-based instructions (1)
package.json

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

Add and update test scripts in package.json to include test, test:watch, test:coverage, test:unit, test:integration, test:e2e, and test:ci

Files:

  • package.json
🧠 Learnings (6)
📓 Common learnings
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/package.json:13-64
Timestamp: 2025-09-03T12:16:15.866Z
Learning: For internal packages in the claude-task-master project, Crunchyman-ralph prefers pointing package.json "types" entries to src .ts files rather than dist .d.ts files for better developer experience (DX), as the packages are not being exported as SDKs.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-11T12:30:23.843Z
Learning: Import Task Master's development workflow commands and guidelines; treat the contents of ./.taskmaster/CLAUDE.md as if included in the main CLAUDE.md
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/src/auth/config.ts:5-7
Timestamp: 2025-09-02T21:51:27.921Z
Learning: The user Crunchyman-ralph prefers not to use node: scheme imports (e.g., 'node:os', 'node:path') for Node.js core modules and considers suggestions to change bare imports to node: scheme as too nitpicky.
📚 Learning: 2025-09-03T12:16:15.866Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/package.json:13-64
Timestamp: 2025-09-03T12:16:15.866Z
Learning: For internal packages in the claude-task-master project, Crunchyman-ralph prefers pointing package.json "types" entries to src .ts files rather than dist .d.ts files for better developer experience (DX), as the packages are not being exported as SDKs.

Applied to files:

  • tsdown.config.ts
📚 Learning: 2025-09-02T21:51:41.383Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/src/auth/config.ts:0-0
Timestamp: 2025-09-02T21:51:41.383Z
Learning: In packages/tm-core/src/auth/config.ts, the BASE_DOMAIN configuration intentionally does not include runtime environment variable fallbacks like TM_BASE_DOMAIN or HAMSTER_BASE_URL. The maintainers prefer to keep these capabilities "hush hush" and undocumented, using only the build-time TM_PUBLIC_BASE_DOMAIN and the default value.

Applied to files:

  • tsdown.config.ts
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Applies to package.json : Add and update test scripts in package.json to include test, test:watch, test:coverage, test:unit, test:integration, test:e2e, and test:ci

Applied to files:

  • package.json
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Applies to **/*.test.ts : Use established mocking patterns for dependencies such as bcrypt and Prisma in test files

Applied to files:

  • package.json
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Applies to {tests/integration/**/*.test.ts,src/**/*.integration.test.ts} : Use supertest for API endpoint testing in integration test files

Applied to files:

  • package.json
🧬 Code graph analysis (1)
tsdown.config.ts (1)
packages/build-config/src/tsup.base.ts (2)
  • mergeConfig (36-44)
  • baseConfig (23-30)
🔇 Additional comments (6)
package.json (4)

15-16: Verify multiple --watch globs are supported.

Docs show --watch [path] (single optional path). Repeating --watch may work but isn’t documented; confirm behavior in your environment. If needed, centralize watch paths in config or use a glob that covers all. (tsdown.dev)


146-147: Confirm published tsdown version.

You pinned tsdown at ^0.15.2. npm currently lists 0.14.x as latest; please double‑check before CI breaks on install. (npmjs.com)

If needed, adjust to the latest published tag.


28-35: Test scripts coverage looks good.

All required test scripts (test, test:watch, test:coverage, test:unit, test:integration, test:e2e, test:ci) are present.


115-116: CI already targets Node 20 (no immediate change required).

tsdown is present (package.json: ^0.15.2) and package.json.engines.node = ">=18.0.0". I inspected the repo: GH workflows in .github/workflows use actions/setup-node@v4 with node-version: 20 (e.g., ci.yml, extension-ci.yml, release.yml, pre-release.yml, update-models-md.yml) and .nvmrc contains "22". CI/dev tooling therefore target Node 20+/22 and will satisfy tsdown's Node ≥20.19 requirement. Optional: pin or document the build-time Node (20.19+) in workflows/.nvmrc or README if you want an explicit contract.

tsdown.config.ts (2)

7-17: Build‑time env injection looks correct; ensure usage sites read via process.env or import.meta.env.

env accepts a map and tsdown exposes them to process.env.* / import.meta.env.*. Your approach with dotenv-mono + filtering TM_PUBLIC_* is sane. Verify call‑sites align. (tsdown.ru)


21-35: Entries/externals/copy align with tsdown config surface.

  • entry object, noExternal/external, and copy are supported options. Using noExternal: [/^@tm\//] is the right way to force bundling workspace pkgs; copy: ['public'] replaces the old publicDir. (tsdown.dev)

One nit: if you ever need a post‑build hook here, consider onSuccess in config (not CLI) for portability. (tsdown.dev)

Comment on lines 23 to 30
export const baseConfig: Partial<UserConfig> = {
sourcemap: isDevelopment,
clean: true,
dts: false,
dts: isDevelopment,
minify: isProduction,
treeshake: isProduction,
splitting: false,
// Don't bundle any other dependencies (auto-external all node_modules)
external: [/^[^./]/],
esbuildOptions(options) {
options.platform = 'node';
// Allow importing TypeScript from JavaScript
options.resolveExtensions = ['.ts', '.js', '.mjs', '.json'];
// Better source mapping in development only
options.sourcesContent = isDevelopment;
// Keep original names for better debugging in development
options.keepNames = isDevelopment;
},
// Watch mode configuration for development
watch: false
external: [/^[^./]/]
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

🧩 Analysis chain

External regex is too aggressive; disable dts by default to match team preference.

  • The external: [/^[^./]/] pattern will accidentally externalize path‑aliased intra‑repo imports (anything not starting with . or /), which can break bundling unless each case is countered with noExternal. tsdown already treats dependencies and peerDependencies as external by default, so this regex is unnecessary and risky. (tsdown.dev)
  • Per retrieved learnings, internal packages prefer pointing types to src/*.ts rather than shipping .d.ts. Emitting dts in dev contradicts that and slows watch builds.

Suggested change:

 export const baseConfig: Partial<UserConfig> = {
   sourcemap: isDevelopment,
-  dts: isDevelopment,
+  dts: false,
   minify: isProduction,
   treeshake: isProduction,
   // Don't bundle any other dependencies (auto-external all node_modules)
-  external: [/^[^./]/]
+  // Rely on tsdown defaults for externals; override per-package if needed.
 }

Note: packages that truly need .d.ts can override dts: true locally. tsdown enables dts automatically when package.json has a types field; setting false here ensures we don’t emit by default. (tsdown.dev)


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== packages/build-config/src/tsup.base.ts ==="
if [ -f packages/build-config/src/tsup.base.ts ]; then
  nl -ba packages/build-config/src/tsup.base.ts | sed -n '1,240p'
else
  echo "MISSING: packages/build-config/src/tsup.base.ts"
fi

echo
echo "=== search for the exact external regex or other 'external:' occurrences ==="
rg -n --hidden --no-ignore -S "/\\^\\[\\^./\\]/" || true
rg -n --hidden --no-ignore -S "external\s*:\s*\[.*\]" -g '!*node_modules*' -C3 || true

echo
echo "=== occurrences of 'dts:' across repo (context) ==="
rg -n --hidden --no-ignore -S "\bdts\s*:" -g '!*node_modules*' -C3 || true

echo
echo "=== list package.json 'types' fields under packages/** ==="
for f in $(rg --files -g 'packages/**/package.json' || true); do
  echo ">>> $f"
  jq -r '.types // "<no types>"' "$f" || true
done

echo
echo "=== search for tsdown references ==="
rg -n --hidden --no-ignore -S "tsdown" -g '!*node_modules*' -C3 || true

Length of output: 87


🏁 Script executed:

#!/bin/bash
set -uo pipefail

FILE="packages/build-config/src/tsup.base.ts"
echo "=== $FILE ==="
if [ -f "$FILE" ]; then
  if command -v sed >/dev/null 2>&1; then
    sed -n '1,240p' "$FILE"
  else
    cat "$FILE" | sed -n '1,240p' || cat "$FILE"
  fi
else
  echo "MISSING: $FILE"
fi

echo
echo "=== search for external: patterns ==="
if command -v rg >/dev/null 2>&1; then
  rg -n --hidden --no-ignore -S "/\\^\\[\\^./\\]/" || true
  rg -n --hidden --no-ignore -S "external\s*:\s*\[.*\]" -g '!*node_modules*' -C3 || true
else
  grep -nR --line-number -P "/\^\[\^./\]/" || true
  grep -nR --line-number -P "external\s*:\s*\[.*\]" || true
fi

echo
echo "=== occurrences of 'dts:' across repo ==="
if command -v rg >/dev/null 2>&1; then
  rg -n --hidden --no-ignore -S "\bdts\s*:" -g '!*node_modules*' -C3 || true
else
  grep -nR --line-number -P "\bdts\s*:" || true
fi

echo
echo "=== list package.json 'types' fields under packages/** ==="
if command -v rg >/dev/null 2>&1; then
  files=$(rg --files -g 'packages/**/package.json' || true)
else
  files=$(find packages -type f -name package.json 2>/dev/null || true)
fi

if [ -z "$files" ]; then
  echo "No package.json found under packages/"
else
  for f in $files; do
    echo ">>> $f"
    if command -v jq >/dev/null 2>&1; then
      jq -r '.types // "<no types>"' "$f" || true
    else
      python - <<PY
import json,sys
try:
  j=json.load(open('$f'))
  print(j.get('types','<no types>'))
except Exception as e:
  print('ERROR',e)
PY
    fi
  done
fi

echo
echo "=== search for tsdown references ==="
if command -v rg >/dev/null 2>&1; then
  rg -n --hidden --no-ignore -S "tsdown" -g '!*node_modules*' -C3 || true
else
  grep -nR --line-number -i "tsdown" || true
fi

Length of output: 1899


Disable default dts and remove aggressive external regex in base tsdown config

  • File: packages/build-config/src/tsup.base.ts — set dts: false (packages/build-config/package.json currently has "types": "./dist/tsup.base.d.ts"; emit .d.ts only per-package).
  • Remove external: [/^[^./]/] — this pattern externalizes path‑aliased intra‑repo imports; rely on tsdown defaults and use per-package overrides (noExternal) when needed.
 export const baseConfig: Partial<UserConfig> = {
   sourcemap: isDevelopment,
-  dts: isDevelopment,
+  dts: false,
   minify: isProduction,
   treeshake: isProduction,
   // Don't bundle any other dependencies (auto-external all node_modules)
-  external: [/^[^./]/]
+  // Rely on tsdown defaults for externals; override per-package if needed.
 }
📝 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
export const baseConfig: Partial<UserConfig> = {
sourcemap: isDevelopment,
clean: true,
dts: false,
dts: isDevelopment,
minify: isProduction,
treeshake: isProduction,
splitting: false,
// Don't bundle any other dependencies (auto-external all node_modules)
external: [/^[^./]/],
esbuildOptions(options) {
options.platform = 'node';
// Allow importing TypeScript from JavaScript
options.resolveExtensions = ['.ts', '.js', '.mjs', '.json'];
// Better source mapping in development only
options.sourcesContent = isDevelopment;
// Keep original names for better debugging in development
options.keepNames = isDevelopment;
},
// Watch mode configuration for development
watch: false
external: [/^[^./]/]
};
export const baseConfig: Partial<UserConfig> = {
sourcemap: isDevelopment,
dts: false,
minify: isProduction,
treeshake: isProduction,
// Rely on tsdown defaults for externals; override per-package if needed.
};
🤖 Prompt for AI Agents
In packages/build-config/src/tsup.base.ts around lines 23 to 30, change the base
tsup config to stop emitting declaration files by setting dts: false
(per-package builds will emit .d.ts as declared in
packages/build-config/package.json) and remove the aggressive external:
[/^[^./]/] entry so path‑aliased intra‑repo imports are not auto‑externalized;
rely on tsup defaults and let individual packages opt into noExternal when
necessary.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

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

⚠️ Outside diff range comments (6)
packages/tm-core/src/types/index.ts (1)

166-179: Fix isTaskStatus guard to include 'completed'.

Currently rejects a valid TaskStatus and can cause subtle runtime/type narrowing bugs.

Apply:

 export function isTaskStatus(value: unknown): value is TaskStatus {
   return (
     typeof value === 'string' &&
     [
       'pending',
       'in-progress',
       'done',
       'deferred',
       'cancelled',
       'blocked',
-      'review'
+      'review',
+      'completed'
     ].includes(value)
   );
 }
packages/tm-core/src/constants/index.ts (1)

15-23: TASK_STATUSES missing 'completed'.

This list powers option enumerations; omission will hide the new state in UIs/validators relying on TASK_STATUSES.

 export const TASK_STATUSES: readonly TaskStatus[] = [
   'pending',
   'in-progress',
   'done',
   'deferred',
   'cancelled',
   'blocked',
-  'review'
+  'review',
+  'completed'
 ] as const;
jest.config.js (2)

17-19: Include TS test patterns.

Config only matches .js tests; with ts-jest in place, include .ts/.tsx.

- testMatch: ['**/__tests__/**/*.js', '**/?(*.)+(spec|test).js'],
+ testMatch: [
+   '**/__tests__/**/*.(js|ts|tsx)',
+   '**/?(*.)+(spec|test).(js|ts|tsx)'
+ ],

41-43: Consider adding moduleFileExtensions for TS.

Not required, but helps resolution clarity in some setups.

 moduleDirectories: ['node_modules', '<rootDir>'],
+moduleFileExtensions: ['ts', 'tsx', 'js', 'mjs', 'cjs', 'json', 'node'],
tests/integration/cli/complex-cross-tag-scenarios.test.js (1)

5-8: Fix ESM breakage: replace require('os') with ESM import

This file is ESM; using require('os') will throw. Import os and call os.homedir().

Apply:

@@
 import { fileURLToPath } from 'url';
+import os from 'os';
@@
-    // If we can't change directory, try a known safe directory
-    process.chdir(require('os').homedir());
+    // If we can't change directory, try a known safe directory
+    process.chdir(os.homedir());

Also applies to: 131-134

apps/cli/src/utils/ui.ts (1)

232-239: Include 'completed' in dependency status icons and unify arrow glyph

Dependency badges won’t show a check for completed; also uses '►' vs '▶' elsewhere. Align for consistency.

Apply:

-      const statusIcon =
-        task.status === 'done'
-          ? '✓'
-          : task.status === 'in-progress'
-            ? '►'
-            : '○';
+      const statusIcon =
+        task.status === 'done' || task.status === 'completed'
+          ? '✓'
+          : task.status === 'in-progress'
+            ? '▶'
+            : '○';
♻️ Duplicate comments (3)
packages/build-config/src/tsup.base.ts (3)

1-6: Rename file to reflect tsdown.

File is tsdown-specific but still named tsup.base.ts.

Rename to tsdown.base.ts and update imports/exports.


23-32: Disable dts by default and drop aggressive external regex.

Emitting dts in dev slows watches and conflicts with the team’s DX preference; the external patterns can mis-externalize path-aliased intra-repo imports.

 export const baseConfig: Partial<UserConfig> = {
   sourcemap: isDevelopment,
   format: 'esm',
   platform: 'node',
-  dts: isDevelopment,
+  dts: false,
   minify: isProduction,
   treeshake: isProduction,
-  // Keep all npm dependencies external (available via node_modules)
-  external: [/^[^@./]/, /^@(?!tm\/)/]
+  // Rely on tsdown defaults for externals; override per-package via noExternal.
 };

38-46: Don’t cast to UserConfig; return Partial and let defineConfig validate.

Current cast can mask structural mistakes.

 export function mergeConfig(
   baseConfig: Partial<UserConfig>,
   overrides: Partial<UserConfig>
-): UserConfig {
-  return {
+): Partial<UserConfig> {
+  return {
     ...baseConfig,
-    ...overrides
-  } as UserConfig;
+    ...overrides
+  };
 }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9799ec3 and e973286.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (11)
  • apps/cli/src/ui/components/header.component.ts (0 hunks)
  • apps/cli/src/utils/ui.ts (1 hunks)
  • apps/cli/tsconfig.json (1 hunks)
  • jest.config.js (2 hunks)
  • jest.resolver.cjs (1 hunks)
  • package.json (2 hunks)
  • packages/build-config/src/tsup.base.ts (2 hunks)
  • packages/tm-core/src/constants/index.ts (2 hunks)
  • packages/tm-core/src/types/index.ts (1 hunks)
  • tests/integration/cli/complex-cross-tag-scenarios.test.js (1 hunks)
  • tsdown.config.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • apps/cli/src/ui/components/header.component.ts
🧰 Additional context used
📓 Path-based instructions (11)
**/*.js

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

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

Files:

  • jest.config.js
  • tests/integration/cli/complex-cross-tag-scenarios.test.js
jest.config.js

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

Create and maintain a production-ready Jest configuration in jest.config.js

Files:

  • jest.config.js
tests/{unit,integration,e2e,fixtures}/**/*.js

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

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

Files:

  • tests/integration/cli/complex-cross-tag-scenarios.test.js
**/*.{test,spec}.{js,ts,jsx,tsx}

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

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

Files:

  • tests/integration/cli/complex-cross-tag-scenarios.test.js
**/*.test.js

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

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

Files:

  • tests/integration/cli/complex-cross-tag-scenarios.test.js
tests/integration/**/*.test.js

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

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

Files:

  • tests/integration/cli/complex-cross-tag-scenarios.test.js
tests/{unit,integration,e2e}/**/*.test.js

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

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

Files:

  • tests/integration/cli/complex-cross-tag-scenarios.test.js
tests/{integration,e2e}/**/*.test.js

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

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

Files:

  • tests/integration/cli/complex-cross-tag-scenarios.test.js
**/*.{test,spec}.*

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

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

Files:

  • tests/integration/cli/complex-cross-tag-scenarios.test.js
tests/{unit,integration,e2e}/**

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

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

Files:

  • tests/integration/cli/complex-cross-tag-scenarios.test.js
package.json

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

Add and update test scripts in package.json to include test, test:watch, test:coverage, test:unit, test:integration, test:e2e, and test:ci

Files:

  • package.json
🧠 Learnings (28)
📓 Common learnings
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/package.json:13-64
Timestamp: 2025-09-03T12:16:15.866Z
Learning: For internal packages in the claude-task-master project, Crunchyman-ralph prefers pointing package.json "types" entries to src .ts files rather than dist .d.ts files for better developer experience (DX), as the packages are not being exported as SDKs.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-11T12:30:23.843Z
Learning: Import Task Master's development workflow commands and guidelines; treat the contents of ./.taskmaster/CLAUDE.md as if included in the main CLAUDE.md
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tasks.mdc:0-0
Timestamp: 2025-07-18T17:14:29.399Z
Learning: Applies to scripts/modules/task-manager.js : Use consistent formatting for task files, include all task properties in text files, and format dependencies with status indicators.
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/src/auth/config.ts:5-7
Timestamp: 2025-09-02T21:51:27.921Z
Learning: The user Crunchyman-ralph prefers not to use node: scheme imports (e.g., 'node:os', 'node:path') for Node.js core modules and considers suggestions to change bare imports to node: scheme as too nitpicky.
📚 Learning: 2025-07-18T17:16:32.622Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/ui.mdc:0-0
Timestamp: 2025-07-18T17:16:32.622Z
Learning: Applies to scripts/modules/ui.js : Use getStatusWithColor for status display, formatDependenciesWithStatus for dependency lists, and truncate for overflowing text

Applied to files:

  • apps/cli/src/utils/ui.ts
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Applies to jest.config.js : Create and maintain a production-ready Jest configuration in jest.config.js

Applied to files:

  • jest.config.js
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Applies to **/__tests__/**/*.ts : In JavaScript/TypeScript projects using Jest, test files should be located in __tests__ directories or match *.test.ts and *.spec.ts patterns

Applied to files:

  • jest.config.js
  • package.json
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Applies to **/?(*.)+(spec|test).ts : In JavaScript/TypeScript projects using Jest, test files should match *.test.ts and *.spec.ts patterns

Applied to files:

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

Applied to files:

  • jest.config.js
  • package.json
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Use test-specific file paths (e.g., 'test-tasks.json') for all file operations in tests.

Applied to files:

  • jest.config.js
  • tests/integration/cli/complex-cross-tag-scenarios.test.js
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/**/*.test.js : Test CLI and MCP interfaces with real task data, verify end-to-end workflows across tag contexts, and test error scenarios and recovery in integration tests.

Applied to files:

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

Applied to files:

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

Applied to files:

  • tests/integration/cli/complex-cross-tag-scenarios.test.js
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Verify modifications on the in-memory task objects passed to writeJSON.

Applied to files:

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

Applied to files:

  • tests/integration/cli/complex-cross-tag-scenarios.test.js
📚 Learning: 2025-07-18T17:19:27.365Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: assets/.windsurfrules:0-0
Timestamp: 2025-07-18T17:19:27.365Z
Learning: Use the global `task-master` CLI command instead of directly invoking `node scripts/dev.js` for all task management operations.

Applied to files:

  • tests/integration/cli/complex-cross-tag-scenarios.test.js
📚 Learning: 2025-07-18T17:18:17.759Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/utilities.mdc:0-0
Timestamp: 2025-07-18T17:18:17.759Z
Learning: Applies to scripts/modules/utils.js : Use tag resolution functions for all task data access, provide backward compatibility with legacy format, and default to 'master' tag when no tag is specified.

Applied to files:

  • tests/integration/cli/complex-cross-tag-scenarios.test.js
📚 Learning: 2025-07-18T17:14:29.399Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tasks.mdc:0-0
Timestamp: 2025-07-18T17:14:29.399Z
Learning: Applies to scripts/modules/task-manager.js : Use tag resolution functions to maintain backward compatibility, returning legacy format to core functions and not exposing the tagged structure to existing core logic.

Applied to files:

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

Applied to files:

  • tests/integration/cli/complex-cross-tag-scenarios.test.js
📚 Learning: 2025-07-18T17:19:27.365Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: assets/.windsurfrules:0-0
Timestamp: 2025-07-18T17:19:27.365Z
Learning: Use 'pending' for tasks ready to be worked on, 'done' for completed and verified tasks, and 'deferred' for postponed tasks. Add custom status values as needed.

Applied to files:

  • packages/tm-core/src/types/index.ts
  • packages/tm-core/src/constants/index.ts
📚 Learning: 2025-09-01T09:55:15.061Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: assets/AGENTS.md:0-0
Timestamp: 2025-09-01T09:55:15.061Z
Learning: Follow Task ID formats (1, 1.1, 1.1.1) and status values (pending, in-progress, done, deferred, cancelled, blocked)

Applied to files:

  • packages/tm-core/src/types/index.ts
📚 Learning: 2025-09-02T21:51:41.383Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/src/auth/config.ts:0-0
Timestamp: 2025-09-02T21:51:41.383Z
Learning: In packages/tm-core/src/auth/config.ts, the BASE_DOMAIN configuration intentionally does not include runtime environment variable fallbacks like TM_BASE_DOMAIN or HAMSTER_BASE_URL. The maintainers prefer to keep these capabilities "hush hush" and undocumented, using only the build-time TM_PUBLIC_BASE_DOMAIN and the default value.

Applied to files:

  • tsdown.config.ts
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/*.js : Use consistent file naming conventions: 'task_${id.toString().padStart(3, '0')}.txt', use path.join for composing file paths, and use appropriate file extensions (.txt for tasks, .json for data).

Applied to files:

  • packages/build-config/src/tsup.base.ts
📚 Learning: 2025-09-03T12:16:15.866Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/package.json:13-64
Timestamp: 2025-09-03T12:16:15.866Z
Learning: For internal packages in the claude-task-master project, Crunchyman-ralph prefers pointing package.json "types" entries to src .ts files rather than dist .d.ts files for better developer experience (DX), as the packages are not being exported as SDKs.

Applied to files:

  • packages/build-config/src/tsup.base.ts
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Applies to package.json : Add and update test scripts in package.json to include test, test:watch, test:coverage, test:unit, test:integration, test:e2e, and test:ci

Applied to files:

  • package.json
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/commands.js : Use consistent patterns for option naming and help text in CLI commands.

Applied to files:

  • package.json
📚 Learning: 2025-07-31T22:07:49.716Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/commands.mdc:0-0
Timestamp: 2025-07-31T22:07:49.716Z
Learning: Applies to scripts/modules/commands.js : Use kebab-case for long-form option names (e.g., --output-format), provide single-letter shortcuts when appropriate, and use consistent option names across similar commands.

Applied to files:

  • package.json
📚 Learning: 2025-07-18T17:08:48.695Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/commands.mdc:0-0
Timestamp: 2025-07-18T17:08:48.695Z
Learning: Applies to scripts/modules/commands.js : Use clear variable naming that matches the flag's intent when handling boolean flags in code.

Applied to files:

  • package.json
📚 Learning: 2025-07-18T17:12:57.903Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/new_features.mdc:0-0
Timestamp: 2025-07-18T17:12:57.903Z
Learning: Applies to scripts/modules/commands.js : Use kebab-case for command names and option names in CLI commands, and use the same option names across commands when they represent the same concept.

Applied to files:

  • package.json
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Applies to **/*.test.ts : Use established mocking patterns for dependencies such as bcrypt and Prisma in test files

Applied to files:

  • package.json
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Applies to {tests/integration/**/*.test.ts,src/**/*.integration.test.ts} : Use supertest for API endpoint testing in integration test files

Applied to files:

  • package.json
🧬 Code graph analysis (2)
jest.resolver.cjs (1)
index.js (1)
  • require (34-34)
tsdown.config.ts (1)
packages/build-config/src/tsup.base.ts (2)
  • mergeConfig (38-46)
  • baseConfig (23-32)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test
🔇 Additional comments (13)
packages/tm-core/src/constants/index.ts (2)

54-63: Icons map looks consistent.

Both 'done' and 'completed' use ✓; OK if they’re intended as separate-but-similar states.

If 'completed' is an alias for 'done', consider collapsing to a single canonical state to avoid ambiguity.


68-77: Colors map is consistent with icons.

No issues; both 'done' and 'completed' are green.

package.json (4)

14-16: Build/dev: tsdown migration looks good.

Commands are minimal and clear; watch globs cover CLI and server.


20-27: Test scripts meet project guidelines.

test, test:watch, test:coverage, test:unit, test:integration, test:e2e, and test:ci are present.


138-140: DevDeps updated for TS + ESM testing and build.

Adding ts-jest and tsdown is correct for the new toolchain.


7-11: Verify bin outputs match tsdown/build entries.

package.json defines: task-master → dist/task-master.js; task-master-mcp → dist/mcp-server.js; task-master-ai → dist/mcp-server.js. Repo search returned no tsdown entry definitions.

  • Confirm whether task-master-ai should point to a distinct output (not dist/mcp-server.js).
  • Locate the build config (tsdown.config.* or equivalent) that emits dist/*.js and ensure its entry keys match these bin names.

Location: package.json (lines 7-11, 29-35).

jest.config.js (2)

21-30: TS + ESM preset/transform look correct.

Preset default-esm with useESM: true aligns with NodeNext.


39-39: Custom resolver integration OK.

Points to the new resolver; once the import tweak lands, should be stable.

apps/cli/tsconfig.json (1)

4-5: NodeNext + strict mode: good move.

Settings align with ESM tooling and ts-jest.

Also applies to: 27-33

tsdown.config.ts (2)

19-31: Config composition looks correct.

Entries, outDir, copy, noExternal, and env injection align with the new toolchain.

Please confirm builds produce:

  • dist/task-master.js
  • dist/mcp-server.js
    and that the CLI runs via npm bin shims in CI.

7-17: Env whitelist is safe and focused.

Only TM_PUBLIC_* are injected; dotenv load precedes collection. Good.

packages/tm-core/src/types/index.ts (1)

20-29: ```shell
#!/bin/bash
set -euo pipefail
echo "PWD: $(pwd)"
echo "=== File: packages/tm-core/src/types/index.ts ==="
if [ -f packages/tm-core/src/types/index.ts ]; then
sed -n '1,240p' packages/tm-core/src/types/index.ts || true
else
echo "File not found: packages/tm-core/src/types/index.ts"
fi

echo
echo "=== Search: occurrences of 'TaskStatus' ==="
rg -n -C2 --hidden --no-ignore-vcs "TaskStatus" || true

echo
echo "=== Search: literal 'completed' occurrences ==="
rg -n -C2 --hidden --no-ignore-vcs "'completed'|"completed"" || true

echo
echo "=== Search: literal 'done' occurrences ==="
rg -n -C2 --hidden --no-ignore-vcs "'done'|"done"" || true

echo
echo "=== Search: validation schemas (zod/yup/joi/ajv) ==="
rg -n -C2 --hidden --no-ignore-vcs "z\.enum|z\.literal|z\.union|Yup\.|joi\.|Joi\.|ajv|JSONSchema" || true

echo
echo "=== Search: allowedStatuses / status lists / validators ==="
rg -n -C2 --hidden --no-ignore-vcs "allowedStatuses|allowed_statuses|statusList|statusWhitelist|statusFilter|is[A-Za-z0-9_]*Status|validate[A-Za-z0-9_]*Status" || true


</blockquote></details>
<details>
<summary>apps/cli/src/utils/ui.ts (1)</summary><blockquote>

`54-58`: **LGTM: completed status wired into UI**

The new completed mapping matches core types/constants and styling.

</blockquote></details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

♻️ Duplicate comments (1)
jest.resolver.cjs (1)

1-3: Good fix: named import for defaultResolver; resolves prior nit and is stable across Jest versions.
Matches your team's TS-only plan; fallback to options.defaultResolver retained.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7c14f8a and 1d8da49.

📒 Files selected for processing (2)
  • jest.resolver.cjs (1 hunks)
  • packages/build-config/src/tsdown.base.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (16)
📓 Common learnings
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/package.json:13-64
Timestamp: 2025-09-03T12:16:15.866Z
Learning: For internal packages in the claude-task-master project, Crunchyman-ralph prefers pointing package.json "types" entries to src .ts files rather than dist .d.ts files for better developer experience (DX), as the packages are not being exported as SDKs.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-11T12:30:23.843Z
Learning: Import Task Master's development workflow commands and guidelines; treat the contents of ./.taskmaster/CLAUDE.md as if included in the main CLAUDE.md
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tasks.mdc:0-0
Timestamp: 2025-07-18T17:14:29.399Z
Learning: Applies to scripts/modules/task-manager.js : Use consistent formatting for task files, include all task properties in text files, and format dependencies with status indicators.
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1211
File: jest.resolver.cjs:8-15
Timestamp: 2025-09-17T19:09:08.856Z
Learning: In the eyaltoledano/claude-task-master project, the team only uses .ts files and does not plan to use .tsx or .mts extensions, so Jest resolver and build tooling should focus on .js → .ts mapping only.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/utilities.mdc:0-0
Timestamp: 2025-07-18T17:18:17.759Z
Learning: Applies to scripts/modules/utils.js : Implement complete migration for all related files in the tagged task system, handle configuration and state file creation, and provide migration status tracking.
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/src/auth/config.ts:5-7
Timestamp: 2025-09-02T21:51:27.921Z
Learning: The user Crunchyman-ralph prefers not to use node: scheme imports (e.g., 'node:os', 'node:path') for Node.js core modules and considers suggestions to change bare imports to node: scheme as too nitpicky.
📚 Learning: 2025-09-17T19:09:08.856Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1211
File: jest.resolver.cjs:8-15
Timestamp: 2025-09-17T19:09:08.856Z
Learning: In the eyaltoledano/claude-task-master project, the team only uses .ts files and does not plan to use .tsx or .mts extensions, so Jest resolver and build tooling should focus on .js → .ts mapping only.

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Applies to **/?(*.)+(spec|test).ts : In JavaScript/TypeScript projects using Jest, test files should match *.test.ts and *.spec.ts patterns

Applied to files:

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

Applied to files:

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

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Create self-contained test implementations rather than using real implementations when testing modules with initialization issues.

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Use test-specific file paths (e.g., 'test-tasks.json') for all file operations in tests.

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Use different file paths for each test to avoid test interdependence.

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Do not test exact error messages; test for error presence and general properties instead.

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-07-18T17:10:31.810Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/git_workflow.mdc:0-0
Timestamp: 2025-07-18T17:10:31.810Z
Learning: Applies to **/*.{test,spec}.{js,ts,jsx,tsx} : Create a test file if needed and ensure all tests pass before completing a task

Applied to files:

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

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-09-03T12:16:15.866Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/package.json:13-64
Timestamp: 2025-09-03T12:16:15.866Z
Learning: For internal packages in the claude-task-master project, Crunchyman-ralph prefers pointing package.json "types" entries to src .ts files rather than dist .d.ts files for better developer experience (DX), as the packages are not being exported as SDKs.

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-09-02T21:51:27.921Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/src/auth/config.ts:5-7
Timestamp: 2025-09-02T21:51:27.921Z
Learning: The user Crunchyman-ralph prefers not to use node: scheme imports (e.g., 'node:os', 'node:path') for Node.js core modules and considers suggestions to change bare imports to node: scheme as too nitpicky.

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-09-17T19:08:57.856Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1211
File: tests/integration/cli/complex-cross-tag-scenarios.test.js:20-22
Timestamp: 2025-09-17T19:08:57.856Z
Learning: The user Crunchyman-ralph confirmed that in their build pipeline, they assume dist/ artifacts are already built by the time tests run, when tests reference dist/task-master.js instead of bin/task-master.js.

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-09-03T12:45:30.724Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/src/subpath-exports.test.ts:6-9
Timestamp: 2025-09-03T12:45:30.724Z
Learning: The user Crunchyman-ralph prefers to avoid overly nitpicky or detailed suggestions in code reviews, especially for test coverage of minor import paths. Focus on more substantial issues rather than comprehensive coverage of all possible edge cases.

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-08-02T15:33:22.656Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1069
File: .changeset/fix-tag-complexity-detection.md:0-0
Timestamp: 2025-08-02T15:33:22.656Z
Learning: For changeset files (.changeset/*.md), Crunchyman-ralph prefers to ignore formatting nitpicks about blank lines between frontmatter and descriptions, as he doesn't mind having them and wants to avoid such comments in future reviews.

Applied to files:

  • jest.resolver.cjs
🧬 Code graph analysis (1)
packages/build-config/src/tsdown.base.ts (1)
apps/extension/src/webview/utils/logger.ts (1)
  • isDevelopment (34-47)
⏰ 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: Build
🔇 Additional comments (1)
packages/build-config/src/tsdown.base.ts (1)

26-27: Confirm platform: 'node' is overridden for browser/webview targets

Some apps (e.g., VS Code webview) are browser‑only. Ensure their tsdown configs override platform appropriately, otherwise bundling may pull Node shims or break at runtime.

Comment on lines +10 to +17
/**
* Environment helpers
*/
export const env = {
isProduction,
isDevelopment,
NODE_ENV: process.env.NODE_ENV || 'development'
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick

Optional: add isTest for consistency

Many tools set NODE_ENV='test'. Consider exporting isTest to avoid ad‑hoc checks across packages.

 export const env = {
   isProduction,
   isDevelopment,
-  NODE_ENV: process.env.NODE_ENV || 'development'
+  NODE_ENV: process.env.NODE_ENV || 'development',
+  isTest: process.env.NODE_ENV === 'test'
 };
📝 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
/**
* Environment helpers
*/
export const env = {
isProduction,
isDevelopment,
NODE_ENV: process.env.NODE_ENV || 'development'
};
/**
* Environment helpers
*/
export const env = {
isProduction,
isDevelopment,
NODE_ENV: process.env.NODE_ENV || 'development',
isTest: process.env.NODE_ENV === 'test'
};
🤖 Prompt for AI Agents
In packages/build-config/src/tsdown.base.ts around lines 10 to 17, add and
export an isTest boolean to the env object for consistency: derive it from
process.env.NODE_ENV === 'test' (similar to isProduction/isDevelopment) and
include it in the exported env map (NODE_ENV remains as-is); this avoids
scattered ad-hoc checks and keeps the shape consistent with other environment
flags.

Comment on lines +23 to +32
export const baseConfig: Partial<UserConfig> = {
sourcemap: isDevelopment,
format: 'esm',
platform: 'node',
dts: isDevelopment,
minify: isProduction,
treeshake: isProduction,
// Keep all npm dependencies external (available via node_modules)
external: [/^[^@./]/, /^@(?!tm\/)/]
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick

If you keep external here, add a comment on noExternal precedence

For future maintainers: noExternal forces bundling even if a package matches external. This avoids confusion when both are present. (tsdown.dev)

🤖 Prompt for AI Agents
In packages/build-config/src/tsdown.base.ts around lines 23 to 32, the exported
baseConfig sets an external pattern but lacks a note about noExternal taking
precedence; add a concise comment on the external entry explaining that
noExternal will force bundling of a matched package even if it matches external
(i.e., noExternal has higher precedence), and include a reference to the
tsdown.dev options page for future maintainers.

Comment on lines +23 to +29
export const baseConfig: Partial<UserConfig> = {
sourcemap: isDevelopment,
format: 'esm',
platform: 'node',
dts: isDevelopment,
minify: isProduction,
treeshake: isProduction,
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick

Reconsider dts/treeshake defaults

  • dts: isDevelopment likely isn’t what you want; tsdown auto-enables dts when package.json has a types field, and dts generation is intended for published libs. Given the team’s DX preference to point types at src .ts for internal packages, set dts: false in base and enable per‑package only where needed. (tsdown.dev)
  • treeshake defaults to true; you can omit it unless you explicitly want it off in dev. (tsdown.dev)

Apply:

 export const baseConfig: Partial<UserConfig> = {
   sourcemap: isDevelopment,
   format: 'esm',
   platform: 'node',
-  dts: isDevelopment,
+  // Default off for monorepo DX; enable per-package if publishing types
+  dts: false,
-  minify: isProduction,
-  treeshake: isProduction,
+  minify: isProduction,
+  // treeshake defaults to true; keep explicit only if you want it disabled in dev
+  // treeshake: isProduction,
📝 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
export const baseConfig: Partial<UserConfig> = {
sourcemap: isDevelopment,
format: 'esm',
platform: 'node',
dts: isDevelopment,
minify: isProduction,
treeshake: isProduction,
export const baseConfig: Partial<UserConfig> = {
sourcemap: isDevelopment,
format: 'esm',
platform: 'node',
// Default off for monorepo DX; enable per-package if publishing types
dts: false,
minify: isProduction,
// treeshake defaults to true; keep explicit only if you want it disabled in dev
// treeshake: isProduction,
🤖 Prompt for AI Agents
packages/build-config/src/tsdown.base.ts lines 23-29: the baseConfig currently
sets dts: isDevelopment and explicitly sets treeshake; update the base config to
set dts: false (enable dts only per-package where needed) and remove the
treeshake property so default treeshake behavior is used (only add treeshake
back when you need to override the default).

Comment on lines +30 to +32
// Keep all npm dependencies external (available via node_modules)
external: [/^[^@./]/, /^@(?!tm\/)/]
};
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick

Externalization strategy: rely on tsdown defaults and use noExternal per package

Tsdown already treats dependencies/peerDependencies as external and bundles others by default. Keeping a broad regex here can fight with package‑level overrides and make devDependencies resolution surprising. Prefer removing external from base and let packages opt‑in with noExternal: [/^@tm\//] where bundling internal workspaces is desired. (tsdown.dev)

-  // Keep all npm dependencies external (available via node_modules)
-  external: [/^[^@./]/, /^@(?!tm\/)/]
+  // Defer dependency handling to package-level configs (external/noExternal)
+  // external: [...]
📝 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
// Keep all npm dependencies external (available via node_modules)
external: [/^[^@./]/, /^@(?!tm\/)/]
};
// Defer dependency handling to package-level configs (external/noExternal)
// external: [...]
};
🤖 Prompt for AI Agents
In packages/build-config/src/tsdown.base.ts around lines 30-32, the base config
sets a broad external regex which overrides tsdown defaults and interferes with
package-level overrides; remove the external: [/^[^@./]/, /^@(?!tm\/)/] entry
from the base config so tsdown can use its defaults, and adjust packages that
need to bundle internal workspaces to opt in by setting noExternal: [/^@tm\//]
in their package-specific tsdown config.

Crunchyman-ralph and others added 3 commits September 17, 2025 21:21
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (3)
.github/workflows/ci.yml (3)

41-41: Use npm ci; Yarn-only flags will fail the workflow.

--frozen-lockfile is a Yarn/pnpm flag and will cause npm install to error. Use npm ci for reproducible installs.

- run: npm install --frozen-lockfile --prefer-offline
+ run: npm ci

Apply the same change in all four install steps.

Also applies to: 64-64, 87-87, 112-112


72-95: Tests won’t see build outputs across jobs; pass artifacts or rebuild in Test.

Jobs run on separate runners. If tests import from dist (as recent changes suggest), they’ll miss build outputs unless you transfer them or rebuild.

Option A — transfer build artifacts:

   build:
@@
       - name: Build
         run: npm run turbo:build
         env:
           NODE_ENV: production
           FORCE_COLOR: 1
+      - name: Upload build artifacts
+        uses: actions/upload-artifact@v4
+        with:
+          name: build-dist
+          path: |
+            **/dist/**
+          if-no-files-found: error
@@
   test:
@@
       - name: Install dependencies
-        run: npm install --frozen-lockfile --prefer-offline
+        run: npm ci
         timeout-minutes: 5
+
+      - name: Download build artifacts
+        uses: actions/download-artifact@v4
+        with:
+          name: build-dist

Option B — simply run the build again in Test before running Jest.

Also applies to: 96-122


123-132: Make artifact upload resilient; ensure JUnit is actually produced.

If test-results, coverage, or junit.xml don’t exist, uploads may warn/fail. Add a guard and confirm your Jest JUnit reporter is configured.

       - name: Upload Test Results
         if: always()
         uses: actions/upload-artifact@v4
         with:
           name: test-results
           path: |
             test-results
             coverage
             junit.xml
+          if-no-files-found: ignore
           retention-days: 30

If JUnit is expected, ensure a reporter (e.g., jest-junit) writes junit.xml.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1d8da49 and 3d2123e.

📒 Files selected for processing (1)
  • .github/workflows/ci.yml (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/package.json:13-64
Timestamp: 2025-09-03T12:16:15.866Z
Learning: For internal packages in the claude-task-master project, Crunchyman-ralph prefers pointing package.json "types" entries to src .ts files rather than dist .d.ts files for better developer experience (DX), as the packages are not being exported as SDKs.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-11T12:30:23.843Z
Learning: Import Task Master's development workflow commands and guidelines; treat the contents of ./.taskmaster/CLAUDE.md as if included in the main CLAUDE.md
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1211
File: jest.resolver.cjs:8-15
Timestamp: 2025-09-17T19:09:08.856Z
Learning: In the eyaltoledano/claude-task-master project, the team only uses .ts files and does not plan to use .tsx or .mts extensions, so Jest resolver and build tooling should focus on .js → .ts mapping only.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tasks.mdc:0-0
Timestamp: 2025-07-18T17:14:29.399Z
Learning: Applies to scripts/modules/task-manager.js : Use consistent formatting for task files, include all task properties in text files, and format dependencies with status indicators.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Use sample task fixtures for consistent test data, mock file system operations, and test both success and error paths for task operations.
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/src/auth/config.ts:5-7
Timestamp: 2025-09-02T21:51:27.921Z
Learning: The user Crunchyman-ralph prefers not to use node: scheme imports (e.g., 'node:os', 'node:path') for Node.js core modules and considers suggestions to change bare imports to node: scheme as too nitpicky.
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Run npm run test:coverage before commits to ensure all tests pass with sufficient coverage

Applied to files:

  • .github/workflows/ci.yml

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (4)
.github/workflows/ci.yml (2)

41-41: Fix CI installs: npm doesn’t support --frozen-lockfile. Use npm ci.

npm install --frozen-lockfile will error on npm. Replace with npm ci for deterministic installs.

Apply:

- run: npm install --frozen-lockfile --prefer-offline
+ run: npm ci

Repeat this change in all four steps above.

Also applies to: 64-64, 87-87, 112-112


115-117: Don’t override Jest coverage thresholds in CI.

You’re passing 0% thresholds on the CLI, bypassing jest.config.js (80%). Remove the CLI override.

- npm run test:coverage -- --coverageThreshold '{"global":{"branches":0,"functions":0,"lines":0,"statements":0}}' --detectOpenHandles --forceExit
+ npm run test:coverage -- --detectOpenHandles --forceExit
packages/build-config/package.json (2)

15-15: Update keywords to reflect tsdown migration.

-  "keywords": ["build-config", "tsup", "monorepo"],
+  "keywords": ["build-config", "tsdown", "monorepo"],

22-28: Replace leftover "tsup" with "tsdown" in packages/build-config/package.json

  • Remove "tsup" from "dependencies" and add "tsdown" to "dependencies" (not devDependencies) — packages/build-config/src/tsdown.base.ts imports type { UserConfig } from 'tsdown' and the published .d.ts will require it at install time.
  • Location: packages/build-config/package.json (see packages/build-config/src/tsdown.base.ts:5). Pick the repo-standard tsdown semver.
♻️ Duplicate comments (3)
packages/build-config/src/tsdown.base.ts (3)

13-17: Export isTest alongside NODE_ENV flags.

Keeps checks consistent across packages.

 export const env = {
   isProduction,
   isDevelopment,
-  NODE_ENV: process.env.NODE_ENV || 'development'
+  NODE_ENV: process.env.NODE_ENV || 'development',
+  isTest: process.env.NODE_ENV === 'test'
 };

23-29: Default dts off; avoid toggling treeshake.

Tsdown auto‑emits dts when a package declares types; for internal DX keep off by default and enable per package. Treeshake defaults are fine.

 export const baseConfig: Partial<UserConfig> = {
   sourcemap: isDevelopment,
   format: 'esm',
   platform: 'node',
-  dts: isDevelopment,
+  // Default off for monorepo DX; enable per‑package if publishing types
+  dts: false,
   minify: isProduction,
-  treeshake: isProduction,
+  // Use tsdown defaults unless overriding
+  // treeshake: isProduction,

30-32: Let tsdown handle externals; use noExternal per package.

The broad regex fights per‑package overrides; tsdown already externalizes deps/peers.

-  // Keep all npm dependencies external (available via node_modules)
-  external: [/^[^@./]/, /^@(?!tm\/)/]
+  // Defer dependency handling to package-level configs (external/noExternal)
+  // external: [...]

If you keep this, add a note that noExternal takes precedence.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3d2123e and 6cfd3b7.

📒 Files selected for processing (5)
  • .github/workflows/ci.yml (1 hunks)
  • jest.config.js (2 hunks)
  • jest.resolver.cjs (1 hunks)
  • packages/build-config/package.json (1 hunks)
  • packages/build-config/src/tsdown.base.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.js

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

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

Files:

  • jest.config.js
jest.config.js

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

Create and maintain a production-ready Jest configuration in jest.config.js

Files:

  • jest.config.js
🧠 Learnings (26)
📓 Common learnings
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/package.json:13-64
Timestamp: 2025-09-03T12:16:15.866Z
Learning: For internal packages in the claude-task-master project, Crunchyman-ralph prefers pointing package.json "types" entries to src .ts files rather than dist .d.ts files for better developer experience (DX), as the packages are not being exported as SDKs.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-11T12:30:23.843Z
Learning: Import Task Master's development workflow commands and guidelines; treat the contents of ./.taskmaster/CLAUDE.md as if included in the main CLAUDE.md
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1211
File: jest.resolver.cjs:8-15
Timestamp: 2025-09-17T19:09:08.882Z
Learning: In the eyaltoledano/claude-task-master project, the team only uses .ts files and does not plan to use .tsx or .mts extensions, so Jest resolver and build tooling should focus on .js → .ts mapping only.
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tasks.mdc:0-0
Timestamp: 2025-07-18T17:14:29.399Z
Learning: Applies to scripts/modules/task-manager.js : Use consistent formatting for task files, include all task properties in text files, and format dependencies with status indicators.
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/src/auth/config.ts:5-7
Timestamp: 2025-09-02T21:51:27.921Z
Learning: The user Crunchyman-ralph prefers not to use node: scheme imports (e.g., 'node:os', 'node:path') for Node.js core modules and considers suggestions to change bare imports to node: scheme as too nitpicky.
📚 Learning: 2025-09-17T19:09:08.882Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1211
File: jest.resolver.cjs:8-15
Timestamp: 2025-09-17T19:09:08.882Z
Learning: In the eyaltoledano/claude-task-master project, the team only uses .ts files and does not plan to use .tsx or .mts extensions, so Jest resolver and build tooling should focus on .js → .ts mapping only.

Applied to files:

  • jest.config.js
  • jest.resolver.cjs
  • packages/build-config/package.json
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Applies to jest.config.js : Create and maintain a production-ready Jest configuration in jest.config.js

Applied to files:

  • jest.config.js
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Applies to **/?(*.)+(spec|test).ts : In JavaScript/TypeScript projects using Jest, test files should match *.test.ts and *.spec.ts patterns

Applied to files:

  • jest.config.js
  • jest.resolver.cjs
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Applies to **/__tests__/**/*.ts : In JavaScript/TypeScript projects using Jest, test files should be located in __tests__ directories or match *.test.ts and *.spec.ts patterns

Applied to files:

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

Applied to files:

  • jest.config.js
  • jest.resolver.cjs
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Use test-specific file paths (e.g., 'test-tasks.json') for all file operations in tests.

Applied to files:

  • jest.config.js
  • jest.resolver.cjs
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Run npm run test:coverage before commits to ensure all tests pass with sufficient coverage

Applied to files:

  • .github/workflows/ci.yml
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Do not rely on environment variables for API keys in tests; set mock environment variables in test setup.

Applied to files:

  • packages/build-config/src/tsdown.base.ts
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to tests/{unit,integration,e2e}/**/*.test.js : Explicitly handle all options, including defaults and shorthand flags (e.g., -p for --prompt), and include null/undefined checks in test implementations for parameters that might be optional.

Applied to files:

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

Applied to files:

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

Applied to files:

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

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Create self-contained test implementations rather than using real implementations when testing modules with initialization issues.

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Use different file paths for each test to avoid test interdependence.

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-07-18T17:16:13.793Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/tests.mdc:0-0
Timestamp: 2025-07-18T17:16:13.793Z
Learning: Applies to **/*.test.js : Do not test exact error messages; test for error presence and general properties instead.

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-07-18T17:10:31.810Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/git_workflow.mdc:0-0
Timestamp: 2025-07-18T17:10:31.810Z
Learning: Applies to **/*.{test,spec}.{js,ts,jsx,tsx} : Create a test file if needed and ensure all tests pass before completing a task

Applied to files:

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

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-09-03T12:16:15.866Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/package.json:13-64
Timestamp: 2025-09-03T12:16:15.866Z
Learning: For internal packages in the claude-task-master project, Crunchyman-ralph prefers pointing package.json "types" entries to src .ts files rather than dist .d.ts files for better developer experience (DX), as the packages are not being exported as SDKs.

Applied to files:

  • jest.resolver.cjs
  • packages/build-config/package.json
📚 Learning: 2025-09-02T21:51:27.921Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/src/auth/config.ts:5-7
Timestamp: 2025-09-02T21:51:27.921Z
Learning: The user Crunchyman-ralph prefers not to use node: scheme imports (e.g., 'node:os', 'node:path') for Node.js core modules and considers suggestions to change bare imports to node: scheme as too nitpicky.

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-09-17T19:08:57.882Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1211
File: tests/integration/cli/complex-cross-tag-scenarios.test.js:20-22
Timestamp: 2025-09-17T19:08:57.882Z
Learning: The user Crunchyman-ralph confirmed that in their build pipeline, they assume dist/ artifacts are already built by the time tests run, when tests reference dist/task-master.js instead of bin/task-master.js.

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-09-03T12:45:30.724Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/src/subpath-exports.test.ts:6-9
Timestamp: 2025-09-03T12:45:30.724Z
Learning: The user Crunchyman-ralph prefers to avoid overly nitpicky or detailed suggestions in code reviews, especially for test coverage of minor import paths. Focus on more substantial issues rather than comprehensive coverage of all possible edge cases.

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-08-02T15:33:22.656Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1069
File: .changeset/fix-tag-complexity-detection.md:0-0
Timestamp: 2025-08-02T15:33:22.656Z
Learning: For changeset files (.changeset/*.md), Crunchyman-ralph prefers to ignore formatting nitpicks about blank lines between frontmatter and descriptions, as he doesn't mind having them and wants to avoid such comments in future reviews.

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-09-03T13:46:00.640Z
Learnt from: Crunchyman-ralph
PR: eyaltoledano/claude-task-master#1178
File: packages/tm-core/src/auth/oauth-service.ts:20-20
Timestamp: 2025-09-03T13:46:00.640Z
Learning: For Node.js v22 and later, JSON imports should use `with { type: 'json' }` syntax, not `assert { type: 'json' }`. The `assert` syntax was removed in Node.js v22 in favor of the `with` syntax for import attributes. This applies to the eyaltoledano/claude-task-master codebase which uses Node.js v24.

Applied to files:

  • jest.resolver.cjs
📚 Learning: 2025-08-03T12:13:33.875Z
Learnt from: CR
PR: eyaltoledano/claude-task-master#0
File: .cursor/rules/test_workflow.mdc:0-0
Timestamp: 2025-08-03T12:13:33.875Z
Learning: Applies to {tests/setup.ts,tests/setup/integration.ts,tests/teardown.ts} : Test setup files should be created at tests/setup.ts, tests/setup/integration.ts, and tests/teardown.ts

Applied to files:

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

Applied to files:

  • jest.resolver.cjs
🧬 Code graph analysis (1)
packages/build-config/src/tsdown.base.ts (1)
apps/extension/src/webview/utils/logger.ts (1)
  • isDevelopment (34-47)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test
🔇 Additional comments (6)
.github/workflows/ci.yml (2)

14-16: Concurrency grouping: LGTM.

Correctly prefers PR number and cancels in‑flight runs for the same PR.


35-38: Use .nvmrc for actions/setup-node (don’t hardcode Node versions).

Found .nvmrc = 22 (package.json engines.node = ">=18.0.0") but workflows hardcode node-version: 20 — switch setup-node to read .nvmrc to avoid drift. Apply across all setup-node steps (e.g. .github/workflows/ci.yml at lines 35,58,81,106).

-      - uses: actions/setup-node@v4
-        with:
-          node-version: 20
-          cache: "npm"
+      - uses: actions/setup-node@v4
+        with:
+          node-version-file: '.nvmrc'
+          cache: 'npm'

Likely an incorrect or invalid review comment.

packages/build-config/src/tsdown.base.ts (1)

38-46: mergeConfig: LGTM.

Simple, readable shallow merge; param rename avoids shadowing.

jest.resolver.cjs (1)

1-19: Resolver: LGTM for .js → .ts (relative) fallback.

Clean error chaining and safe scoping to relative specifiers.

Please run a local Jest pass once to confirm NodeNext path cases still resolve as expected.

jest.config.js (2)

21-31: TS‑Jest ESM wiring: LGTM.

Preset, extensionsToTreatAsEsm, transform for .ts, and resolver are coherent.


17-19: Include .ts in testMatch or TypeScript tests won’t run.

Add TS patterns while keeping JS.

File: jest.config.js — lines 17–19

- testMatch: ['**/__tests__/**/*.js', '**/?(*.)+(spec|test).js'],
+ testMatch: [
+   '**/__tests__/**/*.ts',
+   '**/?(*.)+(spec|test).ts',
+   '**/__tests__/**/*.js',
+   '**/?(*.)+(spec|test).js'
+],

Run: npx jest --listTests to confirm .ts tests are discovered.

@Crunchyman-ralph Crunchyman-ralph merged commit 3c41a11 into next Sep 17, 2025
4 of 5 checks passed
@Crunchyman-ralph Crunchyman-ralph deleted the ralph/chore/move.to.tsdown branch September 17, 2025 19:55
Crunchyman-ralph added a commit that referenced this pull request Sep 17, 2025
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
sfc-gh-dflippo pushed a commit to sfc-gh-dflippo/task-master-ai that referenced this pull request Dec 4, 2025
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
sfc-gh-dflippo pushed a commit to sfc-gh-dflippo/task-master-ai that referenced this pull request Dec 4, 2025
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
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.

1 participant