feat: add optional feature flag for code context (#1165)

* feat: add featureFlag for codebase analysis

* chore: add changeset

* chore: run format
This commit is contained in:
Ralph Khreish
2025-08-29 00:28:00 +02:00
committed by GitHub
parent be0c0f267c
commit c4f92f6a0a
14 changed files with 98 additions and 38 deletions

View File

@@ -0,0 +1,11 @@
---
"task-master-ai": minor
---
Add configurable codebase analysis feature flag with multiple configuration sources
Users can now control whether codebase analysis features (Claude Code and Gemini CLI integration) are enabled through environment variables, MCP configuration, or project config files.
Priority order: .env > MCP session env > .taskmaster/config.json.
Set `TASKMASTER_ENABLE_CODEBASE_ANALYSIS=false` in `.env` to disable codebase analysis prompts and tool integration.

View File

@@ -9,17 +9,9 @@
"engines": {
"vscode": "^1.93.0"
},
"categories": [
"AI",
"Visualization",
"Education",
"Other"
],
"categories": ["AI", "Visualization", "Education", "Other"],
"main": "./dist/extension.js",
"activationEvents": [
"onStartupFinished",
"workspaceContains:.taskmaster/**"
],
"activationEvents": ["onStartupFinished", "workspaceContains:.taskmaster/**"],
"contributes": {
"viewsContainers": {
"activitybar": [
@@ -147,11 +139,7 @@
},
"taskmaster.ui.theme": {
"type": "string",
"enum": [
"auto",
"light",
"dark"
],
"enum": ["auto", "light", "dark"],
"default": "auto",
"description": "UI theme preference"
},
@@ -212,12 +200,7 @@
},
"taskmaster.debug.logLevel": {
"type": "string",
"enum": [
"error",
"warn",
"info",
"debug"
],
"enum": ["error", "warn", "info", "debug"],
"default": "info",
"description": "Logging level"
},

View File

@@ -9,10 +9,7 @@
"task-master-mcp": "mcp-server/server.js",
"task-master-ai": "mcp-server/server.js"
},
"workspaces": [
"apps/*",
"."
],
"workspaces": ["apps/*", "."],
"scripts": {
"test": "node --experimental-vm-modules node_modules/.bin/jest",
"test:fails": "node --experimental-vm-modules node_modules/.bin/jest --onlyFailures",

View File

@@ -72,7 +72,8 @@ const DEFAULTS = {
projectName: 'Task Master',
ollamaBaseURL: 'http://localhost:11434/api',
bedrockBaseURL: 'https://bedrock.us-east-1.amazonaws.com',
responseLanguage: 'English'
responseLanguage: 'English',
enableCodebaseAnalysis: true
},
claudeCode: {}
};
@@ -428,15 +429,56 @@ function getResearchProvider(explicitRoot = null) {
}
/**
* Check if a codebase analysis provider is being used (Claude Code or Gemini CLI)
* Check if codebase analysis feature flag is enabled across all sources
* Priority: .env > MCP env > config.json
* @param {object|null} session - MCP session object (optional)
* @param {string|null} projectRoot - Project root path (optional)
* @returns {boolean} True if codebase analysis is enabled
*/
function isCodebaseAnalysisEnabled(session = null, projectRoot = null) {
// Priority 1: Environment variable
const envFlag = resolveEnvVariable(
'TASKMASTER_ENABLE_CODEBASE_ANALYSIS',
session,
projectRoot
);
if (envFlag !== null && envFlag !== undefined && envFlag !== '') {
return envFlag.toLowerCase() === 'true' || envFlag === '1';
}
// Priority 2: MCP session environment
if (session?.env?.TASKMASTER_ENABLE_CODEBASE_ANALYSIS) {
const mcpFlag = session.env.TASKMASTER_ENABLE_CODEBASE_ANALYSIS;
return mcpFlag.toLowerCase() === 'true' || mcpFlag === '1';
}
// Priority 3: Configuration file
const globalConfig = getGlobalConfig(projectRoot);
return globalConfig.enableCodebaseAnalysis !== false; // Default to true
}
/**
* Check if codebase analysis is available and enabled
* @param {boolean} useResearch - Whether to check research provider or main provider
* @param {string|null} projectRoot - Project root path (optional)
* @returns {boolean} True if a codebase analysis provider is the current provider
* @param {object|null} session - MCP session object (optional)
* @returns {boolean} True if codebase analysis is available and enabled
*/
function hasCodebaseAnalysis(useResearch = false, projectRoot = null) {
function hasCodebaseAnalysis(
useResearch = false,
projectRoot = null,
session = null
) {
// First check if the feature is enabled
if (!isCodebaseAnalysisEnabled(session, projectRoot)) {
return false;
}
// Then check if a codebase analysis provider is configured
const currentProvider = useResearch
? getResearchProvider(projectRoot)
: getMainProvider(projectRoot);
return (
currentProvider === CUSTOM_PROVIDERS.CLAUDE_CODE ||
currentProvider === CUSTOM_PROVIDERS.GEMINI_CLI
@@ -558,6 +600,11 @@ function getResponseLanguage(explicitRoot = null) {
return getGlobalConfig(explicitRoot).responseLanguage;
}
function getCodebaseAnalysisEnabled(explicitRoot = null) {
// Directly return value from config
return getGlobalConfig(explicitRoot).enableCodebaseAnalysis;
}
/**
* Gets model parameters (maxTokens, temperature) for a specific role,
* considering model-specific overrides from supported-models.json.
@@ -1016,6 +1063,8 @@ export {
getAzureBaseURL,
getBedrockBaseURL,
getResponseLanguage,
getCodebaseAnalysisEnabled,
isCodebaseAnalysisEnabled,
getParametersForRole,
getUserId,
// API Key Checkers (still relevant)

View File

@@ -426,7 +426,11 @@ async function addTask(
useResearch,
priority: effectivePriority,
dependencies: numericDependencies,
hasCodebaseAnalysis: hasCodebaseAnalysis(useResearch, projectRoot),
hasCodebaseAnalysis: hasCodebaseAnalysis(
useResearch,
projectRoot,
session
),
projectRoot: projectRoot
}
);

View File

@@ -419,7 +419,11 @@ async function analyzeTaskComplexity(options, context = {}) {
tasks: tasksData.tasks,
gatheredContext: gatheredContext || '',
useResearch: useResearch,
hasCodebaseAnalysis: hasCodebaseAnalysis(useResearch, projectRoot),
hasCodebaseAnalysis: hasCodebaseAnalysis(
useResearch,
projectRoot,
session
),
projectRoot: projectRoot || ''
};

View File

@@ -458,7 +458,8 @@ async function expandTask(
// Check if a codebase analysis provider is being used
const hasCodebaseAnalysisCapability = hasCodebaseAnalysis(
useResearch,
projectRoot
projectRoot,
session
);
// Combine all context sources into a single additionalContext parameter

View File

@@ -77,7 +77,7 @@ export class PrdParseConfig {
* Check if codebase analysis is available (Claude Code or Gemini CLI)
*/
hasCodebaseAnalysis() {
return hasCodebaseAnalysis(this.research, this.projectRoot);
return hasCodebaseAnalysis(this.research, this.projectRoot, this.session);
}
}

View File

@@ -232,7 +232,11 @@ async function updateSubtaskById(
updatePrompt: prompt,
useResearch: useResearch,
gatheredContext: gatheredContext || '',
hasCodebaseAnalysis: hasCodebaseAnalysis(useResearch, projectRoot),
hasCodebaseAnalysis: hasCodebaseAnalysis(
useResearch,
projectRoot,
session
),
projectRoot: projectRoot
};

View File

@@ -458,7 +458,11 @@ async function updateTaskById(
useResearch: useResearch,
currentDetails: taskToUpdate.details || '(No existing details)',
gatheredContext: gatheredContext || '',
hasCodebaseAnalysis: hasCodebaseAnalysis(useResearch, projectRoot),
hasCodebaseAnalysis: hasCodebaseAnalysis(
useResearch,
projectRoot,
session
),
projectRoot: projectRoot
};

View File

@@ -436,7 +436,11 @@ async function updateTasks(
updatePrompt: prompt,
useResearch,
projectContext: gatheredContext,
hasCodebaseAnalysis: hasCodebaseAnalysis(useResearch, projectRoot),
hasCodebaseAnalysis: hasCodebaseAnalysis(
useResearch,
projectRoot,
session
),
projectRoot: projectRoot
}
);

View File

@@ -145,6 +145,7 @@ const DEFAULT_CONFIG = {
projectName: 'Task Master',
ollamaBaseURL: 'http://localhost:11434/api',
bedrockBaseURL: 'https://bedrock.us-east-1.amazonaws.com',
enableCodebaseAnalysis: true,
responseLanguage: 'English'
},
claudeCode: {}

View File

@@ -6,7 +6,6 @@ import {
createGetTagAwareFilePathMock,
createSlugifyTagForFilePathMock
} from './setup.js';
import { hasCodebaseAnalysis } from '../../../../../scripts/modules/config-manager.js';
// Mock the dependencies before importing the module under test
jest.unstable_mockModule('../../../../../scripts/modules/utils.js', () => ({

View File

@@ -6,7 +6,6 @@
import { jest } from '@jest/globals';
import fs from 'fs';
import path from 'path';
import { hasCodebaseAnalysis } from '../../../../../scripts/modules/config-manager.js';
// Mock the dependencies
jest.unstable_mockModule('../../../../../src/utils/path-utils.js', () => ({