feat: Modernize package with ES modules and improve error handling
- Update to ES modules syntax throughout the codebase - Add fileURLToPath and dirname imports to handle __dirname in ES modules - Upgrade Anthropic SDK from 0.10.0 to 0.39.0 - Fix JSON parsing to handle responses wrapped in Markdown code blocks - Improve documentation with clearer installation instructions - Add important notes about ES modules and SDK requirements - Update environment examples with API key format and model recommendations - Include index.js in package files list - Bump version to 1.0.2
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
# API Keys (Required)
|
# 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 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
|
MAX_TOKENS=4000 # Maximum tokens for model responses
|
||||||
TEMPERATURE=0.7 # Temperature for model responses (0.0-1.0)
|
TEMPERATURE=0.7 # Temperature for model responses (0.0-1.0)
|
||||||
|
|
||||||
|
|||||||
30
README.md
30
README.md
@@ -2,10 +2,16 @@
|
|||||||
|
|
||||||
A task management system for AI-driven development with Claude, designed to work seamlessly with Cursor AI.
|
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
|
## Installation
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm install -g claude-task-master
|
npm install claude-task-master
|
||||||
```
|
```
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
@@ -13,25 +19,15 @@ npm install -g claude-task-master
|
|||||||
### Initialize a new project
|
### Initialize a new project
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Navigate to your project directory
|
npx claude-task-init
|
||||||
mkdir my-new-project
|
|
||||||
cd my-new-project
|
|
||||||
|
|
||||||
# Initialize the project
|
|
||||||
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
|
### Important Notes
|
||||||
- `scripts/dev.js` - Task management script
|
|
||||||
- `scripts/README.md` - Documentation for the script
|
1. This package uses ES modules. Your package.json should include `"type": "module"`.
|
||||||
- `scripts/example_prd.txt` - Example PRD template
|
2. The Anthropic SDK version should be 0.39.0 or higher.
|
||||||
- `.env.example` - Example environment variables
|
|
||||||
- `.gitignore` - Git ignore file
|
|
||||||
- `package.json` - Project configuration
|
|
||||||
- `tasks.json` - Empty tasks file
|
|
||||||
- `tasks/` - Directory for task files
|
|
||||||
|
|
||||||
## Integrating with Cursor AI
|
## Integrating with Cursor AI
|
||||||
|
|
||||||
|
|||||||
16
index.js
16
index.js
@@ -6,14 +6,22 @@
|
|||||||
// This file serves as the main entry point for the package
|
// This file serves as the main entry point for the package
|
||||||
// The primary functionality is provided through the CLI commands
|
// 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
|
// 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
|
// Export a function to initialize a new project programmatically
|
||||||
exports.initProject = async (options = {}) => {
|
export const initProject = async (options = {}) => {
|
||||||
const init = require('./scripts/init');
|
const init = await import('./scripts/init.js');
|
||||||
return init.initializeProject(options);
|
return init.initializeProject(options);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Export version information
|
// Export version information
|
||||||
exports.version = require('./package.json').version;
|
export const version = require('./package.json').version;
|
||||||
10
package.json
10
package.json
@@ -1,10 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "claude-task-master",
|
"name": "claude-task-master",
|
||||||
"version": "1.0.1",
|
"version": "1.0.2",
|
||||||
"description": "A task management system for AI-driven development with Claude",
|
"description": "A task management system for AI-driven development with Claude",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
"type": "module",
|
||||||
"bin": {
|
"bin": {
|
||||||
"claude-task-init": "./scripts/init.js"
|
"claude-task-init": "scripts/init.js"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
@@ -23,7 +24,7 @@
|
|||||||
"author": "Eyal Toledano",
|
"author": "Eyal Toledano",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@anthropic-ai/sdk": "^0.10.0",
|
"@anthropic-ai/sdk": "^0.39.0",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
"commander": "^11.1.0",
|
"commander": "^11.1.0",
|
||||||
"dotenv": "^16.3.1"
|
"dotenv": "^16.3.1"
|
||||||
@@ -43,6 +44,7 @@
|
|||||||
"scripts/init.js",
|
"scripts/init.js",
|
||||||
"scripts/dev.js",
|
"scripts/dev.js",
|
||||||
"templates/**",
|
"templates/**",
|
||||||
"README.md"
|
"README.md",
|
||||||
|
"index.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,11 @@
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import dotenv from 'dotenv';
|
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
|
// Load environment variables from .env file
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
@@ -169,9 +174,17 @@ async function callClaude(prdContent, prdPath, numTasks) {
|
|||||||
log('debug', `Response length: ${textContent.length} characters`);
|
log('debug', `Response length: ${textContent.length} characters`);
|
||||||
|
|
||||||
try {
|
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...");
|
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`);
|
log('info', `Successfully parsed JSON with ${parsedJson.tasks?.length || 0} tasks`);
|
||||||
return parsedJson;
|
return parsedJson;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
const fs = require('fs');
|
import fs from 'fs';
|
||||||
const path = require('path');
|
import path from 'path';
|
||||||
const { execSync } = require('child_process');
|
import { execSync } from 'child_process';
|
||||||
const readline = require('readline');
|
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
|
// Create readline interface for user input
|
||||||
const rl = readline.createInterface({
|
const rl = readline.createInterface({
|
||||||
@@ -143,6 +148,7 @@ function createProjectStructure(projectName, projectDescription, projectVersion,
|
|||||||
version: projectVersion,
|
version: projectVersion,
|
||||||
description: projectDescription,
|
description: projectDescription,
|
||||||
author: authorName,
|
author: authorName,
|
||||||
|
type: "module",
|
||||||
scripts: {
|
scripts: {
|
||||||
"dev": "node scripts/dev.js",
|
"dev": "node scripts/dev.js",
|
||||||
"list": "node scripts/dev.js list",
|
"list": "node scripts/dev.js list",
|
||||||
@@ -150,7 +156,7 @@ function createProjectStructure(projectName, projectDescription, projectVersion,
|
|||||||
"parse-prd": "node scripts/dev.js parse-prd"
|
"parse-prd": "node scripts/dev.js parse-prd"
|
||||||
},
|
},
|
||||||
dependencies: {
|
dependencies: {
|
||||||
"@anthropic-ai/sdk": "^0.10.0",
|
"@anthropic-ai/sdk": "^0.39.0",
|
||||||
"chalk": "^4.1.2",
|
"chalk": "^4.1.2",
|
||||||
"commander": "^11.1.0",
|
"commander": "^11.1.0",
|
||||||
"dotenv": "^16.3.1"
|
"dotenv": "^16.3.1"
|
||||||
@@ -230,7 +236,7 @@ function createProjectStructure(projectName, projectDescription, projectVersion,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run the initialization if this script is executed directly
|
// Run the initialization if this script is executed directly
|
||||||
if (require.main === module) {
|
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
||||||
(async function main() {
|
(async function main() {
|
||||||
try {
|
try {
|
||||||
await initializeProject();
|
await initializeProject();
|
||||||
@@ -242,7 +248,7 @@ if (require.main === module) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Export functions for programmatic use
|
// Export functions for programmatic use
|
||||||
module.exports = {
|
export {
|
||||||
initializeProject,
|
initializeProject,
|
||||||
createProjectStructure,
|
createProjectStructure,
|
||||||
log
|
log
|
||||||
|
|||||||
@@ -5,9 +5,14 @@
|
|||||||
* It ensures all necessary files are included and properly configured.
|
* It ensures all necessary files are included and properly configured.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const fs = require('fs');
|
import fs from 'fs';
|
||||||
const path = require('path');
|
import path from 'path';
|
||||||
const { execSync } = require('child_process');
|
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
|
// Define colors for console output
|
||||||
const COLORS = {
|
const COLORS = {
|
||||||
|
|||||||
@@ -34,6 +34,12 @@ This project uses the Claude Task Master system to manage development tasks in a
|
|||||||
npm run generate
|
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
|
## 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.
|
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.
|
||||||
|
|||||||
@@ -42,6 +42,11 @@
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import dotenv from 'dotenv';
|
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
|
// Load environment variables from .env file
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
@@ -169,9 +174,17 @@ async function callClaude(prdContent, prdPath, numTasks) {
|
|||||||
log('debug', `Response length: ${textContent.length} characters`);
|
log('debug', `Response length: ${textContent.length} characters`);
|
||||||
|
|
||||||
try {
|
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...");
|
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`);
|
log('info', `Successfully parsed JSON with ${parsedJson.tasks?.length || 0} tasks`);
|
||||||
return parsedJson;
|
return parsedJson;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
# Required
|
# Required
|
||||||
ANTHROPIC_API_KEY=your-api-key-here
|
ANTHROPIC_API_KEY=your-api-key-here # Format: sk-ant-api03-...
|
||||||
|
|
||||||
# Optional - defaults shown
|
# Optional - defaults shown
|
||||||
MODEL=claude-3-7-sonnet-20250219
|
MODEL=claude-3-7-sonnet-20250219 # Recommended models: claude-3-7-sonnet-20250219, claude-3-opus-20240229
|
||||||
MAX_TOKENS=4000
|
MAX_TOKENS=4000 # Maximum tokens for model responses
|
||||||
TEMPERATURE=0.7
|
TEMPERATURE=0.7 # Temperature for model responses (0.0-1.0)
|
||||||
DEBUG=false
|
DEBUG=false # Enable debug logging (true/false)
|
||||||
LOG_LEVEL=info
|
LOG_LEVEL=info # Log level (debug, info, warn, error)
|
||||||
DEFAULT_SUBTASKS=3
|
DEFAULT_SUBTASKS=3 # Default number of subtasks when expanding
|
||||||
DEFAULT_PRIORITY=medium
|
DEFAULT_PRIORITY=medium # Default priority for generated tasks (high, medium, low)
|
||||||
PROJECT_NAME={{projectName}}
|
PROJECT_NAME={{projectName}} # Project name for tasks.json metadata
|
||||||
PROJECT_VERSION={{projectVersion}}
|
PROJECT_VERSION={{projectVersion}} # Project version for tasks.json metadata
|
||||||
Reference in New Issue
Block a user