@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.
Files changed (2) hide show
  1. package/dist/index.js +57 -4
  2. 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, path, options) {
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}${path}`;
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 path = `/notifications${query ? "?" + query : ""}`;
497
- return this.request("GET", path);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@planflow-tools/mcp",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "PlanFlow MCP Server for Claude Code - AI-native project management from your terminal",
5
5
  "author": "PlanFlow <hello@planflow.tools>",
6
6
  "license": "MIT",