feat(05-02): add task CLI commands
- Add `cw task list --plan <planId>` command - Display tasks as table: name, status, type, priority - Show count of pending/in_progress/completed/blocked - Add `cw task get <taskId>` command - Display full task details: id, name, description, type, priority, status, order, timestamps - Add `cw task status <taskId> <status>` command - Validate status is one of: pending, in_progress, completed, blocked - Confirm status update
This commit is contained in:
@@ -231,11 +231,93 @@ export function createCli(serverHandler?: (port?: number) => Promise<void>): Com
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
program
|
// Task command group
|
||||||
|
const taskCommand = program
|
||||||
.command('task')
|
.command('task')
|
||||||
.description('Manage tasks')
|
.description('Manage tasks');
|
||||||
.action(() => {
|
|
||||||
console.log('cw task: not implemented');
|
// cw task list --plan <planId>
|
||||||
|
taskCommand
|
||||||
|
.command('list')
|
||||||
|
.description('List tasks for a plan')
|
||||||
|
.requiredOption('--plan <planId>', 'Plan ID to list tasks for')
|
||||||
|
.action(async (options: { plan: string }) => {
|
||||||
|
try {
|
||||||
|
const client = createDefaultTrpcClient();
|
||||||
|
const tasks = await client.listTasks.query({ planId: options.plan });
|
||||||
|
if (tasks.length === 0) {
|
||||||
|
console.log('No tasks found for this plan');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count by status
|
||||||
|
const pending = tasks.filter(t => t.status === 'pending' || t.status === 'pending_approval').length;
|
||||||
|
const inProgress = tasks.filter(t => t.status === 'in_progress').length;
|
||||||
|
const completed = tasks.filter(t => t.status === 'completed').length;
|
||||||
|
const blocked = tasks.filter(t => t.status === 'blocked').length;
|
||||||
|
|
||||||
|
console.log('Tasks:');
|
||||||
|
console.log('');
|
||||||
|
for (const task of tasks) {
|
||||||
|
const statusLabel = task.status === 'in_progress' ? 'IN_PROGRESS' : task.status.toUpperCase();
|
||||||
|
const priorityLabel = task.priority === 'high' ? '[HIGH]' : task.priority === 'low' ? '[low]' : '';
|
||||||
|
console.log(` ${task.order}. ${task.name} [${statusLabel}] ${task.type} ${priorityLabel}`);
|
||||||
|
}
|
||||||
|
console.log('');
|
||||||
|
console.log(`Summary: ${pending} pending, ${inProgress} in progress, ${completed} completed, ${blocked} blocked`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to list tasks:', (error as Error).message);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// cw task get <taskId>
|
||||||
|
taskCommand
|
||||||
|
.command('get <taskId>')
|
||||||
|
.description('Get task details by ID')
|
||||||
|
.action(async (taskId: string) => {
|
||||||
|
try {
|
||||||
|
const client = createDefaultTrpcClient();
|
||||||
|
const task = await client.getTask.query({ id: taskId });
|
||||||
|
console.log(`Task: ${task.name}`);
|
||||||
|
console.log(` ID: ${task.id}`);
|
||||||
|
console.log(` Plan: ${task.planId}`);
|
||||||
|
console.log(` Description: ${task.description ?? '(none)'}`);
|
||||||
|
console.log(` Type: ${task.type}`);
|
||||||
|
console.log(` Priority: ${task.priority}`);
|
||||||
|
console.log(` Status: ${task.status}`);
|
||||||
|
console.log(` Order: ${task.order}`);
|
||||||
|
console.log(` Created: ${task.createdAt}`);
|
||||||
|
console.log(` Updated: ${task.updatedAt}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to get task:', (error as Error).message);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// cw task status <taskId> <status>
|
||||||
|
taskCommand
|
||||||
|
.command('status <taskId> <status>')
|
||||||
|
.description('Update task status (pending, in_progress, completed, blocked)')
|
||||||
|
.action(async (taskId: string, status: string) => {
|
||||||
|
const validStatuses = ['pending', 'in_progress', 'completed', 'blocked'];
|
||||||
|
if (!validStatuses.includes(status)) {
|
||||||
|
console.error(`Invalid status: ${status}`);
|
||||||
|
console.error(`Valid statuses: ${validStatuses.join(', ')}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const client = createDefaultTrpcClient();
|
||||||
|
const task = await client.updateTaskStatus.mutate({
|
||||||
|
id: taskId,
|
||||||
|
status: status as 'pending' | 'in_progress' | 'completed' | 'blocked',
|
||||||
|
});
|
||||||
|
console.log(`Task '${task.name}' status updated to: ${task.status}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to update task status:', (error as Error).message);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return program;
|
return program;
|
||||||
|
|||||||
Reference in New Issue
Block a user