mcp-ai-agent-guidelines
Version:
A comprehensive Model Context Protocol server providing advanced tools, resources, and prompts for implementing AI agent best practices
119 lines • 3.91 kB
JavaScript
/**
* Update Progress Tool
*
* Updates spec progress.md with completed tasks and recalculates metrics.
* Provides direct MCP access to the ProgressTracker for AI agents.
*
* @module tools/update-progress
*/
import { promises as fs } from "node:fs";
import { createProgressTracker, parseTasksFromMarkdown, } from "../strategies/speckit/index.js";
import { createMcpResponse } from "./shared/response-utils.js";
/**
* Update progress.md with completed tasks and recalculate metrics
*
* @param request - Update progress request with task IDs and options
* @returns MCP response with updated progress.md content
* @throws {Error} If task file cannot be read
* @throws {Error} If progress file cannot be read
*
* @example
* ```typescript
* // Mark tasks complete
* const result = await updateProgress({
* progressPath: "./progress.md",
* completedTaskIds: ["P4-001", "P4-002"],
* outputFormat: "markdown"
* });
* ```
*
* @example
* ```typescript
* // With git sync
* const result = await updateProgress({
* progressPath: "./progress.md",
* syncFromGit: true,
* gitOptions: { since: "2026-01-01" }
* });
* ```
*/
export async function updateProgress(request) {
// Load tasks if available
let tasks;
if (request.tasksPath) {
try {
const tasksContent = await fs.readFile(request.tasksPath, "utf-8");
tasks = parseTasksFromMarkdown(tasksContent);
}
catch (error) {
throw new Error(`Failed to read tasks file: ${error instanceof Error ? error.message : String(error)}`);
}
}
// Create tracker
const tracker = createProgressTracker(tasks);
// Load existing progress if available
if (request.progressContent) {
tracker.loadProgress(request.progressContent);
}
else if (request.progressPath) {
try {
await tracker.loadProgressFromFile(request.progressPath);
}
catch (error) {
// If file doesn't exist, that's okay - we'll create new progress
// Only throw if it's a real read error (file exists but can't read)
if (error instanceof Error &&
!error.message.includes("ENOENT") &&
!error.message.includes("no such file")) {
throw new Error(`Failed to read progress file: ${error.message}`);
}
}
}
// Apply simple completions
if (request.completedTaskIds && request.completedTaskIds.length > 0) {
for (const taskId of request.completedTaskIds) {
const update = {
taskId,
status: "completed",
timestamp: new Date().toISOString(),
};
tracker.updateProgress(update);
}
}
// Apply detailed updates
if (request.taskUpdates && request.taskUpdates.length > 0) {
tracker.updateMultiple(request.taskUpdates.map((u) => ({
taskId: u.taskId,
status: u.status,
notes: u.notes,
timestamp: new Date().toISOString(),
})));
}
// Sync from git if requested
let gitUpdates = [];
if (request.syncFromGit) {
gitUpdates = tracker.syncFromGit(request.gitOptions ?? {});
}
// Calculate metrics
const metrics = tracker.calculateCompletion();
// Generate output
let output;
if (request.outputFormat === "json") {
output = JSON.stringify({
metrics,
gitUpdates: gitUpdates.length > 0 ? gitUpdates : undefined,
progressMarkdown: tracker.generateProgressMarkdown(),
}, null, 2);
}
else {
output = tracker.generateProgressMarkdown();
}
return createMcpResponse({
content: output,
metadata: {
...metrics,
gitUpdatesApplied: gitUpdates.length,
},
});
}
//# sourceMappingURL=update-progress.js.map