diff --git a/docs/examples/claude-code-usage.md b/docs/examples/claude-code-usage.md index 3e46a476..f8e6c69c 100644 --- a/docs/examples/claude-code-usage.md +++ b/docs/examples/claude-code-usage.md @@ -60,7 +60,11 @@ task-master set-status --id=task-001 --status=in-progress ## Requirements 1. Claude Code CLI must be installed and authenticated on your system -2. No API key is required in your environment variables or MCP configuration +2. Install the optional `@anthropic-ai/claude-code` package if you enable this provider: + ```bash + npm install @anthropic-ai/claude-code + ``` +3. No API key is required in your environment variables or MCP configuration ## Advanced Settings diff --git a/package-lock.json b/package-lock.json index 4cec0fc9..0e915610 100644 --- a/package-lock.json +++ b/package-lock.json @@ -68,6 +68,9 @@ }, "engines": { "node": ">=18.0.0" + }, + "optionalDependencies": { + "@anthropic-ai/claude-code": "^1.0.25" } }, "node_modules/@ai-sdk/amazon-bedrock": { @@ -446,6 +449,28 @@ "node": ">=6.0.0" } }, + "node_modules/@anthropic-ai/claude-code": { + "version": "1.0.25", + "resolved": "https://registry.npmjs.org/@anthropic-ai/claude-code/-/claude-code-1.0.25.tgz", + "integrity": "sha512-5p4FLlFO4TuRf0zV0axiOxiAkUC8eer0lqJi/A/pA46LESv31Alw6xaNYgwQVkP6oSbP5PydK36u7YrB9QSaXQ==", + "hasInstallScript": true, + "license": "SEE LICENSE IN README.md", + "optional": true, + "bin": { + "claude": "cli.js" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "^0.33.5", + "@img/sharp-darwin-x64": "^0.33.5", + "@img/sharp-linux-arm": "^0.33.5", + "@img/sharp-linux-arm64": "^0.33.5", + "@img/sharp-linux-x64": "^0.33.5", + "@img/sharp-win32-x64": "^0.33.5" + } + }, "node_modules/@anthropic-ai/sdk": { "version": "0.39.0", "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.39.0.tgz", @@ -2651,6 +2676,215 @@ "node": ">=18" } }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@inquirer/checkbox": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.1.4.tgz", @@ -3868,6 +4102,19 @@ "node": ">= 0.6" } }, + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3966,6 +4213,16 @@ "node": ">=8.0.0" } }, + "node_modules/@paralleldrive/cuid2": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@paralleldrive/cuid2/-/cuid2-2.2.2.tgz", + "integrity": "sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@noble/hashes": "^1.1.5" + } + }, "node_modules/@sec-ant/readable-stream": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", @@ -5328,9 +5585,9 @@ } }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", "dev": true, "license": "MIT", "dependencies": { @@ -7159,16 +7416,19 @@ } }, "node_modules/formidable": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.2.tgz", - "integrity": "sha512-Jqc1btCy3QzRbJaICGwKcBfGWuLADRerLzDqi2NwSt/UkXLsHJw2TVResiaoBufHVHy9aSgClOHCeJsSsFLTbg==", + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-3.5.4.tgz", + "integrity": "sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==", "dev": true, "license": "MIT", "dependencies": { + "@paralleldrive/cuid2": "^2.2.2", "dezalgo": "^1.0.4", - "hexoid": "^2.0.0", "once": "^1.4.0" }, + "engines": { + "node": ">=14.0.0" + }, "funding": { "url": "https://ko-fi.com/tunnckoCore/commissions" } @@ -7672,16 +7932,6 @@ "node": ">=18.0.0" } }, - "node_modules/hexoid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hexoid/-/hexoid-2.0.0.tgz", - "integrity": "sha512-qlspKUK7IlSQv2o+5I7yhUd7TxlOG2Vr5LTa3ve2XSNVKAL/n/u/7KLvKmFNimomDIKvZFXWHv0T12mv7rT8Aw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/highlight.js": { "version": "10.7.3", "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", diff --git a/package.json b/package.json index f0dba5db..91e47874 100644 --- a/package.json +++ b/package.json @@ -76,6 +76,9 @@ "uuid": "^11.1.0", "zod": "^3.23.8" }, + "optionalDependencies": { + "@anthropic-ai/claude-code": "^1.0.25" + }, "engines": { "node": ">=18.0.0" }, diff --git a/scripts/init.js b/scripts/init.js index 9f938249..f3b4a202 100755 --- a/scripts/init.js +++ b/scripts/init.js @@ -507,7 +507,7 @@ function createProjectStructure( ...replacements } ); - + // Update config.json with correct maxTokens values from supported-models.json const configPath = path.join(targetDir, TASKMASTER_CONFIG_FILE); if (updateConfigMaxTokens(configPath)) { diff --git a/scripts/modules/update-config-tokens.js b/scripts/modules/update-config-tokens.js index 403bf35c..14e68b2d 100644 --- a/scripts/modules/update-config-tokens.js +++ b/scripts/modules/update-config-tokens.js @@ -20,29 +20,33 @@ export function updateConfigMaxTokens(configPath) { try { // Load supported models const supportedModelsPath = path.join(__dirname, 'supported-models.json'); - const supportedModels = JSON.parse(fs.readFileSync(supportedModelsPath, 'utf-8')); - + const supportedModels = JSON.parse( + fs.readFileSync(supportedModelsPath, 'utf-8') + ); + // Load config const config = JSON.parse(fs.readFileSync(configPath, 'utf-8')); - + // Update each role's maxTokens if the model exists in supported-models.json const roles = ['main', 'research', 'fallback']; - + for (const role of roles) { if (config.models && config.models[role]) { const provider = config.models[role].provider; const modelId = config.models[role].modelId; - + // Find the model in supported models if (supportedModels[provider]) { - const modelData = supportedModels[provider].find(m => m.id === modelId); + const modelData = supportedModels[provider].find( + (m) => m.id === modelId + ); if (modelData && modelData.max_tokens) { config.models[role].maxTokens = modelData.max_tokens; } } } } - + // Write back the updated config fs.writeFileSync(configPath, JSON.stringify(config, null, 2)); return true; @@ -50,4 +54,4 @@ export function updateConfigMaxTokens(configPath) { console.error('Error updating config maxTokens:', error.message); return false; } -} \ No newline at end of file +} diff --git a/src/ai-providers/claude-code.js b/src/ai-providers/claude-code.js index 842f847e..c84ff439 100644 --- a/src/ai-providers/claude-code.js +++ b/src/ai-providers/claude-code.js @@ -44,4 +44,4 @@ export class ClaudeCodeProvider extends BaseAIProvider { this.handleError('client initialization', error); } } -} \ No newline at end of file +} diff --git a/src/ai-providers/custom-sdk/claude-code/errors.js b/src/ai-providers/custom-sdk/claude-code/errors.js index b2d217e0..a0251f37 100644 --- a/src/ai-providers/custom-sdk/claude-code/errors.js +++ b/src/ai-providers/custom-sdk/claude-code/errors.js @@ -123,4 +123,4 @@ export function getErrorMetadata(error) { return /** @type {ClaudeCodeErrorMetadata} */ (error.data); } return undefined; -} \ No newline at end of file +} diff --git a/src/ai-providers/custom-sdk/claude-code/index.js b/src/ai-providers/custom-sdk/claude-code/index.js index ea116bd5..076a2241 100644 --- a/src/ai-providers/custom-sdk/claude-code/index.js +++ b/src/ai-providers/custom-sdk/claude-code/index.js @@ -80,4 +80,4 @@ export { createAPICallError, createAuthenticationError, createTimeoutError -} from './errors.js'; \ No newline at end of file +} from './errors.js'; diff --git a/src/ai-providers/custom-sdk/claude-code/json-extractor.js b/src/ai-providers/custom-sdk/claude-code/json-extractor.js index ff0d884c..335fff82 100644 --- a/src/ai-providers/custom-sdk/claude-code/json-extractor.js +++ b/src/ai-providers/custom-sdk/claude-code/json-extractor.js @@ -56,4 +56,4 @@ export function extractJson(text) { return text; } } -} \ No newline at end of file +} diff --git a/src/ai-providers/custom-sdk/claude-code/language-model.js b/src/ai-providers/custom-sdk/claude-code/language-model.js index ab1172f7..933127c8 100644 --- a/src/ai-providers/custom-sdk/claude-code/language-model.js +++ b/src/ai-providers/custom-sdk/claude-code/language-model.js @@ -7,7 +7,23 @@ import { generateId } from '@ai-sdk/provider-utils'; import { convertToClaudeCodeMessages } from './message-converter.js'; import { extractJson } from './json-extractor.js'; import { createAPICallError, createAuthenticationError } from './errors.js'; -import { query, AbortError } from '@anthropic-ai/claude-code'; + +let query; +let AbortError; + +async function loadClaudeCodeModule() { + if (!query || !AbortError) { + try { + const mod = await import('@anthropic-ai/claude-code'); + query = mod.query; + AbortError = mod.AbortError; + } catch (err) { + throw new Error( + "Claude Code SDK is not installed. Please install '@anthropic-ai/claude-code' to use the claude-code provider." + ); + } + } +} /** * @typedef {import('./types.js').ClaudeCodeSettings} ClaudeCodeSettings @@ -78,7 +94,8 @@ export class ClaudeCodeLanguageModel { const unsupportedParams = []; // Check for unsupported parameters - if (options.temperature !== undefined) unsupportedParams.push('temperature'); + if (options.temperature !== undefined) + unsupportedParams.push('temperature'); if (options.maxTokens !== undefined) unsupportedParams.push('maxTokens'); if (options.topP !== undefined) unsupportedParams.push('topP'); if (options.topK !== undefined) unsupportedParams.push('topK'); @@ -110,6 +127,7 @@ export class ClaudeCodeLanguageModel { * @returns {Promise} */ async doGenerate(options) { + await loadClaudeCodeModule(); const { messagesPrompt } = convertToClaudeCodeMessages( options.prompt, options.mode @@ -188,9 +206,7 @@ export class ClaudeCodeLanguageModel { } } catch (error) { if (error instanceof AbortError) { - throw options.abortSignal?.aborted - ? options.abortSignal.reason - : error; + throw options.abortSignal?.aborted ? options.abortSignal.reason : error; } // Check for authentication errors @@ -256,6 +272,7 @@ export class ClaudeCodeLanguageModel { * @returns {Promise} */ async doStream(options) { + await loadClaudeCodeModule(); const { messagesPrompt } = convertToClaudeCodeMessages( options.prompt, options.mode @@ -368,7 +385,10 @@ export class ClaudeCodeLanguageModel { } } }); - } else if (message.type === 'system' && message.subtype === 'init') { + } else if ( + message.type === 'system' && + message.subtype === 'init' + ) { // Store session ID for future use this.sessionId = message.session_id; @@ -435,4 +455,4 @@ export class ClaudeCodeLanguageModel { } }; } -} \ No newline at end of file +} diff --git a/src/ai-providers/custom-sdk/claude-code/message-converter.js b/src/ai-providers/custom-sdk/claude-code/message-converter.js index a92a3a23..7bad0418 100644 --- a/src/ai-providers/custom-sdk/claude-code/message-converter.js +++ b/src/ai-providers/custom-sdk/claude-code/message-converter.js @@ -136,4 +136,4 @@ Begin your response with { and end with }`; messagesPrompt: finalPrompt, systemPrompt }; -} \ No newline at end of file +} diff --git a/src/ai-providers/custom-sdk/claude-code/types.js b/src/ai-providers/custom-sdk/claude-code/types.js index 4aad25a3..130d1f65 100644 --- a/src/ai-providers/custom-sdk/claude-code/types.js +++ b/src/ai-providers/custom-sdk/claude-code/types.js @@ -70,4 +70,4 @@ * @property {ClaudeCodeSettings} [defaultSettings] - Default settings to use for all models */ -export {}; // This ensures the file is treated as a module \ No newline at end of file +export {}; // This ensures the file is treated as a module