@planflow-tools/mcp 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +57 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -266,12 +266,12 @@ var ApiClient = class {
|
|
|
266
266
|
/**
|
|
267
267
|
* Make an authenticated HTTP request with retry logic
|
|
268
268
|
*/
|
|
269
|
-
async request(method,
|
|
269
|
+
async request(method, path2, options) {
|
|
270
270
|
const { body, requireAuth = true, retries = MAX_RETRIES } = options ?? {};
|
|
271
271
|
if (requireAuth && !this.token) {
|
|
272
272
|
throw new AuthError("Not authenticated. Please run planflow_login first.");
|
|
273
273
|
}
|
|
274
|
-
const url = `${this.baseUrl}${
|
|
274
|
+
const url = `${this.baseUrl}${path2}`;
|
|
275
275
|
logger.debug("API request", { method, url });
|
|
276
276
|
let lastError = null;
|
|
277
277
|
for (let attempt = 1; attempt <= retries; attempt++) {
|
|
@@ -493,8 +493,8 @@ var ApiClient = class {
|
|
|
493
493
|
if (options?.unreadOnly) params.append("unreadOnly", "true");
|
|
494
494
|
if (options?.limit) params.append("limit", String(options.limit));
|
|
495
495
|
const query = params.toString();
|
|
496
|
-
const
|
|
497
|
-
return this.request("GET",
|
|
496
|
+
const path2 = `/notifications${query ? "?" + query : ""}`;
|
|
497
|
+
return this.request("GET", path2);
|
|
498
498
|
}
|
|
499
499
|
/**
|
|
500
500
|
* Mark a notification as read
|
|
@@ -1331,6 +1331,8 @@ Please try again or check your connection.`
|
|
|
1331
1331
|
|
|
1332
1332
|
// src/tools/task-update.ts
|
|
1333
1333
|
import { z as z9 } from "zod";
|
|
1334
|
+
import * as fs from "fs";
|
|
1335
|
+
import * as path from "path";
|
|
1334
1336
|
var TaskUpdateInputSchema = z9.object({
|
|
1335
1337
|
projectId: z9.string().uuid("Project ID must be a valid UUID"),
|
|
1336
1338
|
taskId: z9.string().describe('Task ID (e.g., "T1.1", "T2.3")'),
|
|
@@ -1362,6 +1364,54 @@ function getComplexityIndicator2(complexity) {
|
|
|
1362
1364
|
return "\u26AA";
|
|
1363
1365
|
}
|
|
1364
1366
|
}
|
|
1367
|
+
function updateLocalPlanFile(taskId, status) {
|
|
1368
|
+
const planPath = path.join(process.cwd(), "PROJECT_PLAN.md");
|
|
1369
|
+
if (!fs.existsSync(planPath)) {
|
|
1370
|
+
logger.debug("No local PROJECT_PLAN.md found, skipping local update");
|
|
1371
|
+
return false;
|
|
1372
|
+
}
|
|
1373
|
+
try {
|
|
1374
|
+
let content = fs.readFileSync(planPath, "utf-8");
|
|
1375
|
+
const statusMap = {
|
|
1376
|
+
"TODO": { checkbox: "[ ]", label: "TODO" },
|
|
1377
|
+
"IN_PROGRESS": { checkbox: "[-]", label: "IN_PROGRESS \u{1F504}" },
|
|
1378
|
+
"DONE": { checkbox: "[x]", label: "DONE \u2705" },
|
|
1379
|
+
"BLOCKED": { checkbox: "[!]", label: "BLOCKED \u{1F6AB}" }
|
|
1380
|
+
};
|
|
1381
|
+
const newStatus = statusMap[status] || statusMap["TODO"];
|
|
1382
|
+
const statusLinePattern = new RegExp(
|
|
1383
|
+
`(####\\s*\\*\\*${taskId}\\*\\*[\\s\\S]*?-\\s*)\\[[x\\s\\-!]\\](\\s*\\*\\*\u10E1\u10E2\u10D0\u10E2\u10E3\u10E1\u10D8\\*\\*:\\s*)\\S+.*`,
|
|
1384
|
+
"i"
|
|
1385
|
+
);
|
|
1386
|
+
if (statusLinePattern.test(content)) {
|
|
1387
|
+
content = content.replace(
|
|
1388
|
+
statusLinePattern,
|
|
1389
|
+
`$1${newStatus.checkbox}$2${newStatus.label}`
|
|
1390
|
+
);
|
|
1391
|
+
fs.writeFileSync(planPath, content, "utf-8");
|
|
1392
|
+
logger.info("Updated local PROJECT_PLAN.md", { taskId, status });
|
|
1393
|
+
return true;
|
|
1394
|
+
}
|
|
1395
|
+
const statusLinePatternEn = new RegExp(
|
|
1396
|
+
`(####\\s*\\*\\*${taskId}\\*\\*[\\s\\S]*?-\\s*)\\[[x\\s\\-!]\\](\\s*\\*\\*Status\\*\\*:\\s*)\\S+.*`,
|
|
1397
|
+
"i"
|
|
1398
|
+
);
|
|
1399
|
+
if (statusLinePatternEn.test(content)) {
|
|
1400
|
+
content = content.replace(
|
|
1401
|
+
statusLinePatternEn,
|
|
1402
|
+
`$1${newStatus.checkbox}$2${newStatus.label}`
|
|
1403
|
+
);
|
|
1404
|
+
fs.writeFileSync(planPath, content, "utf-8");
|
|
1405
|
+
logger.info("Updated local PROJECT_PLAN.md (EN)", { taskId, status });
|
|
1406
|
+
return true;
|
|
1407
|
+
}
|
|
1408
|
+
logger.debug("Task pattern not found in PROJECT_PLAN.md", { taskId });
|
|
1409
|
+
return false;
|
|
1410
|
+
} catch (error) {
|
|
1411
|
+
logger.error("Failed to update local PROJECT_PLAN.md", { error: String(error) });
|
|
1412
|
+
return false;
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1365
1415
|
var taskUpdateTool = {
|
|
1366
1416
|
name: "planflow_task_update",
|
|
1367
1417
|
description: `Update task status in a PlanFlow project.
|
|
@@ -1416,6 +1466,7 @@ Use planflow_task_list() to see available tasks.`
|
|
|
1416
1466
|
taskId: input.taskId,
|
|
1417
1467
|
newStatus: input.status
|
|
1418
1468
|
});
|
|
1469
|
+
const localUpdated = updateLocalPlanFile(input.taskId, input.status);
|
|
1419
1470
|
const statusEmoji = getStatusEmoji2(updatedTask.status);
|
|
1420
1471
|
const complexityIndicator = getComplexityIndicator2(updatedTask.complexity);
|
|
1421
1472
|
const taskDetails = formatKeyValue({
|
|
@@ -1461,10 +1512,12 @@ Use planflow_task_list() to see available tasks.`
|
|
|
1461
1512
|
` \u2022 View all tasks: planflow_task_list(projectId: "${input.projectId}")`
|
|
1462
1513
|
].join("\n");
|
|
1463
1514
|
}
|
|
1515
|
+
const localSyncInfo = localUpdated ? "\n\u{1F4C1} Local PROJECT_PLAN.md also updated" : "";
|
|
1464
1516
|
const output = [
|
|
1465
1517
|
`${statusEmoji} Task ${input.taskId} updated to ${input.status}!
|
|
1466
1518
|
`,
|
|
1467
1519
|
taskDetails,
|
|
1520
|
+
localSyncInfo,
|
|
1468
1521
|
nextSteps
|
|
1469
1522
|
].join("\n");
|
|
1470
1523
|
return createSuccessResult(output);
|
package/package.json
CHANGED