Task 104: Implement 'scope-up' and 'scope-down' CLI Commands for Dynamic Task Complexity Adjustment (#1069)
* feat(task-104): Complete task 104 - Implement scope-up and scope-down CLI Commands - Added new CLI commands 'scope-up' and 'scope-down' with comma-separated ID support - Implemented strength levels (light/regular/heavy) and custom prompt functionality - Created core complexity adjustment logic with AI integration - Added MCP tool equivalents for integrated environments - Comprehensive error handling and task validation - Full test coverage with TDD approach - Updated task manager core and UI components Task 104: Implement 'scope-up' and 'scope-down' CLI Commands for Dynamic Task Complexity Adjustment - Complete implementation with CLI, MCP integration, and testing * chore: Add changeset for scope-up and scope-down features - Comprehensive user-facing description with usage examples - Key features and benefits explanation - CLI and MCP integration details - Real-world use cases for agile workflows * feat(extension): Add scope-up and scope-down to VS Code extension task details - Added useScopeUpTask and useScopeDownTask hooks in useTaskQueries.ts - Enhanced AIActionsSection with Task Complexity Adjustment section - Added strength selection (light/regular/heavy) and custom prompt support - Integrated scope buttons with proper loading states and error handling - Uses existing mcpRequest handler for scope_up_task and scope_down_task tools - Maintains consistent UI patterns with existing AI actions Extension now supports dynamic task complexity adjustment directly from task details view.
This commit is contained in:
124
mcp-server/src/core/direct-functions/scope-down.js
Normal file
124
mcp-server/src/core/direct-functions/scope-down.js
Normal file
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* scope-down.js
|
||||
* Direct function implementation for scoping down task complexity
|
||||
*/
|
||||
|
||||
import { scopeDownTask } from '../../../../scripts/modules/task-manager.js';
|
||||
import {
|
||||
enableSilentMode,
|
||||
disableSilentMode
|
||||
} from '../../../../scripts/modules/utils.js';
|
||||
import { createLogWrapper } from '../../tools/utils.js';
|
||||
|
||||
/**
|
||||
* Direct function wrapper for scoping down task complexity with error handling.
|
||||
*
|
||||
* @param {Object} args - Command arguments
|
||||
* @param {string} args.id - Comma-separated list of task IDs to scope down
|
||||
* @param {string} [args.strength='regular'] - Strength level (light, regular, heavy)
|
||||
* @param {string} [args.prompt] - Custom prompt for scoping adjustments
|
||||
* @param {string} [args.tasksJsonPath] - Path to the tasks.json file (resolved by tool)
|
||||
* @param {boolean} [args.research=false] - Whether to use research capabilities for scoping
|
||||
* @param {string} args.projectRoot - Project root path
|
||||
* @param {string} [args.tag] - Tag for the task context (optional)
|
||||
* @param {Object} log - Logger object
|
||||
* @param {Object} context - Additional context (session)
|
||||
* @returns {Promise<Object>} - Result object { success: boolean, data?: any, error?: { code: string, message: string } }
|
||||
*/
|
||||
export async function scopeDownDirect(args, log, context = {}) {
|
||||
// Destructure expected args
|
||||
const {
|
||||
tasksJsonPath,
|
||||
id,
|
||||
strength = 'regular',
|
||||
prompt: customPrompt,
|
||||
research = false,
|
||||
projectRoot,
|
||||
tag
|
||||
} = args;
|
||||
const { session } = context; // Destructure session from context
|
||||
|
||||
// Enable silent mode to prevent console logs from interfering with JSON response
|
||||
enableSilentMode();
|
||||
|
||||
// Create logger wrapper using the utility
|
||||
const mcpLog = createLogWrapper(log);
|
||||
|
||||
try {
|
||||
// Check if tasksJsonPath was provided
|
||||
if (!tasksJsonPath) {
|
||||
log.error('scopeDownDirect called without tasksJsonPath');
|
||||
disableSilentMode(); // Disable before returning
|
||||
return {
|
||||
success: false,
|
||||
error: {
|
||||
code: 'MISSING_ARGUMENT',
|
||||
message: 'tasksJsonPath is required'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Check required parameters
|
||||
if (!id) {
|
||||
log.error('Missing required parameter: id');
|
||||
disableSilentMode();
|
||||
return {
|
||||
success: false,
|
||||
error: {
|
||||
code: 'MISSING_PARAMETER',
|
||||
message: 'The id parameter is required for scoping down tasks'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Parse task IDs
|
||||
const taskIds = id.split(',').map((taskId) => taskId.trim());
|
||||
|
||||
log.info(
|
||||
`Scoping down tasks: ${taskIds.join(', ')}, strength: ${strength}, research: ${research}`
|
||||
);
|
||||
|
||||
// Call the scopeDownTask function
|
||||
const result = await scopeDownTask(
|
||||
tasksJsonPath,
|
||||
taskIds,
|
||||
strength,
|
||||
customPrompt,
|
||||
{
|
||||
session,
|
||||
mcpLog,
|
||||
projectRoot,
|
||||
commandName: 'scope-down',
|
||||
outputType: 'mcp',
|
||||
tag
|
||||
},
|
||||
'json', // outputFormat
|
||||
research
|
||||
);
|
||||
|
||||
// Restore normal logging
|
||||
disableSilentMode();
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
updatedTasks: result.updatedTasks,
|
||||
tasksUpdated: result.updatedTasks.length,
|
||||
message: `Successfully scoped down ${result.updatedTasks.length} task(s)`,
|
||||
telemetryData: result.telemetryData
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
// Make sure to restore normal logging even if there's an error
|
||||
disableSilentMode();
|
||||
|
||||
log.error(`Error in scopeDownDirect: ${error.message}`);
|
||||
return {
|
||||
success: false,
|
||||
error: {
|
||||
code: error.code || 'SCOPE_DOWN_ERROR',
|
||||
message: error.message
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
124
mcp-server/src/core/direct-functions/scope-up.js
Normal file
124
mcp-server/src/core/direct-functions/scope-up.js
Normal file
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* scope-up.js
|
||||
* Direct function implementation for scoping up task complexity
|
||||
*/
|
||||
|
||||
import { scopeUpTask } from '../../../../scripts/modules/task-manager.js';
|
||||
import {
|
||||
enableSilentMode,
|
||||
disableSilentMode
|
||||
} from '../../../../scripts/modules/utils.js';
|
||||
import { createLogWrapper } from '../../tools/utils.js';
|
||||
|
||||
/**
|
||||
* Direct function wrapper for scoping up task complexity with error handling.
|
||||
*
|
||||
* @param {Object} args - Command arguments
|
||||
* @param {string} args.id - Comma-separated list of task IDs to scope up
|
||||
* @param {string} [args.strength='regular'] - Strength level (light, regular, heavy)
|
||||
* @param {string} [args.prompt] - Custom prompt for scoping adjustments
|
||||
* @param {string} [args.tasksJsonPath] - Path to the tasks.json file (resolved by tool)
|
||||
* @param {boolean} [args.research=false] - Whether to use research capabilities for scoping
|
||||
* @param {string} args.projectRoot - Project root path
|
||||
* @param {string} [args.tag] - Tag for the task context (optional)
|
||||
* @param {Object} log - Logger object
|
||||
* @param {Object} context - Additional context (session)
|
||||
* @returns {Promise<Object>} - Result object { success: boolean, data?: any, error?: { code: string, message: string } }
|
||||
*/
|
||||
export async function scopeUpDirect(args, log, context = {}) {
|
||||
// Destructure expected args
|
||||
const {
|
||||
tasksJsonPath,
|
||||
id,
|
||||
strength = 'regular',
|
||||
prompt: customPrompt,
|
||||
research = false,
|
||||
projectRoot,
|
||||
tag
|
||||
} = args;
|
||||
const { session } = context; // Destructure session from context
|
||||
|
||||
// Enable silent mode to prevent console logs from interfering with JSON response
|
||||
enableSilentMode();
|
||||
|
||||
// Create logger wrapper using the utility
|
||||
const mcpLog = createLogWrapper(log);
|
||||
|
||||
try {
|
||||
// Check if tasksJsonPath was provided
|
||||
if (!tasksJsonPath) {
|
||||
log.error('scopeUpDirect called without tasksJsonPath');
|
||||
disableSilentMode(); // Disable before returning
|
||||
return {
|
||||
success: false,
|
||||
error: {
|
||||
code: 'MISSING_ARGUMENT',
|
||||
message: 'tasksJsonPath is required'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Check required parameters
|
||||
if (!id) {
|
||||
log.error('Missing required parameter: id');
|
||||
disableSilentMode();
|
||||
return {
|
||||
success: false,
|
||||
error: {
|
||||
code: 'MISSING_PARAMETER',
|
||||
message: 'The id parameter is required for scoping up tasks'
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Parse task IDs
|
||||
const taskIds = id.split(',').map((taskId) => taskId.trim());
|
||||
|
||||
log.info(
|
||||
`Scoping up tasks: ${taskIds.join(', ')}, strength: ${strength}, research: ${research}`
|
||||
);
|
||||
|
||||
// Call the scopeUpTask function
|
||||
const result = await scopeUpTask(
|
||||
tasksJsonPath,
|
||||
taskIds,
|
||||
strength,
|
||||
customPrompt,
|
||||
{
|
||||
session,
|
||||
mcpLog,
|
||||
projectRoot,
|
||||
commandName: 'scope-up',
|
||||
outputType: 'mcp',
|
||||
tag
|
||||
},
|
||||
'json', // outputFormat
|
||||
research
|
||||
);
|
||||
|
||||
// Restore normal logging
|
||||
disableSilentMode();
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
updatedTasks: result.updatedTasks,
|
||||
tasksUpdated: result.updatedTasks.length,
|
||||
message: `Successfully scoped up ${result.updatedTasks.length} task(s)`,
|
||||
telemetryData: result.telemetryData
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
// Make sure to restore normal logging even if there's an error
|
||||
disableSilentMode();
|
||||
|
||||
log.error(`Error in scopeUpDirect: ${error.message}`);
|
||||
return {
|
||||
success: false,
|
||||
error: {
|
||||
code: error.code || 'SCOPE_UP_ERROR',
|
||||
message: error.message
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user