refactor(config): Standardize env var access and config getters
This commit focuses on standardizing configuration and API key access patterns across key modules as part of subtask 61.34. Key changes include: - Refactored `ai-services.js` to remove global AI clients and use `resolveEnvVariable` for API key checks. Client instantiation now relies on `getAnthropicClient`/`getPerplexityClient` accepting a session object. - Refactored `task-manager.js` (`analyzeTaskComplexity` function) to use the unified `generateTextService` from `ai-services-unified.js`, removing direct AI client calls. - Replaced direct `process.env` access for model parameters and other configurations (`PERPLEXITY_MODEL`, `CONFIG.*`) in `task-manager.js` with calls to the appropriate getters from `config-manager.js` (e.g., `getResearchModelId(session)`, `getMainMaxTokens(session)`). - Ensured `utils.js` (`resolveEnvVariable`) correctly handles potentially undefined session objects. - Updated function signatures where necessary to propagate the `session` object for correct context-aware configuration/key retrieval. This moves towards the goal of using `ai-client-factory.js` and `ai-services-unified.js` as the standard pattern for AI interactions and centralizing configuration management through `config-manager.js`.
This commit is contained in:
158
scripts/modules/task-manager/remove-task.js
Normal file
158
scripts/modules/task-manager/remove-task.js
Normal file
@@ -0,0 +1,158 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
import { log, readJSON, writeJSON } from '../utils.js';
|
||||
import generateTaskFiles from './generate-task-files.js';
|
||||
import taskExists from './task-exists.js';
|
||||
|
||||
/**
|
||||
* Removes a task or subtask from the tasks file
|
||||
* @param {string} tasksPath - Path to the tasks file
|
||||
* @param {string|number} taskId - ID of task or subtask to remove (e.g., '5' or '5.2')
|
||||
* @returns {Object} Result object with success message and removed task info
|
||||
*/
|
||||
async function removeTask(tasksPath, taskId) {
|
||||
try {
|
||||
// Read the tasks file
|
||||
const data = readJSON(tasksPath);
|
||||
if (!data || !data.tasks) {
|
||||
throw new Error(`No valid tasks found in ${tasksPath}`);
|
||||
}
|
||||
|
||||
// Check if the task ID exists
|
||||
if (!taskExists(data.tasks, taskId)) {
|
||||
throw new Error(`Task with ID ${taskId} not found`);
|
||||
}
|
||||
|
||||
// Handle subtask removal (e.g., '5.2')
|
||||
if (typeof taskId === 'string' && taskId.includes('.')) {
|
||||
const [parentTaskId, subtaskId] = taskId
|
||||
.split('.')
|
||||
.map((id) => parseInt(id, 10));
|
||||
|
||||
// Find the parent task
|
||||
const parentTask = data.tasks.find((t) => t.id === parentTaskId);
|
||||
if (!parentTask || !parentTask.subtasks) {
|
||||
throw new Error(
|
||||
`Parent task with ID ${parentTaskId} or its subtasks not found`
|
||||
);
|
||||
}
|
||||
|
||||
// Find the subtask to remove
|
||||
const subtaskIndex = parentTask.subtasks.findIndex(
|
||||
(st) => st.id === subtaskId
|
||||
);
|
||||
if (subtaskIndex === -1) {
|
||||
throw new Error(
|
||||
`Subtask with ID ${subtaskId} not found in parent task ${parentTaskId}`
|
||||
);
|
||||
}
|
||||
|
||||
// Store the subtask info before removal for the result
|
||||
const removedSubtask = parentTask.subtasks[subtaskIndex];
|
||||
|
||||
// Remove the subtask
|
||||
parentTask.subtasks.splice(subtaskIndex, 1);
|
||||
|
||||
// Remove references to this subtask in other subtasks' dependencies
|
||||
if (parentTask.subtasks && parentTask.subtasks.length > 0) {
|
||||
parentTask.subtasks.forEach((subtask) => {
|
||||
if (
|
||||
subtask.dependencies &&
|
||||
subtask.dependencies.includes(subtaskId)
|
||||
) {
|
||||
subtask.dependencies = subtask.dependencies.filter(
|
||||
(depId) => depId !== subtaskId
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Save the updated tasks
|
||||
writeJSON(tasksPath, data);
|
||||
|
||||
// Generate updated task files
|
||||
try {
|
||||
await generateTaskFiles(tasksPath, path.dirname(tasksPath));
|
||||
} catch (genError) {
|
||||
log(
|
||||
'warn',
|
||||
`Successfully removed subtask but failed to regenerate task files: ${genError.message}`
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: `Successfully removed subtask ${subtaskId} from task ${parentTaskId}`,
|
||||
removedTask: removedSubtask,
|
||||
parentTaskId: parentTaskId
|
||||
};
|
||||
}
|
||||
|
||||
// Handle main task removal
|
||||
const taskIdNum = parseInt(taskId, 10);
|
||||
const taskIndex = data.tasks.findIndex((t) => t.id === taskIdNum);
|
||||
if (taskIndex === -1) {
|
||||
throw new Error(`Task with ID ${taskId} not found`);
|
||||
}
|
||||
|
||||
// Store the task info before removal for the result
|
||||
const removedTask = data.tasks[taskIndex];
|
||||
|
||||
// Remove the task
|
||||
data.tasks.splice(taskIndex, 1);
|
||||
|
||||
// Remove references to this task in other tasks' dependencies
|
||||
data.tasks.forEach((task) => {
|
||||
if (task.dependencies && task.dependencies.includes(taskIdNum)) {
|
||||
task.dependencies = task.dependencies.filter(
|
||||
(depId) => depId !== taskIdNum
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// Save the updated tasks
|
||||
writeJSON(tasksPath, data);
|
||||
|
||||
// Delete the task file if it exists
|
||||
const taskFileName = path.join(
|
||||
path.dirname(tasksPath),
|
||||
`task_${taskIdNum.toString().padStart(3, '0')}.txt`
|
||||
);
|
||||
if (fs.existsSync(taskFileName)) {
|
||||
try {
|
||||
fs.unlinkSync(taskFileName);
|
||||
} catch (unlinkError) {
|
||||
log(
|
||||
'warn',
|
||||
`Successfully removed task from tasks.json but failed to delete task file: ${unlinkError.message}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Generate updated task files
|
||||
try {
|
||||
await generateTaskFiles(tasksPath, path.dirname(tasksPath));
|
||||
} catch (genError) {
|
||||
log(
|
||||
'warn',
|
||||
`Successfully removed task but failed to regenerate task files: ${genError.message}`
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: `Successfully removed task ${taskId}`,
|
||||
removedTask: removedTask
|
||||
};
|
||||
} catch (error) {
|
||||
log('error', `Error removing task: ${error.message}`);
|
||||
throw {
|
||||
code: 'REMOVE_TASK_ERROR',
|
||||
message: error.message,
|
||||
details: error.stack
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default removeTask;
|
||||
Reference in New Issue
Block a user