Compare commits
3 Commits
fix/ollama
...
fix/set-ta
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3592736451 | ||
|
|
e5ed10275e | ||
|
|
97bf01a0ac |
5
.changeset/sharp-dingos-melt.md
Normal file
5
.changeset/sharp-dingos-melt.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'task-master-ai': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Fix the error handling of task status settings
|
||||||
@@ -11,6 +11,7 @@ import {
|
|||||||
} from './utils.js';
|
} from './utils.js';
|
||||||
import { setTaskStatusDirect } from '../core/task-master-core.js';
|
import { setTaskStatusDirect } from '../core/task-master-core.js';
|
||||||
import { findTasksJsonPath } from '../core/utils/path-utils.js';
|
import { findTasksJsonPath } from '../core/utils/path-utils.js';
|
||||||
|
import { TASK_STATUS_OPTIONS } from '../../../src/constants/task-status.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register the setTaskStatus tool with the MCP server
|
* Register the setTaskStatus tool with the MCP server
|
||||||
@@ -27,7 +28,7 @@ export function registerSetTaskStatusTool(server) {
|
|||||||
"Task ID or subtask ID (e.g., '15', '15.2'). Can be comma-separated to update multiple tasks/subtasks at once."
|
"Task ID or subtask ID (e.g., '15', '15.2'). Can be comma-separated to update multiple tasks/subtasks at once."
|
||||||
),
|
),
|
||||||
status: z
|
status: z
|
||||||
.string()
|
.enum(TASK_STATUS_OPTIONS)
|
||||||
.describe(
|
.describe(
|
||||||
"New status to set (e.g., 'pending', 'done', 'in-progress', 'review', 'deferred', 'cancelled'."
|
"New status to set (e.g., 'pending', 'done', 'in-progress', 'review', 'deferred', 'cancelled'."
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -73,6 +73,10 @@ import {
|
|||||||
getApiKeyStatusReport
|
getApiKeyStatusReport
|
||||||
} from './task-manager/models.js';
|
} from './task-manager/models.js';
|
||||||
import { findProjectRoot } from './utils.js';
|
import { findProjectRoot } from './utils.js';
|
||||||
|
import {
|
||||||
|
isValidTaskStatus,
|
||||||
|
TASK_STATUS_OPTIONS
|
||||||
|
} from '../../src/constants/task-status.js';
|
||||||
import { getTaskMasterVersion } from '../../src/utils/getVersion.js';
|
import { getTaskMasterVersion } from '../../src/utils/getVersion.js';
|
||||||
/**
|
/**
|
||||||
* Runs the interactive setup process for model configuration.
|
* Runs the interactive setup process for model configuration.
|
||||||
@@ -1033,7 +1037,7 @@ function registerCommands(programInstance) {
|
|||||||
)
|
)
|
||||||
.option(
|
.option(
|
||||||
'-s, --status <status>',
|
'-s, --status <status>',
|
||||||
'New status (todo, in-progress, review, done)'
|
`New status (one of: ${TASK_STATUS_OPTIONS.join(', ')})`
|
||||||
)
|
)
|
||||||
.option('-f, --file <file>', 'Path to the tasks file', 'tasks/tasks.json')
|
.option('-f, --file <file>', 'Path to the tasks file', 'tasks/tasks.json')
|
||||||
.action(async (options) => {
|
.action(async (options) => {
|
||||||
@@ -1046,6 +1050,16 @@ function registerCommands(programInstance) {
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!isValidTaskStatus(status)) {
|
||||||
|
console.error(
|
||||||
|
chalk.red(
|
||||||
|
`Error: Invalid status value: ${status}. Use one of: ${TASK_STATUS_OPTIONS.join(', ')}`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
chalk.blue(`Setting status of task(s) ${taskId} to: ${status}`)
|
chalk.blue(`Setting status of task(s) ${taskId} to: ${status}`)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -8,6 +8,10 @@ import { validateTaskDependencies } from '../dependency-manager.js';
|
|||||||
import { getDebugFlag } from '../config-manager.js';
|
import { getDebugFlag } from '../config-manager.js';
|
||||||
import updateSingleTaskStatus from './update-single-task-status.js';
|
import updateSingleTaskStatus from './update-single-task-status.js';
|
||||||
import generateTaskFiles from './generate-task-files.js';
|
import generateTaskFiles from './generate-task-files.js';
|
||||||
|
import {
|
||||||
|
isValidTaskStatus,
|
||||||
|
TASK_STATUS_OPTIONS
|
||||||
|
} from '../../../src/constants/task-status.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the status of a task
|
* Set the status of a task
|
||||||
@@ -19,6 +23,11 @@ import generateTaskFiles from './generate-task-files.js';
|
|||||||
*/
|
*/
|
||||||
async function setTaskStatus(tasksPath, taskIdInput, newStatus, options = {}) {
|
async function setTaskStatus(tasksPath, taskIdInput, newStatus, options = {}) {
|
||||||
try {
|
try {
|
||||||
|
if (!isValidTaskStatus(newStatus)) {
|
||||||
|
throw new Error(
|
||||||
|
`Error: Invalid status value: ${newStatus}. Use one of: ${TASK_STATUS_OPTIONS.join(', ')}`
|
||||||
|
);
|
||||||
|
}
|
||||||
// Determine if we're in MCP mode by checking for mcpLog
|
// Determine if we're in MCP mode by checking for mcpLog
|
||||||
const isMcpMode = !!options?.mcpLog;
|
const isMcpMode = !!options?.mcpLog;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
|
|
||||||
import { log } from '../utils.js';
|
import { log } from '../utils.js';
|
||||||
|
import { isValidTaskStatus } from '../../../src/constants/task-status.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the status of a single task
|
* Update the status of a single task
|
||||||
@@ -17,6 +18,12 @@ async function updateSingleTaskStatus(
|
|||||||
data,
|
data,
|
||||||
showUi = true
|
showUi = true
|
||||||
) {
|
) {
|
||||||
|
if (!isValidTaskStatus(newStatus)) {
|
||||||
|
throw new Error(
|
||||||
|
`Error: Invalid status value: ${newStatus}. Use one of: ${TASK_STATUS_OPTIONS.join(', ')}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Check if it's a subtask (e.g., "1.2")
|
// Check if it's a subtask (e.g., "1.2")
|
||||||
if (taskIdInput.includes('.')) {
|
if (taskIdInput.includes('.')) {
|
||||||
const [parentId, subtaskId] = taskIdInput
|
const [parentId, subtaskId] = taskIdInput
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ import {
|
|||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import { findNextTask, analyzeTaskComplexity } from './task-manager.js';
|
import { findNextTask, analyzeTaskComplexity } from './task-manager.js';
|
||||||
import { getProjectName, getDefaultSubtasks } from './config-manager.js';
|
import { getProjectName, getDefaultSubtasks } from './config-manager.js';
|
||||||
|
import { TASK_STATUS_OPTIONS } from '../../src/constants/task-status.js';
|
||||||
import { getTaskMasterVersion } from '../../src/utils/getVersion.js';
|
import { getTaskMasterVersion } from '../../src/utils/getVersion.js';
|
||||||
|
|
||||||
// Create a color gradient for the banner
|
// Create a color gradient for the banner
|
||||||
@@ -448,7 +449,7 @@ function displayHelp() {
|
|||||||
{
|
{
|
||||||
name: 'set-status',
|
name: 'set-status',
|
||||||
args: '--id=<id> --status=<status>',
|
args: '--id=<id> --status=<status>',
|
||||||
desc: 'Update task status (done, pending, etc.)'
|
desc: `Update task status (${TASK_STATUS_OPTIONS.join(', ')})`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'update',
|
name: 'update',
|
||||||
|
|||||||
32
src/constants/task-status.js
Normal file
32
src/constants/task-status.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* @typedef {'pending' | 'done' | 'in-progress' | 'review' | 'deferred' | 'cancelled'} TaskStatus
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task status options list
|
||||||
|
* @type {TaskStatus[]}
|
||||||
|
* @description Defines possible task statuses:
|
||||||
|
* - pending: Task waiting to start
|
||||||
|
* - done: Task completed
|
||||||
|
* - in-progress: Task in progress
|
||||||
|
* - review: Task completed and waiting for review
|
||||||
|
* - deferred: Task postponed or paused
|
||||||
|
* - cancelled: Task cancelled and will not be completed
|
||||||
|
*/
|
||||||
|
export const TASK_STATUS_OPTIONS = [
|
||||||
|
'pending',
|
||||||
|
'done',
|
||||||
|
'in-progress',
|
||||||
|
'review',
|
||||||
|
'deferred',
|
||||||
|
'cancelled'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a given status is a valid task status
|
||||||
|
* @param {string} status - The status to check
|
||||||
|
* @returns {boolean} True if the status is valid, false otherwise
|
||||||
|
*/
|
||||||
|
export function isValidTaskStatus(status) {
|
||||||
|
return TASK_STATUS_OPTIONS.includes(status);
|
||||||
|
}
|
||||||
@@ -199,6 +199,12 @@ const testSetTaskStatus = (tasksData, taskIdInput, newStatus) => {
|
|||||||
|
|
||||||
// Simplified version of updateSingleTaskStatus for testing
|
// Simplified version of updateSingleTaskStatus for testing
|
||||||
const testUpdateSingleTaskStatus = (tasksData, taskIdInput, newStatus) => {
|
const testUpdateSingleTaskStatus = (tasksData, taskIdInput, newStatus) => {
|
||||||
|
if (!isValidTaskStatus(newStatus)) {
|
||||||
|
throw new Error(
|
||||||
|
`Error: Invalid status value: ${newStatus}. Use one of: ${TASK_STATUS_OPTIONS.join(', ')}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Check if it's a subtask (e.g., "1.2")
|
// Check if it's a subtask (e.g., "1.2")
|
||||||
if (taskIdInput.includes('.')) {
|
if (taskIdInput.includes('.')) {
|
||||||
const [parentId, subtaskId] = taskIdInput
|
const [parentId, subtaskId] = taskIdInput
|
||||||
@@ -329,6 +335,10 @@ const testAddTask = (
|
|||||||
import * as taskManager from '../../scripts/modules/task-manager.js';
|
import * as taskManager from '../../scripts/modules/task-manager.js';
|
||||||
import { sampleClaudeResponse } from '../fixtures/sample-claude-response.js';
|
import { sampleClaudeResponse } from '../fixtures/sample-claude-response.js';
|
||||||
import { sampleTasks, emptySampleTasks } from '../fixtures/sample-tasks.js';
|
import { sampleTasks, emptySampleTasks } from '../fixtures/sample-tasks.js';
|
||||||
|
import {
|
||||||
|
isValidTaskStatus,
|
||||||
|
TASK_STATUS_OPTIONS
|
||||||
|
} from '../../src/constants/task-status.js';
|
||||||
|
|
||||||
// Destructure the required functions for convenience
|
// Destructure the required functions for convenience
|
||||||
const { findNextTask, generateTaskFiles, clearSubtasks, updateTaskById } =
|
const { findNextTask, generateTaskFiles, clearSubtasks, updateTaskById } =
|
||||||
@@ -1165,6 +1175,16 @@ describe('Task Manager Module', () => {
|
|||||||
expect(testTasksData.tasks[1].status).toBe('done');
|
expect(testTasksData.tasks[1].status).toBe('done');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should throw error for invalid status', async () => {
|
||||||
|
// Arrange
|
||||||
|
const testTasksData = JSON.parse(JSON.stringify(sampleTasks));
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(() =>
|
||||||
|
testUpdateSingleTaskStatus(testTasksData, '2', 'Done')
|
||||||
|
).toThrow(/Error: Invalid status value: Done./);
|
||||||
|
});
|
||||||
|
|
||||||
test('should update subtask status', async () => {
|
test('should update subtask status', async () => {
|
||||||
// Arrange
|
// Arrange
|
||||||
const testTasksData = JSON.parse(JSON.stringify(sampleTasks));
|
const testTasksData = JSON.parse(JSON.stringify(sampleTasks));
|
||||||
|
|||||||
Reference in New Issue
Block a user