claude-flow
Version:
Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration
302 lines • 10.7 kB
JavaScript
/**
* Task MCP Tools for CLI
*
* Tool definitions for task management with file persistence.
*/
import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
import { join } from 'node:path';
// Storage paths
const STORAGE_DIR = '.claude-flow';
const TASK_DIR = 'tasks';
const TASK_FILE = 'store.json';
function getTaskDir() {
return join(process.cwd(), STORAGE_DIR, TASK_DIR);
}
function getTaskPath() {
return join(getTaskDir(), TASK_FILE);
}
function ensureTaskDir() {
const dir = getTaskDir();
if (!existsSync(dir)) {
mkdirSync(dir, { recursive: true });
}
}
function loadTaskStore() {
try {
const path = getTaskPath();
if (existsSync(path)) {
const data = readFileSync(path, 'utf-8');
return JSON.parse(data);
}
}
catch {
// Return empty store on error
}
return { tasks: {}, version: '3.0.0' };
}
function saveTaskStore(store) {
ensureTaskDir();
writeFileSync(getTaskPath(), JSON.stringify(store, null, 2), 'utf-8');
}
export const taskTools = [
{
name: 'task_create',
description: 'Create a new task',
category: 'task',
inputSchema: {
type: 'object',
properties: {
type: { type: 'string', description: 'Task type (feature, bugfix, research, refactor)' },
description: { type: 'string', description: 'Task description' },
priority: { type: 'string', description: 'Task priority (low, normal, high, critical)' },
assignTo: { type: 'array', items: { type: 'string' }, description: 'Agent IDs to assign' },
tags: { type: 'array', items: { type: 'string' }, description: 'Task tags' },
},
required: ['type', 'description'],
},
handler: async (input) => {
const store = loadTaskStore();
const taskId = `task-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
const task = {
taskId,
type: input.type,
description: input.description,
priority: input.priority || 'normal',
status: 'pending',
progress: 0,
assignedTo: input.assignTo || [],
tags: input.tags || [],
createdAt: new Date().toISOString(),
startedAt: null,
completedAt: null,
};
store.tasks[taskId] = task;
saveTaskStore(store);
return {
taskId,
type: task.type,
description: task.description,
priority: task.priority,
status: task.status,
createdAt: task.createdAt,
assignedTo: task.assignedTo,
tags: task.tags,
};
},
},
{
name: 'task_status',
description: 'Get task status',
category: 'task',
inputSchema: {
type: 'object',
properties: {
taskId: { type: 'string', description: 'Task ID' },
},
required: ['taskId'],
},
handler: async (input) => {
const store = loadTaskStore();
const taskId = input.taskId;
const task = store.tasks[taskId];
if (task) {
return {
taskId: task.taskId,
type: task.type,
description: task.description,
status: task.status,
progress: task.progress,
priority: task.priority,
assignedTo: task.assignedTo,
tags: task.tags,
createdAt: task.createdAt,
startedAt: task.startedAt,
completedAt: task.completedAt,
};
}
return {
taskId,
status: 'not_found',
error: 'Task not found',
};
},
},
{
name: 'task_list',
description: 'List all tasks',
category: 'task',
inputSchema: {
type: 'object',
properties: {
status: { type: 'string', description: 'Filter by status' },
type: { type: 'string', description: 'Filter by type' },
assignedTo: { type: 'string', description: 'Filter by assigned agent' },
priority: { type: 'string', description: 'Filter by priority' },
limit: { type: 'number', description: 'Max tasks to return' },
},
},
handler: async (input) => {
const store = loadTaskStore();
let tasks = Object.values(store.tasks);
// Apply filters
if (input.status) {
// Support comma-separated status values
const statuses = input.status.split(',').map(s => s.trim());
tasks = tasks.filter(t => statuses.includes(t.status));
}
if (input.type) {
tasks = tasks.filter(t => t.type === input.type);
}
if (input.assignedTo) {
tasks = tasks.filter(t => t.assignedTo.includes(input.assignedTo));
}
if (input.priority) {
tasks = tasks.filter(t => t.priority === input.priority);
}
// Sort by creation date (newest first)
tasks.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
// Apply limit
const limit = input.limit || 50;
tasks = tasks.slice(0, limit);
return {
tasks: tasks.map(t => ({
taskId: t.taskId,
type: t.type,
description: t.description,
status: t.status,
progress: t.progress,
priority: t.priority,
assignedTo: t.assignedTo,
createdAt: t.createdAt,
})),
total: tasks.length,
filters: {
status: input.status,
type: input.type,
assignedTo: input.assignedTo,
priority: input.priority,
},
};
},
},
{
name: 'task_complete',
description: 'Mark task as complete',
category: 'task',
inputSchema: {
type: 'object',
properties: {
taskId: { type: 'string', description: 'Task ID' },
result: { type: 'object', description: 'Task result data' },
},
required: ['taskId'],
},
handler: async (input) => {
const store = loadTaskStore();
const taskId = input.taskId;
const task = store.tasks[taskId];
if (task) {
task.status = 'completed';
task.progress = 100;
task.completedAt = new Date().toISOString();
task.result = input.result || {};
saveTaskStore(store);
return {
taskId: task.taskId,
status: task.status,
completedAt: task.completedAt,
result: task.result,
};
}
return {
taskId,
status: 'not_found',
error: 'Task not found',
};
},
},
{
name: 'task_update',
description: 'Update task status or progress',
category: 'task',
inputSchema: {
type: 'object',
properties: {
taskId: { type: 'string', description: 'Task ID' },
status: { type: 'string', description: 'New status' },
progress: { type: 'number', description: 'Progress percentage (0-100)' },
assignTo: { type: 'array', items: { type: 'string' }, description: 'Agent IDs to assign' },
},
required: ['taskId'],
},
handler: async (input) => {
const store = loadTaskStore();
const taskId = input.taskId;
const task = store.tasks[taskId];
if (task) {
if (input.status) {
const newStatus = input.status;
task.status = newStatus;
if (newStatus === 'in_progress' && !task.startedAt) {
task.startedAt = new Date().toISOString();
}
}
if (typeof input.progress === 'number') {
task.progress = Math.min(100, Math.max(0, input.progress));
}
if (input.assignTo) {
task.assignedTo = input.assignTo;
}
saveTaskStore(store);
return {
success: true,
taskId: task.taskId,
status: task.status,
progress: task.progress,
assignedTo: task.assignedTo,
};
}
return {
success: false,
taskId,
error: 'Task not found',
};
},
},
{
name: 'task_cancel',
description: 'Cancel a task',
category: 'task',
inputSchema: {
type: 'object',
properties: {
taskId: { type: 'string', description: 'Task ID' },
reason: { type: 'string', description: 'Cancellation reason' },
},
required: ['taskId'],
},
handler: async (input) => {
const store = loadTaskStore();
const taskId = input.taskId;
const task = store.tasks[taskId];
if (task) {
task.status = 'cancelled';
task.completedAt = new Date().toISOString();
task.result = { cancelReason: input.reason || 'Cancelled by user' };
saveTaskStore(store);
return {
success: true,
taskId: task.taskId,
status: task.status,
cancelledAt: task.completedAt,
};
}
return {
success: false,
taskId,
error: 'Task not found',
};
},
},
];
//# sourceMappingURL=task-tools.js.map