Compare commits

..

17 Commits

Author SHA1 Message Date
Ralph Khreish
b594795238 chore: run format to resolve CI issues 2025-08-01 00:14:25 +03:00
Carl Mercier
8f97b6aead refactor: normalize IDs once when loading JSON instead of scattered calls
- Normalize all tags' data when creating _rawTaggedData in readJSON
- Add support for handling malformed dotted subtask IDs (e.g., "5.1" -> 1)
- Remove redundant normalizeTaskIds calls from set-task-status, add-task, and move-task
- Add comprehensive test for mixed ID formats (string IDs and dotted notation)
- Cleaner, more maintainable solution that normalizes IDs at load time

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-01 00:14:25 +03:00
Carl Mercier
3f31c34f8d Simplified implementation 2025-08-01 00:14:25 +03:00
Carl Mercier
ef23beac0d fix: normalize task IDs to numbers on load to fix comparison issues
- Added normalizeTaskIds function to convert string IDs to numbers
- Applied normalization in readJSON for all code paths
- Fixed set-task-status, add-task, and move-task to normalize IDs when working with raw data
- Exported normalizeTaskIds function for use in other modules
- Added test case for string ID normalization

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-01 00:14:25 +03:00
Carl Mercier
077cbb99de Update scripts/modules/utils.js
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-01 00:14:25 +03:00
Carl Mercier
ee2af1760f Update scripts/modules/utils.js
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-01 00:14:25 +03:00
Carl Mercier
2421c205c4 Update scripts/modules/utils.js
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-08-01 00:14:25 +03:00
Carl Mercier
33208388bd Fix formatting once and for all 2025-08-01 00:14:25 +03:00
Carl Mercier
3fa0c7f7af Don't mess up formatting 2025-08-01 00:14:25 +03:00
Carl Mercier
0609b9ae28 Added test 2025-08-01 00:14:25 +03:00
Carl Mercier
b79eb4f7a2 fix: normalize task IDs to numbers on load to fix comparison issues
When tasks.json contains string IDs (e.g., "5" instead of 5), task lookups
fail because the code uses parseInt() and strict equality (===) for comparisons.

This fix normalizes all task and subtask IDs to numbers when loading the JSON,
ensuring consistent comparisons throughout the codebase without requiring
changes to multiple comparison locations.

Fixes task not found errors when using string IDs in tasks.json.
2025-08-01 00:14:25 +03:00
Ben Vargas
45a14c323d fix: remove default value from complexity report option to enable tag-specific detection (#1049)
Removes the default empty array value from the complexity report option to properly detect when tags are explicitly provided vs when no tags are provided, fixing the expand --all command behavior with tagged tasks.

Co-authored-by: Ben Vargas <ben@example.com>
2025-07-26 15:26:45 +02:00
github-actions[bot]
29e67fafa4 Version Packages (#1050)
* Version Packages

* chore: fix release 0.22

todo: fix CI

* chore: run format

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
2025-07-26 00:45:07 +02:00
Ralph Khreish
43e4d7c9d3 Release 0.22 #1038 from eyaltoledano/next
Release 0.22
2025-07-26 01:24:38 +03:00
Ralph Khreish
1bd1e64cac feat: add pull request templates for bug fixes, features, and integrations (#1044)
* feat: add pull request templates for bug fixes, features, and integrations

- Introduced a comprehensive pull request template structure to streamline contributions.
- Added specific templates for bug fixes, new features, and integrations to enhance clarity and consistency in PR submissions.
- Configured the pull request template settings for better user guidance during the contribution process.

* chore: fix format

* Update .github/PULL_REQUEST_TEMPLATE.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update .github/PULL_REQUEST_TEMPLATE.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update .github/PULL_REQUEST_TEMPLATE.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* chore: implement PR requested changes

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-07-24 17:33:43 +02:00
Ralph Khreish
dc44ed9de8 feat: Improved the CLI user interface to suggest generating a complexity report if it is missing, instead of showing an error. (#1043)
* feat: fix CLI UI error when trying to display non-existent complexity report

* chore: fix git issue

* chore: run format

* Update .changeset/thick-squids-attend.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update .changeset/thick-squids-attend.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

* Update .changeset/thick-squids-attend.md

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
2025-07-24 15:50:18 +02:00
github-actions[bot]
31b8407dbc chore: rc version bump 2025-07-23 16:29:49 +00:00
20 changed files with 436 additions and 70 deletions

View File

@@ -0,0 +1,5 @@
---
"task-master-ai": patch
---
Fix for tasks not found when using string IDs

View File

@@ -1,5 +0,0 @@
---
"task-master-ai": patch
---
Fix compatibility with @google/gemini-cli-core v0.1.12+ by updating ai-sdk-provider-gemini-cli to v0.1.1.

View File

@@ -0,0 +1,7 @@
---
"task-master-ai": patch
---
Fix tag-specific complexity report detection in expand command
The expand command now correctly finds and uses tag-specific complexity reports (e.g., `task-complexity-report_feature-xyz.json`) when operating in a tag context. Previously, it would always look for the generic `task-complexity-report.json` file due to a default value in the CLI option definition.

View File

@@ -1,5 +0,0 @@
---
"task-master-ai": patch
---
Fix 'expand --all' and 'show' commands to correctly handle tag contexts for complexity reports and task display.

View File

@@ -1,5 +0,0 @@
---
"task-master-ai": patch
---
Clean up remaining automatic task file generation calls

View File

@@ -1,24 +0,0 @@
---
"task-master-ai": minor
---
Add comprehensive Kiro IDE integration with autonomous task management hooks
- **Kiro Profile**: Added full support for Kiro IDE with automatic installation of 7 Taskmaster agent hooks
- **Hook-Driven Workflow**: Introduced natural language automation hooks that eliminate manual task status updates
- **Automatic Hook Installation**: Hooks are now automatically copied to `.kiro/hooks/` when running `task-master rules add kiro`
- **Language-Agnostic Support**: All hooks support multiple programming languages (JS, Python, Go, Rust, Java, etc.)
- **Frontmatter Transformation**: Kiro rules use simplified `inclusion: always` format instead of Cursor's complex frontmatter
- **Special Rule**: Added `taskmaster_hooks_workflow.md` that guides AI assistants to prefer hook-driven completion
Key hooks included:
- Task Dependency Auto-Progression: Automatically starts tasks when dependencies complete
- Code Change Task Tracker: Updates task progress as you save files
- Test Success Task Completer: Marks tasks done when tests pass
- Daily Standup Assistant: Provides personalized task status summaries
- PR Readiness Checker: Validates task completion before creating pull requests
- Complexity Analyzer: Auto-expands complex tasks into manageable subtasks
- Git Commit Task Linker: Links commits to tasks for better traceability
This creates a truly autonomous development workflow where task management happens naturally as you code!

View File

@@ -1,10 +0,0 @@
---
"task-master-ai": patch
---
Fix max_tokens limits for OpenRouter and Groq models
- Add special handling in config-manager.js for custom OpenRouter models to use a conservative default of 32,768 max_tokens
- Update qwen/qwen-turbo model max_tokens from 1,000,000 to 32,768 to match OpenRouter's actual limits
- Fix moonshotai/kimi-k2-instruct max_tokens to 16,384 to match Groq's actual limit (fixes #1028)
- This prevents "maximum context length exceeded" errors when using OpenRouter models not in our supported models list

View File

@@ -1,5 +0,0 @@
---
"task-master-ai": patch
---
Fix VSCode profile generation to use correct rule file names (using `.instructions.md` extension instead of `.md`) and front-matter properties (removing the unsupported `alwaysApply` property from instructions files' front-matter).

45
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,45 @@
# What type of PR is this?
<!-- Check one -->
- [ ] 🐛 Bug fix
- [ ] ✨ Feature
- [ ] 🔌 Integration
- [ ] 📝 Docs
- [ ] 🧹 Refactor
- [ ] Other:
## Description
<!-- What does this PR do? -->
## Related Issues
<!-- Link issues: Fixes #123 -->
## How to Test This
<!-- Quick steps to verify the changes work -->
```bash
# Example commands or steps
```
**Expected result:**
<!-- What should happen? -->
## 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
<!-- One line describing the change for users -->
<!-- Example: "Added Kiro IDE integration with automatic task status updates" -->
---
### For Maintainers
- [ ] PR title follows conventional commits
- [ ] Target branch correct
- [ ] Labels added
- [ ] Milestone assigned (if applicable)

39
.github/PULL_REQUEST_TEMPLATE/bugfix.md vendored Normal file
View File

@@ -0,0 +1,39 @@
## 🐛 Bug Fix
### 🔍 Bug Description
<!-- Describe the bug -->
### 🔗 Related Issues
<!-- Fixes #123 -->
### ✨ Solution
<!-- How does this PR fix the bug? -->
## How to Test
### Steps that caused the bug:
1.
2.
**Before fix:**
**After fix:**
### Quick verification:
```bash
# Commands to verify the fix
```
## Contributor Checklist
- [ ] Created changeset: `npm run changeset`
- [ ] Tests pass: `npm test`
- [ ] Format check passes: `npm run format-check`
- [ ] Addressed CodeRabbit comments
- [ ] Added unit tests (if applicable)
- [ ] Manually verified the fix works
---
### For Maintainers
- [ ] Root cause identified
- [ ] Fix doesn't introduce new issues
- [ ] CI passes

View File

@@ -0,0 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: 🐛 Bug Fix
url: https://github.com/eyaltoledano/claude-task-master/compare/next...HEAD?template=bugfix.md
about: Fix a bug in Task Master
- name: ✨ New Feature
url: https://github.com/eyaltoledano/claude-task-master/compare/next...HEAD?template=feature.md
about: Add a new feature to Task Master
- name: 🔌 New Integration
url: https://github.com/eyaltoledano/claude-task-master/compare/next...HEAD?template=integration.md
about: Add support for a new tool, IDE, or platform

View File

@@ -0,0 +1,49 @@
## ✨ New Feature
### 📋 Feature Description
<!-- Brief description -->
### 🎯 Problem Statement
<!-- What problem does this feature solve? Why is it needed? -->
### 💡 Solution
<!-- How does this feature solve the problem? What's the approach? -->
### 🔗 Related Issues
<!-- Link related issues: Fixes #123, Part of #456 -->
## How to Use It
### Quick Start
```bash
# Basic usage example
```
### Example
<!-- Show a real use case -->
```bash
# Practical example
```
**What you should see:**
<!-- Expected behavior -->
## Contributor Checklist
- [ ] Created changeset: `npm run changeset`
- [ ] Tests pass: `npm test`
- [ ] Format check passes: `npm run format-check`
- [ ] Addressed CodeRabbit comments
- [ ] Added tests for new functionality
- [ ] Manually tested in CLI mode
- [ ] Manually tested in MCP mode (if applicable)
## Changelog Entry
<!-- One-liner for release notes -->
---
### For Maintainers
- [ ] Feature aligns with project vision
- [ ] CIs pass
- [ ] Changeset file exists

View File

@@ -0,0 +1,53 @@
# 🔌 New Integration
## What tool/IDE is being integrated?
<!-- Name and brief description -->
## What can users do with it?
<!-- Key benefits -->
## How to Enable
### Setup
```bash
task-master rules add [name]
# Any other setup steps
```
### Example Usage
<!-- Show it in action -->
```bash
# Real example
```
### Natural Language Hooks (if applicable)
```
"When tests pass, mark task as done"
# Other examples
```
## Contributor Checklist
- [ ] Created changeset: `npm run changeset`
- [ ] Tests pass: `npm test`
- [ ] Format check passes: `npm run format-check`
- [ ] Addressed CodeRabbit comments
- [ ] Integration fully tested with target tool/IDE
- [ ] Error scenarios tested
- [ ] Added integration tests
- [ ] Documentation includes setup guide
- [ ] Examples are working and clear
---
## For Maintainers
- [ ] Integration stability verified
- [ ] Documentation comprehensive
- [ ] Examples working

View File

@@ -1,5 +1,91 @@
# task-master-ai
## 0.22.0
### Minor Changes
- [#1043](https://github.com/eyaltoledano/claude-task-master/pull/1043) [`dc44ed9`](https://github.com/eyaltoledano/claude-task-master/commit/dc44ed9de8a57aca5d39d3a87565568bd0a82068) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Prompt to generate a complexity report when it is missing
- [#1032](https://github.com/eyaltoledano/claude-task-master/pull/1032) [`4423119`](https://github.com/eyaltoledano/claude-task-master/commit/4423119a5ec53958c9dffa8bf564da8be7a2827d) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Add comprehensive Kiro IDE integration with autonomous task management hooks
- **Kiro Profile**: Added full support for Kiro IDE with automatic installation of 7 Taskmaster agent hooks
- **Hook-Driven Workflow**: Introduced natural language automation hooks that eliminate manual task status updates
- **Automatic Hook Installation**: Hooks are now automatically copied to `.kiro/hooks/` when running `task-master rules add kiro`
- **Language-Agnostic Support**: All hooks support multiple programming languages (JS, Python, Go, Rust, Java, etc.)
- **Frontmatter Transformation**: Kiro rules use simplified `inclusion: always` format instead of Cursor's complex frontmatter
- **Special Rule**: Added `taskmaster_hooks_workflow.md` that guides AI assistants to prefer hook-driven completion
Key hooks included:
- Task Dependency Auto-Progression: Automatically starts tasks when dependencies complete
- Code Change Task Tracker: Updates task progress as you save files
- Test Success Task Completer: Marks tasks done when tests pass
- Daily Standup Assistant: Provides personalized task status summaries
- PR Readiness Checker: Validates task completion before creating pull requests
- Complexity Analyzer: Auto-expands complex tasks into manageable subtasks
- Git Commit Task Linker: Links commits to tasks for better traceability
This creates a truly autonomous development workflow where task management happens naturally as you code!
### Patch Changes
- [#1033](https://github.com/eyaltoledano/claude-task-master/pull/1033) [`7b90568`](https://github.com/eyaltoledano/claude-task-master/commit/7b9056832653464f934c91c22997077065d738c4) Thanks [@ben-vargas](https://github.com/ben-vargas)! - Fix compatibility with @google/gemini-cli-core v0.1.12+ by updating ai-sdk-provider-gemini-cli to v0.1.1.
- [#1038](https://github.com/eyaltoledano/claude-task-master/pull/1038) [`77cc5e4`](https://github.com/eyaltoledano/claude-task-master/commit/77cc5e4537397642f2664f61940a101433ee6fb4) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix 'expand --all' and 'show' commands to correctly handle tag contexts for complexity reports and task display.
- [#1025](https://github.com/eyaltoledano/claude-task-master/pull/1025) [`8781794`](https://github.com/eyaltoledano/claude-task-master/commit/8781794c56d454697fc92c88a3925982d6b81205) Thanks [@joedanz](https://github.com/joedanz)! - Clean up remaining automatic task file generation calls
- [#1035](https://github.com/eyaltoledano/claude-task-master/pull/1035) [`fb7d588`](https://github.com/eyaltoledano/claude-task-master/commit/fb7d588137e8c53b0d0f54bd1dd8d387648583ee) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix max_tokens limits for OpenRouter and Groq models
- Add special handling in config-manager.js for custom OpenRouter models to use a conservative default of 32,768 max_tokens
- Update qwen/qwen-turbo model max_tokens from 1,000,000 to 32,768 to match OpenRouter's actual limits
- Fix moonshotai/kimi-k2-instruct max_tokens to 16,384 to match Groq's actual limit (fixes #1028)
- This prevents "maximum context length exceeded" errors when using OpenRouter models not in our supported models list
- [#1027](https://github.com/eyaltoledano/claude-task-master/pull/1027) [`6ae66b2`](https://github.com/eyaltoledano/claude-task-master/commit/6ae66b2afbfe911340fa25e0236c3db83deaa7eb) Thanks [@andreswebs](https://github.com/andreswebs)! - Fix VSCode profile generation to use correct rule file names (using `.instructions.md` extension instead of `.md`) and front-matter properties (removing the unsupported `alwaysApply` property from instructions files' front-matter).
## 0.22.0-rc.1
### Minor Changes
- [#1043](https://github.com/eyaltoledano/claude-task-master/pull/1043) [`dc44ed9`](https://github.com/eyaltoledano/claude-task-master/commit/dc44ed9de8a57aca5d39d3a87565568bd0a82068) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Prompt to generate a complexity report when it is missing
## 0.22.0-rc.0
### Minor Changes
- [#1032](https://github.com/eyaltoledano/claude-task-master/pull/1032) [`4423119`](https://github.com/eyaltoledano/claude-task-master/commit/4423119a5ec53958c9dffa8bf564da8be7a2827d) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Add comprehensive Kiro IDE integration with autonomous task management hooks
- **Kiro Profile**: Added full support for Kiro IDE with automatic installation of 7 Taskmaster agent hooks
- **Hook-Driven Workflow**: Introduced natural language automation hooks that eliminate manual task status updates
- **Automatic Hook Installation**: Hooks are now automatically copied to `.kiro/hooks/` when running `task-master rules add kiro`
- **Language-Agnostic Support**: All hooks support multiple programming languages (JS, Python, Go, Rust, Java, etc.)
- **Frontmatter Transformation**: Kiro rules use simplified `inclusion: always` format instead of Cursor's complex frontmatter
- **Special Rule**: Added `taskmaster_hooks_workflow.md` that guides AI assistants to prefer hook-driven completion
Key hooks included:
- Task Dependency Auto-Progression: Automatically starts tasks when dependencies complete
- Code Change Task Tracker: Updates task progress as you save files
- Test Success Task Completer: Marks tasks done when tests pass
- Daily Standup Assistant: Provides personalized task status summaries
- PR Readiness Checker: Validates task completion before creating pull requests
- Complexity Analyzer: Auto-expands complex tasks into manageable subtasks
- Git Commit Task Linker: Links commits to tasks for better traceability
This creates a truly autonomous development workflow where task management happens naturally as you code!
### Patch Changes
- [#1033](https://github.com/eyaltoledano/claude-task-master/pull/1033) [`7b90568`](https://github.com/eyaltoledano/claude-task-master/commit/7b9056832653464f934c91c22997077065d738c4) Thanks [@ben-vargas](https://github.com/ben-vargas)! - Fix compatibility with @google/gemini-cli-core v0.1.12+ by updating ai-sdk-provider-gemini-cli to v0.1.1.
- [#1038](https://github.com/eyaltoledano/claude-task-master/pull/1038) [`77cc5e4`](https://github.com/eyaltoledano/claude-task-master/commit/77cc5e4537397642f2664f61940a101433ee6fb4) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix 'expand --all' and 'show' commands to correctly handle tag contexts for complexity reports and task display.
- [#1025](https://github.com/eyaltoledano/claude-task-master/pull/1025) [`8781794`](https://github.com/eyaltoledano/claude-task-master/commit/8781794c56d454697fc92c88a3925982d6b81205) Thanks [@joedanz](https://github.com/joedanz)! - Clean up remaining automatic task file generation calls
- [#1035](https://github.com/eyaltoledano/claude-task-master/pull/1035) [`fb7d588`](https://github.com/eyaltoledano/claude-task-master/commit/fb7d588137e8c53b0d0f54bd1dd8d387648583ee) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix max_tokens limits for OpenRouter and Groq models
- Add special handling in config-manager.js for custom OpenRouter models to use a conservative default of 32,768 max_tokens
- Update qwen/qwen-turbo model max_tokens from 1,000,000 to 32,768 to match OpenRouter's actual limits
- Fix moonshotai/kimi-k2-instruct max_tokens to 16,384 to match Groq's actual limit (fixes #1028)
- This prevents "maximum context length exceeded" errors when using OpenRouter models not in our supported models list
- [#1027](https://github.com/eyaltoledano/claude-task-master/pull/1027) [`6ae66b2`](https://github.com/eyaltoledano/claude-task-master/commit/6ae66b2afbfe911340fa25e0236c3db83deaa7eb) Thanks [@andreswebs](https://github.com/andreswebs)! - Fix VSCode profile generation to use correct rule file names (using `.instructions.md` extension instead of `.md`) and front-matter properties (removing the unsupported `alwaysApply` property from instructions files' front-matter).
## 0.21.0
### Minor Changes

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "task-master-ai",
"version": "0.21.0",
"version": "0.22.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "task-master-ai",
"version": "0.21.0",
"version": "0.22.0",
"license": "MIT WITH Commons-Clause",
"workspaces": [
"apps/*",

View File

@@ -1,6 +1,6 @@
{
"name": "task-master-ai",
"version": "0.21.0",
"version": "0.22.0",
"description": "A task management system for ambitious AI-driven development that doesn't overwhelm and confuse Cursor.",
"main": "index.js",
"type": "module",

View File

@@ -1564,8 +1564,8 @@ function registerCommands(programInstance) {
) // Allow file override
.option(
'-cr, --complexity-report <file>',
'Path to the report file',
COMPLEXITY_REPORT_FILE
'Path to the complexity report file (use this to specify the complexity report, not --file)'
// Removed default value to allow tag-specific auto-detection
)
.option('--tag <tag>', 'Specify tag context for task operations')
.action(async (options) => {

View File

@@ -9,6 +9,7 @@ import boxen from 'boxen';
import ora from 'ora';
import Table from 'cli-table3';
import gradient from 'gradient-string';
import readline from 'readline';
import {
log,
findTaskById,
@@ -1682,18 +1683,15 @@ async function displayComplexityReport(reportPath) {
)
);
const readline = require('readline').createInterface({
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const answer = await new Promise((resolve) => {
readline.question(
chalk.cyan('Generate complexity report? (y/n): '),
resolve
);
rl.question(chalk.cyan('Generate complexity report? (y/n): '), resolve);
});
readline.close();
rl.close();
if (answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes') {
// Call the analyze-complexity command
@@ -1974,8 +1972,6 @@ async function confirmTaskOverwrite(tasksPath) {
)
);
// Use dynamic import to get the readline module
const readline = await import('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
@@ -2463,8 +2459,6 @@ async function displayMultipleTasksSummary(
)
);
// Use dynamic import for readline
const readline = await import('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout

View File

@@ -262,6 +262,43 @@ function hasTaggedStructure(data) {
return false;
}
/**
* Normalizes task IDs to ensure they are numbers instead of strings
* @param {Array} tasks - Array of tasks to normalize
*/
function normalizeTaskIds(tasks) {
if (!Array.isArray(tasks)) return;
tasks.forEach((task) => {
// Convert task ID to number with validation
if (task.id !== undefined) {
const parsedId = parseInt(task.id, 10);
if (!isNaN(parsedId) && parsedId > 0) {
task.id = parsedId;
}
}
// Convert subtask IDs to numbers with validation
if (Array.isArray(task.subtasks)) {
task.subtasks.forEach((subtask) => {
if (subtask.id !== undefined) {
// Check for dot notation (which shouldn't exist in storage)
if (typeof subtask.id === 'string' && subtask.id.includes('.')) {
// Extract the subtask part after the dot
const parts = subtask.id.split('.');
subtask.id = parseInt(parts[parts.length - 1], 10);
} else {
const parsedSubtaskId = parseInt(subtask.id, 10);
if (!isNaN(parsedSubtaskId) && parsedSubtaskId > 0) {
subtask.id = parsedSubtaskId;
}
}
}
});
}
});
}
/**
* Reads and parses a JSON file
* @param {string} filepath - Path to the JSON file
@@ -322,6 +359,8 @@ function readJSON(filepath, projectRoot = null, tag = null) {
console.log(`File is in legacy format, performing migration...`);
}
normalizeTaskIds(data.tasks);
// This is legacy format - migrate it to tagged format
const migratedData = {
master: {
@@ -401,6 +440,16 @@ function readJSON(filepath, projectRoot = null, tag = null) {
// Store reference to the raw tagged data for functions that need it
const originalTaggedData = JSON.parse(JSON.stringify(data));
// Normalize IDs in all tags before storing as originalTaggedData
for (const tagName in originalTaggedData) {
if (
originalTaggedData[tagName] &&
Array.isArray(originalTaggedData[tagName].tasks)
) {
normalizeTaskIds(originalTaggedData[tagName].tasks);
}
}
// Check and auto-switch git tags if enabled (for existing tagged format)
// This needs to run synchronously BEFORE tag resolution
if (projectRoot) {
@@ -448,6 +497,8 @@ function readJSON(filepath, projectRoot = null, tag = null) {
// Get the data for the resolved tag
const tagData = data[resolvedTag];
if (tagData && tagData.tasks) {
normalizeTaskIds(tagData.tasks);
// Add the _rawTaggedData property and the resolved tag to the returned data
const result = {
...tagData,
@@ -464,6 +515,8 @@ function readJSON(filepath, projectRoot = null, tag = null) {
// If the resolved tag doesn't exist, fall back to master
const masterData = data.master;
if (masterData && masterData.tasks) {
normalizeTaskIds(masterData.tasks);
if (isDebug) {
console.log(
`Tag '${resolvedTag}' not found, falling back to master with ${masterData.tasks.length} tasks`
@@ -493,6 +546,7 @@ function readJSON(filepath, projectRoot = null, tag = null) {
// If anything goes wrong, try to return master or empty
const masterData = data.master;
if (masterData && masterData.tasks) {
normalizeTaskIds(masterData.tasks);
return {
...masterData,
_rawTaggedData: originalTaggedData
@@ -1412,5 +1466,6 @@ export {
createStateJson,
markMigrationForNotice,
flattenTasksWithSubtasks,
ensureTagMetadata
ensureTagMetadata,
normalizeTaskIds
};

View File

@@ -23,6 +23,82 @@ describe('Task Finder', () => {
expect(result.originalSubtaskCount).toBeNull();
});
test('should find tasks when JSON contains string IDs (normalized to numbers)', () => {
// Simulate tasks loaded from JSON with string IDs and mixed subtask notations
const tasksWithStringIds = [
{ id: '1', title: 'First Task' },
{
id: '2',
title: 'Second Task',
subtasks: [
{ id: '1', title: 'Subtask One' },
{ id: '2.2', title: 'Subtask Two (with dotted notation)' } // Testing dotted notation
]
},
{
id: '5',
title: 'Fifth Task',
subtasks: [
{ id: '5.1', title: 'Subtask with dotted ID' }, // Should normalize to 1
{ id: '3', title: 'Subtask with simple ID' } // Should stay as 3
]
}
];
// The readJSON function should normalize these IDs to numbers
// For this test, we'll manually normalize them to simulate what happens
tasksWithStringIds.forEach((task) => {
task.id = parseInt(task.id, 10);
if (task.subtasks) {
task.subtasks.forEach((subtask) => {
// Handle dotted notation like "5.1" -> extract the subtask part
if (typeof subtask.id === 'string' && subtask.id.includes('.')) {
const parts = subtask.id.split('.');
subtask.id = parseInt(parts[parts.length - 1], 10);
} else {
subtask.id = parseInt(subtask.id, 10);
}
});
}
});
// Test finding tasks by numeric ID
const result1 = findTaskById(tasksWithStringIds, 5);
expect(result1.task).toBeDefined();
expect(result1.task.id).toBe(5);
expect(result1.task.title).toBe('Fifth Task');
// Test finding tasks by string ID
const result2 = findTaskById(tasksWithStringIds, '5');
expect(result2.task).toBeDefined();
expect(result2.task.id).toBe(5);
// Test finding subtasks with normalized IDs
const result3 = findTaskById(tasksWithStringIds, '2.1');
expect(result3.task).toBeDefined();
expect(result3.task.id).toBe(1);
expect(result3.task.title).toBe('Subtask One');
expect(result3.task.isSubtask).toBe(true);
// Test subtask that was originally "2.2" (should be normalized to 2)
const result4 = findTaskById(tasksWithStringIds, '2.2');
expect(result4.task).toBeDefined();
expect(result4.task.id).toBe(2);
expect(result4.task.title).toBe('Subtask Two (with dotted notation)');
// Test subtask that was originally "5.1" (should be normalized to 1)
const result5 = findTaskById(tasksWithStringIds, '5.1');
expect(result5.task).toBeDefined();
expect(result5.task.id).toBe(1);
expect(result5.task.title).toBe('Subtask with dotted ID');
// Test subtask that was originally "3" (should stay as 3)
const result6 = findTaskById(tasksWithStringIds, '5.3');
expect(result6.task).toBeDefined();
expect(result6.task.id).toBe(3);
expect(result6.task.title).toBe('Subtask with simple ID');
});
test('should find a subtask using dot notation', () => {
const result = findTaskById(sampleTasks.tasks, '3.1');
expect(result.task).toBeDefined();