Compare commits

..

3 Commits

Author SHA1 Message Date
github-actions[bot]
bd929d419a docs: auto-update documentation based on changes in next branch
This PR was automatically generated to update documentation based on recent changes.

  Original commit: Merge pull request #1231 from eyaltoledano/ralph/merge.from.main\n\n\n

  Co-authored-by: Claude <claude-assistant@anthropic.com>
2025-09-22 18:02:01 +00:00
Ralph Khreish
66c05053c0 Merge pull request #1231 from eyaltoledano/ralph/merge.from.main 2025-09-22 19:54:12 +02:00
Ralph Khreish
d7ab4609aa chore: fix CI 2025-09-22 19:25:44 +02:00
110 changed files with 458 additions and 863 deletions

View File

@@ -11,6 +11,9 @@
"access": "public",
"baseBranch": "main",
"ignore": [
"docs"
"docs",
"@tm/cli",
"@tm/core",
"@tm/build-config"
]
}

View File

@@ -1,6 +0,0 @@
{
"$schema": "https://unpkg.com/@manypkg/get-packages@1.1.3/schema.json",
"defaultBranch": "main",
"ignoredRules": ["ROOT_HAS_DEPENDENCIES", "INTERNAL_MISMATCH"],
"ignoredPackages": ["@tm/core", "@tm/cli", "@tm/build-config"]
}

View File

@@ -1,41 +1,5 @@
# task-master-ai
## 0.27.3
### Patch Changes
- [#1254](https://github.com/eyaltoledano/claude-task-master/pull/1254) [`af53525`](https://github.com/eyaltoledano/claude-task-master/commit/af53525cbc660a595b67d4bb90d906911c71f45d) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fixed issue where `tm show` command could not find subtasks using dotted notation IDs (e.g., '8.1').
- The command now properly searches within parent task subtasks and returns the correct subtask information.
## 0.27.2
### Patch Changes
- [#1248](https://github.com/eyaltoledano/claude-task-master/pull/1248) [`044a7bf`](https://github.com/eyaltoledano/claude-task-master/commit/044a7bfc98049298177bc655cf341d7a8b6a0011) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix set-status for subtasks:
- Parent tasks are now set as `done` when subtasks are all `done`
- Parent tasks are now set as `in-progress` when at least one subtask is `in-progress` or `done`
## 0.27.1
### Patch Changes
- [#1232](https://github.com/eyaltoledano/claude-task-master/pull/1232) [`f487736`](https://github.com/eyaltoledano/claude-task-master/commit/f487736670ef8c484059f676293777eabb249c9e) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix module not found for new 0.27.0 release
- [#1233](https://github.com/eyaltoledano/claude-task-master/pull/1233) [`c911608`](https://github.com/eyaltoledano/claude-task-master/commit/c911608f60454253f4e024b57ca84e5a5a53f65c) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix Zed MCP configuration by adding required "source" property
- Add "source": "custom" property to task-master-ai server in Zed settings.json
## 0.27.1-rc.1
### Patch Changes
- [#1233](https://github.com/eyaltoledano/claude-task-master/pull/1233) [`1a18794`](https://github.com/eyaltoledano/claude-task-master/commit/1a1879483b86c118a4e46c02cbf4acebfcf6bcf9) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - One last testing final final
## 0.27.1-rc.0
### Patch Changes
- [#1232](https://github.com/eyaltoledano/claude-task-master/pull/1232) [`f487736`](https://github.com/eyaltoledano/claude-task-master/commit/f487736670ef8c484059f676293777eabb249c9e) Thanks [@Crunchyman-ralph](https://github.com/Crunchyman-ralph)! - Fix module not found for new 0.27.0 release
## 0.27.0
### Minor Changes

View File

@@ -1,12 +1,5 @@
# @tm/cli
## null
### Patch Changes
- Updated dependencies []:
- @tm/core@null
## 0.27.0
### Patch Changes

View File

@@ -1,5 +1,6 @@
{
"name": "@tm/cli",
"version": "0.27.0",
"description": "Task Master CLI - Command line interface for task management",
"type": "module",
"private": true,
@@ -23,12 +24,12 @@
},
"dependencies": {
"@tm/core": "*",
"boxen": "^8.0.1",
"boxen": "^7.1.1",
"chalk": "5.6.2",
"cli-table3": "^0.6.5",
"commander": "^12.1.0",
"inquirer": "^12.5.0",
"ora": "^8.2.0"
"inquirer": "^9.2.10",
"ora": "^8.1.0"
},
"devDependencies": {
"@biomejs/biome": "^1.9.4",

View File

@@ -18,8 +18,7 @@ export * as ui from './utils/ui.js';
export {
checkForUpdate,
performAutoUpdate,
displayUpgradeNotification,
compareVersions
displayUpgradeNotification
} from './utils/auto-update.js';
// Re-export commonly used types from tm-core

View File

@@ -7,6 +7,7 @@ import https from 'https';
import chalk from 'chalk';
import ora from 'ora';
import boxen from 'boxen';
import packageJson from '../../../../package.json' with { type: 'json' };
export interface UpdateInfo {
currentVersion: string;
@@ -15,18 +16,15 @@ export interface UpdateInfo {
}
/**
* Get current version from build-time injected environment variable
* Get current version from package.json
*/
function getCurrentVersion(): string {
// Version is injected at build time via TM_PUBLIC_VERSION
const version = process.env.TM_PUBLIC_VERSION;
if (version && version !== 'unknown') {
return version;
try {
return packageJson.version;
} catch (error) {
console.warn('Could not read package.json for version info');
return '0.0.0';
}
// Fallback for development or if injection failed
console.warn('Could not read version from TM_PUBLIC_VERSION, using fallback');
return '0.0.0';
}
/**
@@ -35,7 +33,7 @@ function getCurrentVersion(): string {
* @param v2 - Second version
* @returns -1 if v1 < v2, 0 if v1 = v2, 1 if v1 > v2
*/
export function compareVersions(v1: string, v2: string): number {
function compareVersions(v1: string, v2: string): number {
const toParts = (v: string) => {
const [core, pre = ''] = v.split('-', 2);
const nums = core.split('.').map((n) => Number.parseInt(n, 10) || 0);

View File

@@ -1,7 +1,5 @@
# docs
## 0.0.4
## 0.0.3
## 0.0.2

View File

@@ -206,4 +206,25 @@ sidebarTitle: "CLI Commands"
task-master init
```
</Accordion>
<Accordion title="Start Working on Tasks">
```bash
# Start working on a specific task with Claude Code
task-master start <task-id>
# Start working on the next available task automatically
task-master start
# Example: Start working on task 1.2
task-master start 1.2
```
The `start` command automatically launches Claude Code with a comprehensive prompt containing:
- Complete task details and context
- Implementation guidelines and best practices
- Relevant codebase information
- Dependencies and requirements
When no task ID is provided, it automatically detects and starts the next available task.
</Accordion>
</AccordionGroup>

View File

@@ -30,7 +30,8 @@ For MCP/Cursor usage: Configure keys in the env section of your .cursor/mcp.json
"MISTRAL_API_KEY": "MISTRAL_API_KEY_HERE",
"AZURE_OPENAI_API_KEY": "AZURE_OPENAI_API_KEY_HERE",
"OLLAMA_API_KEY": "OLLAMA_API_KEY_HERE",
"GITHUB_API_KEY": "GITHUB_API_KEY_HERE"
"GITHUB_API_KEY": "GITHUB_API_KEY_HERE",
"GROK_CLI_API_KEY": "GROK_CLI_API_KEY_HERE"
}
}
}
@@ -62,8 +63,50 @@ PERPLEXITY_API_KEY=pplx-your-key-here
# Google Vertex AI Configuration (Required if using 'vertex' provider)
# VERTEX_PROJECT_ID=your-gcp-project-id
# Grok CLI Configuration (Required if using 'grok-cli' provider)
# GROK_CLI_API_KEY=your-grok-api-key-here
# Codebase Analysis Feature Control
# TASKMASTER_ENABLE_CODEBASE_ANALYSIS=true # Enable codebase analysis features (default: true)
```
## Grok Provider Setup
Task Master now supports Grok models from xAI with full codebase context awareness. This is especially useful for AI operations that benefit from understanding your entire project structure.
### Getting Started with Grok
1. **Get your Grok API key** from [console.x.ai](https://console.x.ai)
2. **Set the environment variable**:
```bash
export GROK_CLI_API_KEY="your-api-key-here"
```
3. **Configure Task Master to use Grok**:
```bash
task-master models --set-main grok-beta
# or
task-master models --set-research grok-beta
# or
task-master models --set-fallback grok-beta
```
### Key Features
- **Full codebase context**: Grok models can analyze your entire project when generating tasks or parsing PRDs
- **xAI model access**: Support for latest Grok models (grok-2, grok-3, grok-4, etc.)
- **Code-aware task generation**: Create more accurate and contextual tasks based on your actual codebase
- **Intelligent PRD parsing**: Parse requirements with understanding of your existing code structure
### Available Models
- `grok-beta` - Latest Grok model with codebase context
- `grok-vision-beta` - Grok with vision capabilities and codebase context
<Note>
The Grok CLI provider integrates with xAI's Grok models via [grok-cli](https://github.com/superagent-ai/grok-cli) by Superagent AI and can also use the local Grok CLI configuration file (`~/.grok/user-settings.json`) if available.
</Note>
## What Else Can Be Configured?
The main configuration file (`.taskmaster/config.json`) allows you to control nearly every aspect of Task Masters behavior. Heres a high-level look at what you can customize:
@@ -89,6 +132,13 @@ You dont need to configure everything up front. Most settings can be left as
- `defaultSubtasks`: Number of subtasks to auto-generate
- `defaultPriority`: Priority level for new tasks
### Codebase Analysis Control
- `TASKMASTER_ENABLE_CODEBASE_ANALYSIS`: Control whether codebase analysis features are enabled
- Can be set via environment variables, MCP configuration, or project config files
- Priority order: `.env` > MCP session env > `.taskmaster/config.json`
- Default: `true`
- When enabled, allows providers like Claude Code and Gemini CLI to analyze your project structure for more contextual task generation
### API Endpoint Overrides
- `ollamaBaseURL`: Custom Ollama server URL
- `azureBaseURL`: Global Azure endpoint

View File

@@ -1,6 +1,6 @@
{
"name": "docs",
"version": "0.0.4",
"version": "0.0.3",
"private": true,
"description": "Task Master documentation powered by Mintlify",
"scripts": {

View File

@@ -3,4 +3,78 @@ title: "What's New"
sidebarTitle: "What's New"
---
An easy way to see the latest releases
## Version 0.27.0 - Latest Release
### New Features
#### `task-master start` Command
- **Automated Task Execution**: New command that automatically launches Claude Code with comprehensive task context
- **Smart Task Detection**: When no task ID is provided, automatically detects and starts the next available task
- **Rich Context**: Provides complete task details, implementation guidelines, and codebase information to Claude Code
#### Grok Provider Integration
- **Full Codebase Context**: Grok models can now analyze your entire project when generating tasks or parsing PRDs
- **xAI Model Support**: Access to latest Grok models (grok-2, grok-3, grok-4, etc.) via the grok-cli integration
- **Code-Aware Generation**: More accurate and contextual task creation based on your actual codebase structure
- **Available Models**:
- `grok-beta` - Latest Grok model with codebase context
- `grok-vision-beta` - Grok with vision capabilities and codebase context
### Improvements
#### Enhanced Provider Defaults
- **Main Model**: Upgraded from Claude 3.5 Sonnet to **Claude Sonnet 4** for better performance
- **Fallback Model**: Improved from Claude 3.5 Sonnet to **Claude 3.7** for enhanced reliability
#### MCP Server Simplification
- **No More --package Flag**: Removed the need for `--package=task-master-ai` in MCP server configuration
- **Bundled Package**: The entire package is now bundled, eliminating common configuration issues
#### Auto-Update Functionality
- **CLI Auto-Updates**: Every CLI command now includes auto-update functionality to keep you on the latest version
#### Codebase Analysis Feature Control
- **Configurable Analysis**: New `TASKMASTER_ENABLE_CODEBASE_ANALYSIS` environment variable to control codebase analysis features
- **Multiple Configuration Sources**: Can be set via `.env`, MCP configuration, or project config files
- **Priority System**: Environment variables > MCP session env > `.taskmaster/config.json`
### TypeScript Migration
- **Improved Development**: Moving from JavaScript to TypeScript environment for better development experience
- **Gradual Migration**: JavaScript commands are being incrementally moved to TypeScript
## Getting Started with New Features
### Using the Start Command
```bash
# Start working on a specific task
task-master start 1.2
# Auto-detect and start next available task
task-master start
```
### Setting up Grok
```bash
# Set your API key
export GROK_CLI_API_KEY="your-api-key-here"
# Configure Grok as your main provider
task-master models --set-main grok-beta
```
### Simplified MCP Configuration
```json
{
"mcpServers": {
"task-master-ai": {
"command": "npx",
"args": ["-y", "task-master-ai"],
"env": {
"ANTHROPIC_API_KEY": "your-key-here"
}
}
}
}
```
For detailed setup instructions and configuration options, see our [Configuration Guide](/docs/getting-started/quick-start/configuration-quick).

View File

@@ -1,40 +1,5 @@
# Change Log
## 0.25.4
### Patch Changes
- Updated dependencies [[`af53525`](https://github.com/eyaltoledano/claude-task-master/commit/af53525cbc660a595b67d4bb90d906911c71f45d)]:
- task-master-ai@0.27.3
## 0.25.3
### Patch Changes
- Updated dependencies [[`044a7bf`](https://github.com/eyaltoledano/claude-task-master/commit/044a7bfc98049298177bc655cf341d7a8b6a0011)]:
- task-master-ai@0.27.2
## 0.25.2
### Patch Changes
- Updated dependencies [[`f487736`](https://github.com/eyaltoledano/claude-task-master/commit/f487736670ef8c484059f676293777eabb249c9e), [`c911608`](https://github.com/eyaltoledano/claude-task-master/commit/c911608f60454253f4e024b57ca84e5a5a53f65c), [`1a18794`](https://github.com/eyaltoledano/claude-task-master/commit/1a1879483b86c118a4e46c02cbf4acebfcf6bcf9)]:
- task-master-ai@0.27.1
## 0.25.2-rc.1
### Patch Changes
- Updated dependencies [[`1a18794`](https://github.com/eyaltoledano/claude-task-master/commit/1a1879483b86c118a4e46c02cbf4acebfcf6bcf9)]:
- task-master-ai@0.27.1-rc.1
## 0.25.2-rc.0
### Patch Changes
- Updated dependencies [[`f487736`](https://github.com/eyaltoledano/claude-task-master/commit/f487736670ef8c484059f676293777eabb249c9e)]:
- task-master-ai@0.27.1-rc.0
## 0.25.0
### Minor Changes

View File

@@ -3,7 +3,7 @@
"private": true,
"displayName": "TaskMaster",
"description": "A visual Kanban board interface for TaskMaster projects in VS Code",
"version": "0.25.4",
"version": "0.25.0",
"publisher": "Hamster",
"icon": "assets/icon.png",
"engines": {
@@ -240,7 +240,7 @@
"check-types": "tsc --noEmit"
},
"dependencies": {
"task-master-ai": "0.27.3"
"task-master-ai": "*"
},
"devDependencies": {
"@dnd-kit/core": "^6.3.1",
@@ -254,9 +254,8 @@
"@radix-ui/react-separator": "^1.1.7",
"@radix-ui/react-slot": "^1.2.3",
"@tailwindcss/postcss": "^4.1.11",
"@tanstack/react-query": "^5.83.0",
"@types/mocha": "^10.0.10",
"@types/node": "^22.10.5",
"@types/node": "20.x",
"@types/react": "19.1.8",
"@types/react-dom": "19.1.6",
"@types/vscode": "^1.101.0",
@@ -272,11 +271,12 @@
"lucide-react": "^0.525.0",
"npm-run-all": "^4.1.5",
"postcss": "8.5.6",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"tailwind-merge": "^3.3.1",
"tailwindcss": "4.1.11",
"typescript": "^5.7.3"
"typescript": "^5.8.3",
"@tanstack/react-query": "^5.83.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"overrides": {
"glob@<8": "^10.4.5",

66
output.txt Normal file

File diff suppressed because one or more lines are too long

358
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "task-master-ai",
"version": "0.27.3",
"version": "0.27.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "task-master-ai",
"version": "0.27.3",
"version": "0.27.0",
"license": "MIT WITH Commons-Clause",
"workspaces": [
"apps/*",
@@ -29,7 +29,6 @@
"@inquirer/search": "^3.0.15",
"@openrouter/ai-sdk-provider": "^0.4.5",
"@streamparser/json": "^0.0.22",
"@supabase/supabase-js": "^2.57.4",
"ai": "^4.3.10",
"ajv": "^8.17.1",
"ajv-formats": "^3.0.1",
@@ -38,7 +37,7 @@
"cli-highlight": "^2.1.11",
"cli-progress": "^3.12.0",
"cli-table3": "^0.6.5",
"commander": "^12.1.0",
"commander": "^11.1.0",
"cors": "^2.8.5",
"dotenv": "^16.3.1",
"express": "^4.21.2",
@@ -71,7 +70,6 @@
"@biomejs/biome": "^1.9.4",
"@changesets/changelog-github": "^0.5.1",
"@changesets/cli": "^2.28.1",
"@manypkg/cli": "^0.25.1",
"@tm/cli": "*",
"@types/jest": "^29.5.14",
"@types/marked-terminal": "^6.1.1",
@@ -86,9 +84,9 @@
"supertest": "^7.1.0",
"ts-jest": "^29.4.2",
"tsdown": "^0.15.2",
"tsx": "^4.20.4",
"tsx": "^4.16.2",
"turbo": "^2.5.6",
"typescript": "^5.7.3"
"typescript": "^5.9.2"
},
"engines": {
"node": ">=18.0.0"
@@ -101,15 +99,16 @@
},
"apps/cli": {
"name": "@tm/cli",
"version": "0.27.0",
"license": "MIT",
"dependencies": {
"@tm/core": "*",
"boxen": "^8.0.1",
"boxen": "^7.1.1",
"chalk": "5.6.2",
"cli-table3": "^0.6.5",
"commander": "^12.1.0",
"inquirer": "^12.5.0",
"ora": "^8.2.0"
"inquirer": "^9.2.10",
"ora": "^8.1.0"
},
"devDependencies": {
"@biomejs/biome": "^1.9.4",
@@ -190,6 +189,15 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"license": "MIT"
},
"apps/cli/node_modules/commander": {
"version": "12.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
"integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
"license": "MIT",
"engines": {
"node": ">=18"
}
},
"apps/cli/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -351,15 +359,15 @@
}
},
"apps/docs": {
"version": "0.0.4",
"version": "0.0.3",
"devDependencies": {
"mintlify": "^4.2.111"
}
},
"apps/extension": {
"version": "0.25.4",
"version": "0.25.0",
"dependencies": {
"task-master-ai": "0.27.3"
"task-master-ai": "*"
},
"devDependencies": {
"@dnd-kit/core": "^6.3.1",
@@ -375,7 +383,7 @@
"@tailwindcss/postcss": "^4.1.11",
"@tanstack/react-query": "^5.83.0",
"@types/mocha": "^10.0.10",
"@types/node": "^22.10.5",
"@types/node": "20.x",
"@types/react": "19.1.8",
"@types/react-dom": "19.1.6",
"@types/vscode": "^1.101.0",
@@ -395,7 +403,7 @@
"react-dom": "^19.0.0",
"tailwind-merge": "^3.3.1",
"tailwindcss": "4.1.11",
"typescript": "^5.7.3"
"typescript": "^5.8.3"
},
"engines": {
"vscode": "^1.93.0"
@@ -5391,101 +5399,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/@manypkg/cli": {
"version": "0.25.1",
"resolved": "https://registry.npmjs.org/@manypkg/cli/-/cli-0.25.1.tgz",
"integrity": "sha512-lag906FyiNxzZjsRErkUD5/to174I2JzPk5bZubuJp6loMKKJn73zrtqeU7nHlVkHBg3tgXDTJj22HxUDxLRXw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@manypkg/get-packages": "^3.1.0",
"detect-indent": "^7.0.1",
"normalize-path": "^3.0.0",
"p-limit": "^6.2.0",
"package-json": "^10.0.1",
"parse-github-url": "^1.0.3",
"picocolors": "^1.1.1",
"sembear": "^0.7.0",
"semver": "^7.7.1",
"tinyexec": "^1.0.1",
"validate-npm-package-name": "^6.0.0"
},
"bin": {
"manypkg": "bin.js"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@manypkg/cli/node_modules/@manypkg/find-root": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-3.1.0.tgz",
"integrity": "sha512-BcSqCyKhBVZ5YkSzOiheMCV41kqAFptW6xGqYSTjkVTl9XQpr+pqHhwgGCOHQtjDCv7Is6EFyA14Sm5GVbVABA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@manypkg/tools": "^2.1.0"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@manypkg/cli/node_modules/@manypkg/get-packages": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@manypkg/get-packages/-/get-packages-3.1.0.tgz",
"integrity": "sha512-0TbBVyvPrP7xGYBI/cP8UP+yl/z+HtbTttAD7FMAJgn/kXOTwh5/60TsqP9ZYY710forNfyV0N8P/IE/ujGZJg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@manypkg/find-root": "^3.1.0",
"@manypkg/tools": "^2.1.0"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@manypkg/cli/node_modules/detect-indent": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-7.0.2.tgz",
"integrity": "sha512-y+8xyqdGLL+6sh0tVeHcfP/QDd8gUgbasolJJpY7NgeQGSZ739bDtSiaiDgtoicy+mtYB81dKLxO9xRhCyIB3A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@manypkg/cli/node_modules/p-limit": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz",
"integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==",
"dev": true,
"license": "MIT",
"dependencies": {
"yocto-queue": "^1.1.1"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@manypkg/cli/node_modules/yocto-queue": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz",
"integrity": "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/@manypkg/find-root": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@manypkg/find-root/-/find-root-1.1.0.tgz",
@@ -5598,41 +5511,6 @@
"node": ">= 4.0.0"
}
},
"node_modules/@manypkg/tools": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@manypkg/tools/-/tools-2.1.0.tgz",
"integrity": "sha512-0FOIepYR4ugPYaHwK7hDeHDkfPOBVvayt9QpvRbi2LT/h2b0GaE/gM9Gag7fsnyYyNaTZ2IGyOuVg07IYepvYQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"jju": "^1.4.0",
"js-yaml": "^4.1.0",
"tinyglobby": "^0.2.13"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@manypkg/tools/node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true,
"license": "Python-2.0"
},
"node_modules/@manypkg/tools/node_modules/js-yaml": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"dev": true,
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
},
"bin": {
"js-yaml": "bin/js-yaml.js"
}
},
"node_modules/@mdx-js/mdx": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz",
@@ -7462,51 +7340,6 @@
"node": ">=14"
}
},
"node_modules/@pnpm/config.env-replace": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz",
"integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12.22.0"
}
},
"node_modules/@pnpm/network.ca-file": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz",
"integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==",
"dev": true,
"license": "MIT",
"dependencies": {
"graceful-fs": "4.2.10"
},
"engines": {
"node": ">=12.22.0"
}
},
"node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": {
"version": "4.2.10",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
"dev": true,
"license": "ISC"
},
"node_modules/@pnpm/npm-conf": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.3.1.tgz",
"integrity": "sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@pnpm/config.env-replace": "^1.1.0",
"@pnpm/network.ca-file": "^1.0.1",
"config-chain": "^1.1.11"
},
"engines": {
"node": ">=12"
}
},
"node_modules/@protobufjs/aspromise": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
@@ -14304,12 +14137,12 @@
}
},
"node_modules/commander": {
"version": "12.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
"integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
"license": "MIT",
"engines": {
"node": ">=18"
"node": ">=16"
}
},
"node_modules/component-emitter": {
@@ -14442,17 +14275,6 @@
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
"license": "MIT"
},
"node_modules/config-chain": {
"version": "1.1.13",
"resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
"integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"ini": "^1.3.4",
"proto-list": "~1.2.1"
}
},
"node_modules/consola": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz",
@@ -14934,6 +14756,7 @@
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
"dev": true,
"license": "MIT",
"optional": true,
"engines": {
"node": ">=4.0.0"
}
@@ -18902,7 +18725,8 @@
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
"dev": true,
"license": "ISC"
"license": "ISC",
"optional": true
},
"node_modules/ink": {
"version": "6.3.0",
@@ -21870,13 +21694,6 @@
"jiti": "lib/jiti-cli.mjs"
}
},
"node_modules/jju": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz",
"integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==",
"dev": true,
"license": "MIT"
},
"node_modules/joycon": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz",
@@ -22215,19 +22032,6 @@
"node": ">=6"
}
},
"node_modules/ky": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/ky/-/ky-1.10.0.tgz",
"integrity": "sha512-YRPCzHEWZffbfvmRrfwa+5nwBHwZuYiTrfDX0wuhGBPV0pA/zCqcOq93MDssON/baIkpYbvehIX5aLpMxrRhaA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sindresorhus/ky?sponsor=1"
}
},
"node_modules/lcm": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/lcm/-/lcm-0.0.3.tgz",
@@ -25435,25 +25239,6 @@
"node": ">= 14"
}
},
"node_modules/package-json": {
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/package-json/-/package-json-10.0.1.tgz",
"integrity": "sha512-ua1L4OgXSBdsu1FPb7F3tYH0F48a6kxvod4pLUlGY9COeJAJQNX/sNH2IiEmsxw7lqYiAwrdHMjz1FctOsyDQg==",
"dev": true,
"license": "MIT",
"dependencies": {
"ky": "^1.2.0",
"registry-auth-token": "^5.0.2",
"registry-url": "^6.0.1",
"semver": "^7.6.0"
},
"engines": {
"node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/package-json-from-dist": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
@@ -25517,19 +25302,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/parse-github-url": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.3.tgz",
"integrity": "sha512-tfalY5/4SqGaV/GIGzWyHnFjlpTPTNpENR9Ea2lLldSJ8EWXMsvacWucqY3m3I4YPtas15IxTLQVQ5NSYXPrww==",
"dev": true,
"license": "MIT",
"bin": {
"parse-github-url": "cli.js"
},
"engines": {
"node": ">= 0.10"
}
},
"node_modules/parse-json": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
@@ -26175,13 +25947,6 @@
"url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/proto-list": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
"integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==",
"dev": true,
"license": "ISC"
},
"node_modules/protobufjs": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz",
@@ -26518,6 +26283,7 @@
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
"dev": true,
"license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
"optional": true,
"dependencies": {
"deep-extend": "^0.6.0",
"ini": "~1.3.0",
@@ -26534,6 +26300,7 @@
"integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
"dev": true,
"license": "MIT",
"optional": true,
"engines": {
"node": ">=0.10.0"
}
@@ -26950,35 +26717,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/registry-auth-token": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.1.0.tgz",
"integrity": "sha512-GdekYuwLXLxMuFTwAPg5UKGLW/UXzQrZvH/Zj791BQif5T05T0RsaLfHc9q3ZOKi7n+BoprPD9mJ0O0k4xzUlw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@pnpm/npm-conf": "^2.1.0"
},
"engines": {
"node": ">=14"
}
},
"node_modules/registry-url": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/registry-url/-/registry-url-6.0.1.tgz",
"integrity": "sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"rc": "1.2.8"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/rehype-katex": {
"version": "7.0.1",
"resolved": "https://registry.npmjs.org/rehype-katex/-/rehype-katex-7.0.1.tgz",
@@ -27788,16 +27526,6 @@
"url": "https://ko-fi.com/killymxi"
}
},
"node_modules/sembear": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/sembear/-/sembear-0.7.0.tgz",
"integrity": "sha512-XyLTEich2D02FODCkfdto3mB9DetWPLuTzr4tvoofe9SvyM27h4nQSbV3+iVcYQz94AFyKtqBv5pcZbj3k2hdA==",
"dev": true,
"license": "MIT",
"dependencies": {
"semver": "^7.3.5"
}
},
"node_modules/semver": {
"version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
@@ -30757,16 +30485,6 @@
"spdx-expression-parse": "^3.0.0"
}
},
"node_modules/validate-npm-package-name": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.2.tgz",
"integrity": "sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==",
"dev": true,
"license": "ISC",
"engines": {
"node": "^18.17.0 || >=20.5.0"
}
},
"node_modules/vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
@@ -32155,6 +31873,7 @@
},
"packages/build-config": {
"name": "@tm/build-config",
"version": "1.0.1",
"license": "MIT",
"dependencies": {
"tsup": "^8.5.0"
@@ -32166,21 +31885,22 @@
},
"packages/tm-core": {
"name": "@tm/core",
"version": "0.26.1",
"license": "MIT",
"dependencies": {
"@supabase/supabase-js": "^2.57.4",
"zod": "^3.23.8"
"zod": "^3.22.4"
},
"devDependencies": {
"@biomejs/biome": "^1.9.4",
"@tm/build-config": "*",
"@types/node": "^22.10.5",
"@types/node": "^20.11.30",
"@vitest/coverage-v8": "^2.0.5",
"dotenv-mono": "^1.5.1",
"dotenv-mono": "^1.3.14",
"ts-node": "^10.9.2",
"tsup": "^8.5.0",
"typescript": "^5.7.3",
"vitest": "^2.1.8"
"typescript": "^5.4.3",
"vitest": "^2.0.5"
},
"engines": {
"node": ">=18.0.0"

View File

@@ -1,6 +1,6 @@
{
"name": "task-master-ai",
"version": "0.27.3",
"version": "0.27.0",
"description": "A task management system for ambitious AI-driven development that doesn't overwhelm and confuse Cursor.",
"main": "index.js",
"type": "module",
@@ -33,9 +33,7 @@
"inspector": "npx @modelcontextprotocol/inspector node dist/mcp-server.js",
"mcp-server": "node dist/mcp-server.js",
"format-check": "biome format .",
"format": "biome format . --write",
"deps:check": "manypkg check || echo 'Note: Workspace package version warnings are expected for internal @tm/* packages'",
"deps:fix": "manypkg fix"
"format": "biome format . --write"
},
"keywords": [
"claude",
@@ -67,7 +65,6 @@
"@inquirer/search": "^3.0.15",
"@openrouter/ai-sdk-provider": "^0.4.5",
"@streamparser/json": "^0.0.22",
"@supabase/supabase-js": "^2.57.4",
"ai": "^4.3.10",
"ajv": "^8.17.1",
"ajv-formats": "^3.0.1",
@@ -76,7 +73,7 @@
"cli-highlight": "^2.1.11",
"cli-progress": "^3.12.0",
"cli-table3": "^0.6.5",
"commander": "^12.1.0",
"commander": "^11.1.0",
"cors": "^2.8.5",
"dotenv": "^16.3.1",
"express": "^4.21.2",
@@ -123,11 +120,10 @@
"whatwg-url": "^11.0.0"
},
"devDependencies": {
"@tm/cli": "*",
"@biomejs/biome": "^1.9.4",
"@changesets/changelog-github": "^0.5.1",
"@changesets/cli": "^2.28.1",
"@manypkg/cli": "^0.25.1",
"@tm/cli": "*",
"@types/jest": "^29.5.14",
"@types/marked-terminal": "^6.1.1",
"concurrently": "^9.2.1",
@@ -141,8 +137,8 @@
"supertest": "^7.1.0",
"ts-jest": "^29.4.2",
"tsdown": "^0.15.2",
"tsx": "^4.20.4",
"tsx": "^4.16.2",
"turbo": "^2.5.6",
"typescript": "^5.7.3"
"typescript": "^5.9.2"
}
}

View File

@@ -1,5 +1,3 @@
# @tm/build-config
## null
## 1.0.1

View File

@@ -1,5 +1,6 @@
{
"name": "@tm/build-config",
"version": "1.0.1",
"description": "Shared build configuration for Task Master monorepo",
"type": "module",
"private": true,

View File

@@ -1,7 +1,5 @@
# Changelog
## null
## 0.26.1
All notable changes to the @task-master/tm-core package will be documented in this file.

View File

@@ -1,5 +1,6 @@
{
"name": "@tm/core",
"version": "0.26.1",
"private": true,
"description": "Core library for Task Master - TypeScript task management system",
"type": "module",
@@ -31,18 +32,18 @@
},
"dependencies": {
"@supabase/supabase-js": "^2.57.4",
"zod": "^3.23.8"
"zod": "^3.22.4"
},
"devDependencies": {
"@biomejs/biome": "^1.9.4",
"@tm/build-config": "*",
"@types/node": "^22.10.5",
"@types/node": "^20.11.30",
"@vitest/coverage-v8": "^2.0.5",
"dotenv-mono": "^1.5.1",
"dotenv-mono": "^1.3.14",
"ts-node": "^10.9.2",
"tsup": "^8.5.0",
"typescript": "^5.7.3",
"vitest": "^2.1.8"
"typescript": "^5.4.3",
"vitest": "^2.0.5"
},
"engines": {
"node": ">=18.0.0"

View File

@@ -3,17 +3,7 @@
* This file defines the contract for all storage implementations
*/
import type { Task, TaskMetadata, TaskStatus } from '../types/index.js';
/**
* Result type for updateTaskStatus operations
*/
export interface UpdateStatusResult {
success: boolean;
oldStatus: TaskStatus;
newStatus: TaskStatus;
taskId: string;
}
import type { Task, TaskMetadata } from '../types/index.js';
/**
* Interface for storage operations on tasks
@@ -64,19 +54,6 @@ export interface IStorage {
tag?: string
): Promise<void>;
/**
* Update task or subtask status by ID
* @param taskId - ID of the task or subtask (e.g., "1" or "1.2")
* @param newStatus - New status to set
* @param tag - Optional tag context for the task
* @returns Promise that resolves to update result with old and new status
*/
updateTaskStatus(
taskId: string,
newStatus: TaskStatus,
tag?: string
): Promise<UpdateStatusResult>;
/**
* Delete a task by ID
* @param taskId - ID of the task to delete
@@ -214,11 +191,6 @@ export abstract class BaseStorage implements IStorage {
updates: Partial<Task>,
tag?: string
): Promise<void>;
abstract updateTaskStatus(
taskId: string,
newStatus: TaskStatus,
tag?: string
): Promise<UpdateStatusResult>;
abstract deleteTask(taskId: string, tag?: string): Promise<void>;
abstract exists(tag?: string): Promise<boolean>;
abstract loadMetadata(tag?: string): Promise<TaskMetadata | null>;

View File

@@ -135,28 +135,15 @@ export class TaskService {
}
/**
* Get a single task by ID - delegates to storage layer
* Get a single task by ID
*/
async getTask(taskId: string, tag?: string): Promise<Task | null> {
// Use provided tag or get active tag
const activeTag = tag || this.getActiveTag();
const result = await this.getTaskList({
tag,
includeSubtasks: true
});
try {
// Delegate to storage layer which handles the specific logic for tasks vs subtasks
return await this.storage.loadTask(String(taskId), activeTag);
} catch (error) {
throw new TaskMasterError(
`Failed to get task ${taskId}`,
ERROR_CODES.STORAGE_ERROR,
{
operation: 'getTask',
resource: 'task',
taskId: String(taskId),
tag: activeTag
},
error as Error
);
}
return result.tasks.find((t) => t.id === taskId) || null;
}
/**
@@ -459,7 +446,7 @@ export class TaskService {
}
/**
* Update task status - delegates to storage layer which handles storage-specific logic
* Update task status
*/
async updateTaskStatus(
taskId: string | number,
@@ -481,28 +468,49 @@ export class TaskService {
// Use provided tag or get active tag
const activeTag = tag || this.getActiveTag();
const taskIdStr = String(taskId);
try {
// Delegate to storage layer which handles the specific logic for tasks vs subtasks
return await this.storage.updateTaskStatus(
taskIdStr,
newStatus,
activeTag
// TODO: For now, assume it's a regular task and just try to update directly
// In the future, we can add subtask support if needed
if (taskIdStr.includes('.')) {
throw new TaskMasterError(
'Subtask status updates not yet supported in API storage',
ERROR_CODES.NOT_IMPLEMENTED
);
}
// Get the current task to get old status (simple, direct approach)
let currentTask: Task | null;
try {
// Try to get the task directly
currentTask = await this.storage.loadTask(taskIdStr, activeTag);
} catch (error) {
throw new TaskMasterError(
`Failed to update task status for ${taskIdStr}`,
ERROR_CODES.STORAGE_ERROR,
{
operation: 'updateTaskStatus',
resource: 'task',
taskId: taskIdStr,
newStatus,
tag: activeTag
},
`Failed to load task ${taskIdStr}`,
ERROR_CODES.TASK_NOT_FOUND,
{ taskId: taskIdStr },
error as Error
);
}
if (!currentTask) {
throw new TaskMasterError(
`Task ${taskIdStr} not found`,
ERROR_CODES.TASK_NOT_FOUND
);
}
const oldStatus = currentTask.status;
// Simple, direct update - just change the status
await this.storage.updateTask(taskIdStr, { status: newStatus }, activeTag);
return {
success: true,
oldStatus,
newStatus,
taskId: taskIdStr
};
}
}

View File

@@ -5,15 +5,9 @@
import type {
IStorage,
StorageStats,
UpdateStatusResult
StorageStats
} from '../interfaces/storage.interface.js';
import type {
Task,
TaskMetadata,
TaskTag,
TaskStatus
} from '../types/index.js';
import type { Task, TaskMetadata, TaskTag } from '../types/index.js';
import { ERROR_CODES, TaskMasterError } from '../errors/task-master-error.js';
import { TaskRepository } from '../repositories/task-repository.interface.js';
import { SupabaseTaskRepository } from '../repositories/supabase-task-repository.js';
@@ -491,62 +485,6 @@ export class ApiStorage implements IStorage {
}
}
/**
* Update task or subtask status by ID - for API storage
*/
async updateTaskStatus(
taskId: string,
newStatus: TaskStatus,
tag?: string
): Promise<UpdateStatusResult> {
await this.ensureInitialized();
try {
const existingTask = await this.retryOperation(() =>
this.repository.getTask(this.projectId, taskId)
);
if (!existingTask) {
throw new Error(`Task ${taskId} not found`);
}
const oldStatus = existingTask.status;
if (oldStatus === newStatus) {
return {
success: true,
oldStatus,
newStatus,
taskId
};
}
// Update the task/subtask status
await this.retryOperation(() =>
this.repository.updateTask(this.projectId, taskId, {
status: newStatus,
updatedAt: new Date().toISOString()
})
);
// Note: Parent status auto-adjustment is handled by the backend API service
// which has its own business logic for managing task relationships
return {
success: true,
oldStatus,
newStatus,
taskId
};
} catch (error) {
throw new TaskMasterError(
'Failed to update task status via API',
ERROR_CODES.STORAGE_ERROR,
{ operation: 'updateTaskStatus', taskId, newStatus, tag },
error as Error
);
}
}
/**
* Get all available tags
*/

View File

@@ -2,11 +2,10 @@
* @fileoverview Refactored file-based storage implementation for Task Master
*/
import type { Task, TaskMetadata, TaskStatus } from '../../types/index.js';
import type { Task, TaskMetadata } from '../../types/index.js';
import type {
IStorage,
StorageStats,
UpdateStatusResult
StorageStats
} from '../../interfaces/storage.interface.js';
import { FormatHandler } from './format-handler.js';
import { FileOperations } from './file-operations.js';
@@ -105,65 +104,9 @@ export class FileStorage implements IStorage {
/**
* Load a single task by ID from the tasks.json file
* Handles both regular tasks and subtasks (with dotted notation like "1.2")
*/
async loadTask(taskId: string, tag?: string): Promise<Task | null> {
const tasks = await this.loadTasks(tag);
// Check if this is a subtask (contains a dot)
if (taskId.includes('.')) {
const [parentId, subtaskId] = taskId.split('.');
const parentTask = tasks.find((t) => String(t.id) === parentId);
if (!parentTask || !parentTask.subtasks) {
return null;
}
const subtask = parentTask.subtasks.find(
(st) => String(st.id) === subtaskId
);
if (!subtask) {
return null;
}
const toFullSubId = (maybeDotId: string | number): string => {
const depId = String(maybeDotId);
return depId.includes('.') ? depId : `${parentTask.id}.${depId}`;
};
const resolvedDependencies =
subtask.dependencies?.map((dep) => toFullSubId(dep)) ?? [];
// Return a Task-like object for the subtask with the full dotted ID
// Following the same pattern as findTaskById in utils.js
const subtaskResult = {
...subtask,
id: taskId, // Use the full dotted ID
title: subtask.title || `Subtask ${subtaskId}`,
description: subtask.description || '',
status: subtask.status || 'pending',
priority: subtask.priority || parentTask.priority || 'medium',
dependencies: resolvedDependencies,
details: subtask.details || '',
testStrategy: subtask.testStrategy || '',
subtasks: [],
tags: parentTask.tags || [],
assignee: subtask.assignee || parentTask.assignee,
complexity: subtask.complexity || parentTask.complexity,
createdAt: subtask.createdAt || parentTask.createdAt,
updatedAt: subtask.updatedAt || parentTask.updatedAt,
// Add reference to parent task for context (like utils.js does)
parentTask: {
id: parentTask.id,
title: parentTask.title,
status: parentTask.status
},
isSubtask: true
};
return subtaskResult;
}
// Handle regular task lookup
return tasks.find((task) => String(task.id) === String(taskId)) || null;
}
@@ -338,156 +281,6 @@ export class FileStorage implements IStorage {
await this.saveTasks(tasks, tag);
}
/**
* Update task or subtask status by ID - handles file storage logic with parent/subtask relationships
*/
async updateTaskStatus(
taskId: string,
newStatus: TaskStatus,
tag?: string
): Promise<UpdateStatusResult> {
const tasks = await this.loadTasks(tag);
// Check if this is a subtask (contains a dot)
if (taskId.includes('.')) {
return this.updateSubtaskStatusInFile(tasks, taskId, newStatus, tag);
}
// Handle regular task update
const taskIndex = tasks.findIndex((t) => String(t.id) === String(taskId));
if (taskIndex === -1) {
throw new Error(`Task ${taskId} not found`);
}
const oldStatus = tasks[taskIndex].status;
if (oldStatus === newStatus) {
return {
success: true,
oldStatus,
newStatus,
taskId: String(taskId)
};
}
tasks[taskIndex] = {
...tasks[taskIndex],
status: newStatus,
updatedAt: new Date().toISOString()
};
await this.saveTasks(tasks, tag);
return {
success: true,
oldStatus,
newStatus,
taskId: String(taskId)
};
}
/**
* Update subtask status within file storage - handles parent status auto-adjustment
*/
private async updateSubtaskStatusInFile(
tasks: Task[],
subtaskId: string,
newStatus: TaskStatus,
tag?: string
): Promise<UpdateStatusResult> {
// Parse the subtask ID to get parent ID and subtask ID
const parts = subtaskId.split('.');
if (parts.length !== 2) {
throw new Error(
`Invalid subtask ID format: ${subtaskId}. Expected format: parentId.subtaskId`
);
}
const [parentId, subIdRaw] = parts;
const subId = subIdRaw.trim();
if (!/^\d+$/.test(subId)) {
throw new Error(
`Invalid subtask ID: ${subId}. Subtask ID must be a positive integer.`
);
}
const subtaskNumericId = Number(subId);
// Find the parent task
const parentTaskIndex = tasks.findIndex(
(t) => String(t.id) === String(parentId)
);
if (parentTaskIndex === -1) {
throw new Error(`Parent task ${parentId} not found`);
}
const parentTask = tasks[parentTaskIndex];
// Find the subtask within the parent task
const subtaskIndex = parentTask.subtasks.findIndex(
(st) => st.id === subtaskNumericId || String(st.id) === subId
);
if (subtaskIndex === -1) {
throw new Error(
`Subtask ${subtaskId} not found in parent task ${parentId}`
);
}
const oldStatus = parentTask.subtasks[subtaskIndex].status || 'pending';
if (oldStatus === newStatus) {
return {
success: true,
oldStatus,
newStatus,
taskId: subtaskId
};
}
const now = new Date().toISOString();
// Update the subtask status
parentTask.subtasks[subtaskIndex] = {
...parentTask.subtasks[subtaskIndex],
status: newStatus,
updatedAt: now
};
// Auto-adjust parent status based on subtask statuses
const subs = parentTask.subtasks;
let parentNewStatus = parentTask.status;
if (subs.length > 0) {
const norm = (s: any) => s.status || 'pending';
const isDoneLike = (s: any) => {
const st = norm(s);
return st === 'done' || st === 'completed';
};
const allDone = subs.every(isDoneLike);
const anyInProgress = subs.some((s) => norm(s) === 'in-progress');
const anyDone = subs.some(isDoneLike);
if (allDone) parentNewStatus = 'done';
else if (anyInProgress || anyDone) parentNewStatus = 'in-progress';
}
// Always bump updatedAt; update status only if changed
tasks[parentTaskIndex] = {
...parentTask,
...(parentNewStatus !== parentTask.status
? { status: parentNewStatus }
: {}),
updatedAt: now
};
await this.saveTasks(tasks, tag);
return {
success: true,
oldStatus,
newStatus,
taskId: subtaskId
};
}
/**
* Delete a task
*/

Some files were not shown because too many files have changed in this diff Show More