diff --git a/.env.example b/.env.example index 6d3209b9..592f3c6a 100644 --- a/.env.example +++ b/.env.example @@ -1,8 +1,8 @@ # API Keys (Required) -ANTHROPIC_API_KEY=your_anthropic_api_key_here +ANTHROPIC_API_KEY=your_anthropic_api_key_here # Format: sk-ant-api03-... # Model Configuration -MODEL=claude-3-7-sonnet-20250219 # Specify which Claude model to use +MODEL=claude-3-7-sonnet-20250219 # Recommended models: claude-3-7-sonnet-20250219, claude-3-opus-20240229 MAX_TOKENS=4000 # Maximum tokens for model responses TEMPERATURE=0.7 # Temperature for model responses (0.0-1.0) diff --git a/README.md b/README.md index fc152906..aa993ece 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,16 @@ A task management system for AI-driven development with Claude, designed to work seamlessly with Cursor AI. +## Requirements + +- Node.js 14.0.0 or higher +- Anthropic API key (Claude API) +- Anthropic SDK version 0.39.0 or higher + ## Installation ```bash -npm install -g claude-task-master +npm install claude-task-master ``` ## Usage @@ -13,25 +19,15 @@ npm install -g claude-task-master ### Initialize a new project ```bash -# Navigate to your project directory -mkdir my-new-project -cd my-new-project - -# Initialize the project -claude-task-init +npx claude-task-init ``` -This will create the necessary file structure for your project, including: +This will prompt you for project details and set up a new project with the necessary files and structure. -- `.cursor/rules/dev_workflow.mdc` - Cursor rules for AI-driven development -- `scripts/dev.js` - Task management script -- `scripts/README.md` - Documentation for the script -- `scripts/example_prd.txt` - Example PRD template -- `.env.example` - Example environment variables -- `.gitignore` - Git ignore file -- `package.json` - Project configuration -- `tasks.json` - Empty tasks file -- `tasks/` - Directory for task files +### Important Notes + +1. This package uses ES modules. Your package.json should include `"type": "module"`. +2. The Anthropic SDK version should be 0.39.0 or higher. ## Integrating with Cursor AI diff --git a/index.js b/index.js index e50baf52..43a5618a 100644 --- a/index.js +++ b/index.js @@ -6,14 +6,22 @@ // This file serves as the main entry point for the package // The primary functionality is provided through the CLI commands +import { fileURLToPath } from 'url'; +import { dirname, resolve } from 'path'; +import { createRequire } from 'module'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); +const require = createRequire(import.meta.url); + // Export the path to the dev.js script for programmatic usage -exports.devScriptPath = require.resolve('./scripts/dev.js'); +export const devScriptPath = resolve(__dirname, './scripts/dev.js'); // Export a function to initialize a new project programmatically -exports.initProject = async (options = {}) => { - const init = require('./scripts/init'); +export const initProject = async (options = {}) => { + const init = await import('./scripts/init.js'); return init.initializeProject(options); }; // Export version information -exports.version = require('./package.json').version; \ No newline at end of file +export const version = require('./package.json').version; \ No newline at end of file diff --git a/package.json b/package.json index b013c944..ea23e387 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,11 @@ { "name": "claude-task-master", - "version": "1.0.1", + "version": "1.0.2", "description": "A task management system for AI-driven development with Claude", "main": "index.js", + "type": "module", "bin": { - "claude-task-init": "./scripts/init.js" + "claude-task-init": "scripts/init.js" }, "scripts": { "test": "echo \"Error: no test specified\" && exit 1", @@ -23,7 +24,7 @@ "author": "Eyal Toledano", "license": "MIT", "dependencies": { - "@anthropic-ai/sdk": "^0.10.0", + "@anthropic-ai/sdk": "^0.39.0", "chalk": "^4.1.2", "commander": "^11.1.0", "dotenv": "^16.3.1" @@ -43,6 +44,7 @@ "scripts/init.js", "scripts/dev.js", "templates/**", - "README.md" + "README.md", + "index.js" ] } diff --git a/scripts/dev.js b/scripts/dev.js index 0004e47b..77450fb1 100755 --- a/scripts/dev.js +++ b/scripts/dev.js @@ -42,6 +42,11 @@ import fs from 'fs'; import path from 'path'; import dotenv from 'dotenv'; +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); // Load environment variables from .env file dotenv.config(); @@ -169,9 +174,17 @@ async function callClaude(prdContent, prdPath, numTasks) { log('debug', `Response length: ${textContent.length} characters`); try { - // Try to parse the response as JSON + // Check if the response is wrapped in a Markdown code block and extract the JSON log('info', "Parsing response as JSON..."); - const parsedJson = JSON.parse(textContent); + let jsonText = textContent; + const codeBlockMatch = textContent.match(/```(?:json)?\s*([\s\S]*?)\s*```/); + if (codeBlockMatch) { + log('debug', "Detected JSON wrapped in Markdown code block, extracting..."); + jsonText = codeBlockMatch[1]; + } + + // Try to parse the response as JSON + const parsedJson = JSON.parse(jsonText); log('info', `Successfully parsed JSON with ${parsedJson.tasks?.length || 0} tasks`); return parsedJson; } catch (error) { diff --git a/scripts/init.js b/scripts/init.js index c069bd74..72e3ec65 100755 --- a/scripts/init.js +++ b/scripts/init.js @@ -1,9 +1,14 @@ #!/usr/bin/env node -const fs = require('fs'); -const path = require('path'); -const { execSync } = require('child_process'); -const readline = require('readline'); +import fs from 'fs'; +import path from 'path'; +import { execSync } from 'child_process'; +import readline from 'readline'; +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); // Create readline interface for user input const rl = readline.createInterface({ @@ -143,6 +148,7 @@ function createProjectStructure(projectName, projectDescription, projectVersion, version: projectVersion, description: projectDescription, author: authorName, + type: "module", scripts: { "dev": "node scripts/dev.js", "list": "node scripts/dev.js list", @@ -150,7 +156,7 @@ function createProjectStructure(projectName, projectDescription, projectVersion, "parse-prd": "node scripts/dev.js parse-prd" }, dependencies: { - "@anthropic-ai/sdk": "^0.10.0", + "@anthropic-ai/sdk": "^0.39.0", "chalk": "^4.1.2", "commander": "^11.1.0", "dotenv": "^16.3.1" @@ -230,7 +236,7 @@ function createProjectStructure(projectName, projectDescription, projectVersion, } // Run the initialization if this script is executed directly -if (require.main === module) { +if (process.argv[1] === fileURLToPath(import.meta.url)) { (async function main() { try { await initializeProject(); @@ -242,7 +248,7 @@ if (require.main === module) { } // Export functions for programmatic use -module.exports = { +export { initializeProject, createProjectStructure, log diff --git a/scripts/prepare-package.js b/scripts/prepare-package.js index 306ce5cf..873d3c79 100755 --- a/scripts/prepare-package.js +++ b/scripts/prepare-package.js @@ -5,9 +5,14 @@ * It ensures all necessary files are included and properly configured. */ -const fs = require('fs'); -const path = require('path'); -const { execSync } = require('child_process'); +import fs from 'fs'; +import path from 'path'; +import { execSync } from 'child_process'; +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); // Define colors for console output const COLORS = { diff --git a/templates/README.md b/templates/README.md index 75304ee9..8ea6a766 100644 --- a/templates/README.md +++ b/templates/README.md @@ -34,6 +34,12 @@ This project uses the Claude Task Master system to manage development tasks in a npm run generate ``` +### Important Notes + +1. This project uses ES modules. The package.json includes `"type": "module"`. +2. The Anthropic SDK version should be 0.39.0 or higher. +3. If you encounter JSON parsing errors, make sure your Anthropic API key is valid and your environment is set up correctly. + ## Integrating with Cursor AI This project includes Cursor AI integration through the `.cursor/rules/dev_workflow.mdc` file, which provides the AI with knowledge about the task management system. diff --git a/templates/dev.js b/templates/dev.js index 0004e47b..77450fb1 100644 --- a/templates/dev.js +++ b/templates/dev.js @@ -42,6 +42,11 @@ import fs from 'fs'; import path from 'path'; import dotenv from 'dotenv'; +import { fileURLToPath } from 'url'; +import { dirname } from 'path'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); // Load environment variables from .env file dotenv.config(); @@ -169,9 +174,17 @@ async function callClaude(prdContent, prdPath, numTasks) { log('debug', `Response length: ${textContent.length} characters`); try { - // Try to parse the response as JSON + // Check if the response is wrapped in a Markdown code block and extract the JSON log('info', "Parsing response as JSON..."); - const parsedJson = JSON.parse(textContent); + let jsonText = textContent; + const codeBlockMatch = textContent.match(/```(?:json)?\s*([\s\S]*?)\s*```/); + if (codeBlockMatch) { + log('debug', "Detected JSON wrapped in Markdown code block, extracting..."); + jsonText = codeBlockMatch[1]; + } + + // Try to parse the response as JSON + const parsedJson = JSON.parse(jsonText); log('info', `Successfully parsed JSON with ${parsedJson.tasks?.length || 0} tasks`); return parsedJson; } catch (error) { diff --git a/templates/env.example b/templates/env.example index 8cca52cc..2bae4f48 100644 --- a/templates/env.example +++ b/templates/env.example @@ -1,13 +1,13 @@ # Required -ANTHROPIC_API_KEY=your-api-key-here +ANTHROPIC_API_KEY=your-api-key-here # Format: sk-ant-api03-... # Optional - defaults shown -MODEL=claude-3-7-sonnet-20250219 -MAX_TOKENS=4000 -TEMPERATURE=0.7 -DEBUG=false -LOG_LEVEL=info -DEFAULT_SUBTASKS=3 -DEFAULT_PRIORITY=medium -PROJECT_NAME={{projectName}} -PROJECT_VERSION={{projectVersion}} \ No newline at end of file +MODEL=claude-3-7-sonnet-20250219 # Recommended models: claude-3-7-sonnet-20250219, claude-3-opus-20240229 +MAX_TOKENS=4000 # Maximum tokens for model responses +TEMPERATURE=0.7 # Temperature for model responses (0.0-1.0) +DEBUG=false # Enable debug logging (true/false) +LOG_LEVEL=info # Log level (debug, info, warn, error) +DEFAULT_SUBTASKS=3 # Default number of subtasks when expanding +DEFAULT_PRIORITY=medium # Default priority for generated tasks (high, medium, low) +PROJECT_NAME={{projectName}} # Project name for tasks.json metadata +PROJECT_VERSION={{projectVersion}} # Project version for tasks.json metadata \ No newline at end of file