@tosin2013/mcp-shrimp-task-manager
Version:
Enhanced MCP Shrimp Task Manager with comprehensive LLM integration. A task management tool built for AI Agents, emphasizing chain-of-thought, reflection, and style consistency. Features real GPT-4 ↔ MCP tools communication, comprehensive testing pipeline
268 lines • 10.2 kB
JavaScript
/**
* Task Memory Connector for the Idea Honing Tool
*
* This component integrates with the task memory system to store specifications,
* create tasks, track task status, and query task memory.
*/
import fsPromises from 'fs/promises';
import path from 'path';
import { fileURLToPath } from 'url';
// Get the base directory for task memory
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const PROJECT_ROOT = path.resolve(__dirname, '../../../..');
const DATA_DIR = process.env.DATA_DIR || path.join(PROJECT_ROOT, 'data');
const TASK_MEMORY_DIR = path.join(DATA_DIR, 'task-memory');
/**
* Stores a specification in task memory
*
* @param specification - Specification document to store
* @returns Promise that resolves with the stored specification ID
*/
export async function storeSpecificationInTaskMemory(specification) {
try {
// Ensure the task memory directory exists
await ensureTaskMemoryDirectory();
// Create the specifications directory if it doesn't exist
const specificationsDir = path.join(TASK_MEMORY_DIR, 'specifications');
await fsPromises.mkdir(specificationsDir, { recursive: true });
// Create a task memory representation of the specification
const taskMemorySpec = {
id: specification.id,
title: specification.title,
sections: specification.sections.map(section => ({
id: section.id,
title: section.title,
content: section.content
})),
metadata: specification.metadata,
version: specification.version,
createdAt: specification.createdAt.toISOString(),
updatedAt: specification.updatedAt.toISOString(),
tasks: [] // Will be populated as tasks are created
};
// Save the specification to task memory
const specPath = path.join(specificationsDir, `${specification.id}.json`);
await fsPromises.writeFile(specPath, JSON.stringify(taskMemorySpec, null, 2), 'utf-8');
return specification.id;
}
catch (error) {
throw new Error(`Failed to store specification in task memory: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Creates a task from a specification
*
* @param specificationId - Specification identifier
* @param options - Task creation options
* @returns Promise that resolves with the created task ID
*/
export async function createTaskFromSpecification(specificationId, options) {
try {
// Ensure the task memory directory exists
await ensureTaskMemoryDirectory();
// Create the tasks directory if it doesn't exist
const tasksDir = path.join(TASK_MEMORY_DIR, 'tasks');
await fsPromises.mkdir(tasksDir, { recursive: true });
// Generate a task ID
const taskId = `task_${Date.now()}_${Math.floor(Math.random() * 1000)}`;
// Create the task
const task = {
id: taskId,
title: options.title,
description: options.description,
status: 'pending',
dependencies: options.dependencies || [],
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
specificationId,
metadata: options.metadata || {}
};
// Save the task to task memory
const taskPath = path.join(tasksDir, `${taskId}.json`);
await fsPromises.writeFile(taskPath, JSON.stringify(task, null, 2), 'utf-8');
// Update the specification with the task ID
await addTaskToSpecification(specificationId, taskId);
return taskId;
}
catch (error) {
throw new Error(`Failed to create task from specification: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Updates a task's status
*
* @param taskId - Task identifier
* @param status - New task status
* @returns Promise that resolves when the task is updated
*/
export async function updateTaskStatus(taskId, status) {
try {
// Get the task
const task = await getTask(taskId);
// Update the task status
task.status = status;
task.updatedAt = new Date().toISOString();
// Save the updated task
const taskPath = path.join(TASK_MEMORY_DIR, 'tasks', `${taskId}.json`);
await fsPromises.writeFile(taskPath, JSON.stringify(task, null, 2), 'utf-8');
}
catch (error) {
throw new Error(`Failed to update task status: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Gets tasks for a specification
*
* @param specificationId - Specification identifier
* @returns Promise that resolves with an array of tasks
*/
export async function getTasksForSpecification(specificationId) {
try {
// Get the specification
const specPath = path.join(TASK_MEMORY_DIR, 'specifications', `${specificationId}.json`);
try {
await fsPromises.access(specPath);
}
catch {
throw new Error(`Specification not found: ${specificationId}`);
}
const specContent = await fsPromises.readFile(specPath, 'utf-8');
const spec = JSON.parse(specContent);
// Get the tasks
const tasks = [];
for (const taskId of spec.tasks) {
try {
const task = await getTask(taskId);
tasks.push(task);
}
catch (error) {
console.error(`Error getting task ${taskId}: ${error}`);
}
}
return tasks;
}
catch (error) {
throw new Error(`Failed to get tasks for specification: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Gets a task by ID
*
* @param taskId - Task identifier
* @returns Promise that resolves with the task
*/
export async function getTask(taskId) {
try {
const taskPath = path.join(TASK_MEMORY_DIR, 'tasks', `${taskId}.json`);
try {
await fsPromises.access(taskPath);
}
catch {
throw new Error(`Task not found: ${taskId}`);
}
const taskContent = await fsPromises.readFile(taskPath, 'utf-8');
return JSON.parse(taskContent);
}
catch (error) {
throw new Error(`Failed to get task: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Queries task memory for tasks matching criteria
*
* @param criteria - Query criteria
* @returns Promise that resolves with an array of matching tasks
*/
export async function queryTaskMemory(criteria) {
try {
// Ensure the task memory directory exists
await ensureTaskMemoryDirectory();
// Create the tasks directory if it doesn't exist
const tasksDir = path.join(TASK_MEMORY_DIR, 'tasks');
await fsPromises.mkdir(tasksDir, { recursive: true });
// Get all task files
const taskFiles = await fsPromises.readdir(tasksDir);
// Filter task files to only include .json files
const jsonTaskFiles = taskFiles.filter(file => file.endsWith('.json'));
// Read and filter tasks
const tasks = [];
for (const file of jsonTaskFiles) {
try {
const taskPath = path.join(tasksDir, file);
const taskContent = await fsPromises.readFile(taskPath, 'utf-8');
const task = JSON.parse(taskContent);
// Check if the task matches the criteria
let matches = true;
if (criteria.status && task.status !== criteria.status) {
matches = false;
}
if (criteria.specificationId && task.specificationId !== criteria.specificationId) {
matches = false;
}
if (criteria.title && !task.title.toLowerCase().includes(criteria.title.toLowerCase())) {
matches = false;
}
if (criteria.description && !task.description.toLowerCase().includes(criteria.description.toLowerCase())) {
matches = false;
}
if (matches) {
tasks.push(task);
}
}
catch (error) {
console.error(`Error reading task file ${file}: ${error}`);
}
}
return tasks;
}
catch (error) {
throw new Error(`Failed to query task memory: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Ensures the task memory directory exists
*
* @returns Promise that resolves when the directory exists
*/
async function ensureTaskMemoryDirectory() {
try {
await fsPromises.mkdir(TASK_MEMORY_DIR, { recursive: true });
}
catch (error) {
throw new Error(`Failed to create task memory directory: ${error instanceof Error ? error.message : String(error)}`);
}
}
/**
* Adds a task to a specification
*
* @param specificationId - Specification identifier
* @param taskId - Task identifier
* @returns Promise that resolves when the task is added
*/
async function addTaskToSpecification(specificationId, taskId) {
try {
const specPath = path.join(TASK_MEMORY_DIR, 'specifications', `${specificationId}.json`);
try {
await fsPromises.access(specPath);
}
catch {
throw new Error(`Specification not found: ${specificationId}`);
}
const specContent = await fsPromises.readFile(specPath, 'utf-8');
const spec = JSON.parse(specContent);
// Add the task ID to the specification
if (!spec.tasks) {
spec.tasks = [];
}
if (!spec.tasks.includes(taskId)) {
spec.tasks.push(taskId);
}
// Save the updated specification
await fsPromises.writeFile(specPath, JSON.stringify(spec, null, 2), 'utf-8');
}
catch (error) {
throw new Error(`Failed to add task to specification: ${error instanceof Error ? error.message : String(error)}`);
}
}
//# sourceMappingURL=task-memory-connector.js.map