@agent-plan/mcp 0.2.19-next.3 → 0.2.19-next.5
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.d.ts.map +1 -1
- package/dist/index.js +28 -52
- package/package.json +3 -3
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAw4BA,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAItD"}
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
4
4
|
import * as z from "zod/v4";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
import { pathToFileURL } from "node:url";
|
|
7
|
-
import { PlanStore, ExportService, withFeatureLock, needsMotivation, findPhaseByRef, buildRecap } from "@agent-plan/core";
|
|
7
|
+
import { PlanStore, ExportService, withFeatureLock, needsMotivation, findPhaseByRef, findTaskByRef, buildRecap, migrateToGlobalSequence } from "@agent-plan/core";
|
|
8
8
|
import { serve } from "@agent-plan/server";
|
|
9
9
|
import { createChecklistItemId, createFeatureId, createPhaseId, createShortId, createTaskId, clampSlug, normalizeSlug, formatPhaseRef, formatFeatureRef } from "@agent-plan/core/naming";
|
|
10
10
|
const STATUS_VALUES = ["planned", "in-progress", "done", "blocked", "canceled", "rejected", "deferred", "waiting"];
|
|
@@ -31,6 +31,7 @@ async function requireStore() {
|
|
|
31
31
|
if (!planBackfillDone) {
|
|
32
32
|
planBackfillDone = true;
|
|
33
33
|
await st.ensureShortIdsAndPriority().catch(() => { });
|
|
34
|
+
await migrateToGlobalSequence(st).catch(() => { });
|
|
34
35
|
}
|
|
35
36
|
return st;
|
|
36
37
|
}
|
|
@@ -61,34 +62,6 @@ function findFeatureByRef(features, ref) {
|
|
|
61
62
|
?? features.find((feature) => feature.name.toLowerCase() === normalized)
|
|
62
63
|
?? features.find((feature) => feature.name.toLowerCase().includes(normalized));
|
|
63
64
|
}
|
|
64
|
-
function findTaskByRef(phases, ref) {
|
|
65
|
-
const normalized = ref.trim().toLowerCase();
|
|
66
|
-
if (!normalized)
|
|
67
|
-
return undefined;
|
|
68
|
-
// Composite ref like "P00x(F00x)/T00x" or "T00x(P00x/F00x)": match by phase + task number.
|
|
69
|
-
const tMatch = normalized.match(/t0*(\d+)/);
|
|
70
|
-
const pMatch = normalized.match(/p0*(\d+)/);
|
|
71
|
-
if (tMatch && pMatch) {
|
|
72
|
-
const tNum = parseInt(tMatch[1], 10);
|
|
73
|
-
const pNum = parseInt(pMatch[1], 10);
|
|
74
|
-
for (const phase of phases) {
|
|
75
|
-
if (phase.number !== pNum)
|
|
76
|
-
continue;
|
|
77
|
-
const task = phase.tasks.find((t) => t.number === tNum);
|
|
78
|
-
if (task)
|
|
79
|
-
return { phase, task };
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
for (const phase of phases) {
|
|
83
|
-
const task = phase.tasks.find((entry) => entry.id.toLowerCase() === normalized
|
|
84
|
-
|| (entry.shortId && entry.shortId.toLowerCase() === normalized)
|
|
85
|
-
|| entry.title.toLowerCase() === normalized
|
|
86
|
-
|| entry.title.toLowerCase().includes(normalized));
|
|
87
|
-
if (task)
|
|
88
|
-
return { phase, task };
|
|
89
|
-
}
|
|
90
|
-
return undefined;
|
|
91
|
-
}
|
|
92
65
|
function featureNumberOfPhase(phase, features) {
|
|
93
66
|
return phase.featureId ? features.find((f) => f.id === phase.featureId)?.number : undefined;
|
|
94
67
|
}
|
|
@@ -289,7 +262,7 @@ server.registerTool("planner-feature-add", {
|
|
|
289
262
|
const priority = await st.nextPriority("feature");
|
|
290
263
|
const feature = {
|
|
291
264
|
id: createFeatureId(),
|
|
292
|
-
number:
|
|
265
|
+
number: await st.allocFeatureNumber(),
|
|
293
266
|
shortId,
|
|
294
267
|
priority,
|
|
295
268
|
name: name.trim(),
|
|
@@ -316,7 +289,7 @@ server.registerTool("planner-feature-add", {
|
|
|
316
289
|
});
|
|
317
290
|
server.registerTool("planner-feature-show", {
|
|
318
291
|
description: "Show a feature by id or name.",
|
|
319
|
-
inputSchema: { feature: z.string().min(1).describe("Feature
|
|
292
|
+
inputSchema: { feature: z.string().min(1).describe("Feature ref. Accepts F00x/P00x/T00x composite, bare P00x/T00x (global), 5-char shortId, UUID, or title.") },
|
|
320
293
|
}, async ({ feature: ref }) => {
|
|
321
294
|
const st = await requireStore();
|
|
322
295
|
const features = (await st.loadFeatures()).features;
|
|
@@ -324,12 +297,12 @@ server.registerTool("planner-feature-show", {
|
|
|
324
297
|
if (!feature)
|
|
325
298
|
return text(`Feature not found: ${ref}`);
|
|
326
299
|
const phases = (await st.loadAllPhases()).filter((phase) => phase.featureId === feature.id);
|
|
327
|
-
return text(`${feature.name} (${feature.
|
|
300
|
+
return text(`${feature.name} — ${formatFeatureRef(feature.number)}${feature.shortId ? ` · ${feature.shortId}` : ""} (${feature.status}; ${phases.length} phases)`, { feature, phases });
|
|
328
301
|
});
|
|
329
302
|
server.registerTool("planner-feature-update", {
|
|
330
303
|
description: "Update a feature.",
|
|
331
304
|
inputSchema: {
|
|
332
|
-
feature: z.string().min(1).describe("Feature
|
|
305
|
+
feature: z.string().min(1).describe("Feature ref. Accepts F00x/P00x/T00x composite, bare P00x/T00x (global), 5-char shortId, UUID, or title."),
|
|
333
306
|
name: z.string().optional(),
|
|
334
307
|
description: z.string().optional(),
|
|
335
308
|
status: z.enum(STATUS_VALUES).optional(),
|
|
@@ -374,7 +347,7 @@ server.registerTool("planner-feature-update", {
|
|
|
374
347
|
server.registerTool("planner-feature-delete", {
|
|
375
348
|
description: "Delete a feature. By default, phases are unlinked rather than deleted.",
|
|
376
349
|
inputSchema: {
|
|
377
|
-
feature: z.string().min(1).describe("Feature
|
|
350
|
+
feature: z.string().min(1).describe("Feature ref. Accepts F00x/P00x/T00x composite, bare P00x/T00x (global), 5-char shortId, UUID, or title."),
|
|
378
351
|
cascade: z.boolean().optional().describe("Also delete phases belonging to this feature"),
|
|
379
352
|
},
|
|
380
353
|
}, async ({ feature: ref, cascade }) => {
|
|
@@ -404,7 +377,7 @@ server.registerTool("planner-phase-add", {
|
|
|
404
377
|
description: "Create a phase with a rich description. REQUIRED: description must include code references (file:line), current implementation state, dependencies, specific files/systems to modify, and behaviors to preserve. The description is the primary context for future agents; one-liners cause misalignment.",
|
|
405
378
|
inputSchema: {
|
|
406
379
|
title: z.string().min(1),
|
|
407
|
-
feature: z.string().optional().describe("Feature
|
|
380
|
+
feature: z.string().optional().describe("Feature ref. Accepts F00x/P00x/T00x composite, bare P00x/T00x (global), 5-char shortId, UUID, or title."),
|
|
408
381
|
summary: z.string().optional().describe("One-line summary of the phase"),
|
|
409
382
|
description: z.string().min(50, "Description must be at least 50 characters — include code references (file:line), current state, structs/traits involved, concrete work items, behaviors to preserve. Prefix with 'design-only' for pre-implementation design tasks.").describe("Required code references (file:line), current state, structs/traits involved, concrete work items, behaviors to preserve. Not a one-liner."),
|
|
410
383
|
},
|
|
@@ -424,7 +397,7 @@ server.registerTool("planner-phase-add", {
|
|
|
424
397
|
const priority = await st.nextPriority("phase", feature?.id);
|
|
425
398
|
phase = {
|
|
426
399
|
id: createPhaseId(),
|
|
427
|
-
number:
|
|
400
|
+
number: await st.allocPhaseNumber(),
|
|
428
401
|
shortId,
|
|
429
402
|
priority,
|
|
430
403
|
slug: normalizeSlug(title),
|
|
@@ -472,18 +445,19 @@ server.registerTool("planner-phase-add", {
|
|
|
472
445
|
});
|
|
473
446
|
server.registerTool("planner-phase-show", {
|
|
474
447
|
description: "Show a phase by id or name.",
|
|
475
|
-
inputSchema: { phase: z.string().min(1).describe("Phase
|
|
448
|
+
inputSchema: { phase: z.string().min(1).describe("Phase ref. Accepts F00x/P00x/T00x composite, bare P00x/T00x (global), 5-char shortId, UUID, or title.") },
|
|
476
449
|
}, async ({ phase: ref }) => {
|
|
477
450
|
const st = await requireStore();
|
|
478
|
-
const
|
|
451
|
+
const features = (await st.loadFeatures()).features;
|
|
452
|
+
const phase = findPhaseByRef(await st.loadAllPhases(), features, ref);
|
|
479
453
|
if (!phase)
|
|
480
454
|
return text(`Phase not found: ${ref}`);
|
|
481
|
-
return text(`${phase.title} (${phase.
|
|
455
|
+
return text(`${phase.title} — ${formatPhaseRef(phase.number, featureNumberOfPhase(phase, features))}${phase.shortId ? ` · ${phase.shortId}` : ""} (${phase.status}; ${phase.tasks.length} tasks)`, { phase });
|
|
482
456
|
});
|
|
483
457
|
server.registerTool("planner-phase-discuss", {
|
|
484
458
|
description: "Persist phase discovery fields and mark phase planned.",
|
|
485
459
|
inputSchema: {
|
|
486
|
-
phase: z.string().min(1).describe("Phase
|
|
460
|
+
phase: z.string().min(1).describe("Phase ref. Accepts F00x/P00x/T00x composite, bare P00x/T00x (global), 5-char shortId, UUID, or title."),
|
|
487
461
|
goal: z.string().optional(),
|
|
488
462
|
summary: z.string().optional(),
|
|
489
463
|
scope: z.string().optional(),
|
|
@@ -568,12 +542,13 @@ server.registerTool("planner-phase-delete", {
|
|
|
568
542
|
feature.phaseIds = feature.phaseIds.filter((id) => id !== phase.id);
|
|
569
543
|
return doc;
|
|
570
544
|
});
|
|
571
|
-
|
|
545
|
+
const dFeat = (await st.loadFeatures()).features.find((f) => f.id === phase.featureId);
|
|
546
|
+
return writeAndSummarize(st, `Phase deleted: ${formatPhaseRef(phase.number, dFeat?.number)}${phase.shortId ? ` · ${phase.shortId}` : ""}`, { deleted: phase.id });
|
|
572
547
|
});
|
|
573
548
|
server.registerTool("planner-task-add", {
|
|
574
549
|
description: "Create a task with a rich description. REQUIRED: description must include code references (file:line), what already exists vs what needs to be built, specific structs/traits/systems to modify, concrete implementation steps, and edge cases to handle. The description is the execution context for agents; one-liners cause misalignment.",
|
|
575
550
|
inputSchema: {
|
|
576
|
-
phase: z.string().min(1).describe("Phase
|
|
551
|
+
phase: z.string().min(1).describe("Phase ref. Accepts F00x/P00x/T00x composite, bare P00x/T00x (global), 5-char shortId, UUID, or title."),
|
|
577
552
|
title: z.string().min(1),
|
|
578
553
|
description: z.string().min(50, "Description must be at least 50 characters — include code references (file:line), current state vs desired state, structs/traits to modify, concrete implementation steps, edge cases. Prefix with 'design-only' for pre-implementation design tasks.").describe("Required code references (file:line), current state vs desired state, structs/traits to modify, concrete implementation steps, edge cases. Not a one-liner."),
|
|
579
554
|
checklist: z.array(z.string()).optional(),
|
|
@@ -590,7 +565,7 @@ server.registerTool("planner-task-add", {
|
|
|
590
565
|
const task = {
|
|
591
566
|
id: taskId,
|
|
592
567
|
phaseId: found.id,
|
|
593
|
-
number:
|
|
568
|
+
number: await st.allocTaskNumber(),
|
|
594
569
|
shortId,
|
|
595
570
|
priority,
|
|
596
571
|
shortName: clampSlug(title, 30, `task-${Date.now().toString(36)}`),
|
|
@@ -620,13 +595,13 @@ server.registerTool("planner-task-add", {
|
|
|
620
595
|
});
|
|
621
596
|
server.registerTool("planner-task-show", {
|
|
622
597
|
description: "Show a task by id or name.",
|
|
623
|
-
inputSchema: { task: z.string().min(1).describe("Task
|
|
598
|
+
inputSchema: { task: z.string().min(1).describe("Task ref. Accepts F00x/P00x/T00x composite, bare P00x/T00x (global), 5-char shortId, UUID, or title.") },
|
|
624
599
|
}, async ({ task: ref }) => {
|
|
625
600
|
const st = await requireStore();
|
|
626
|
-
const found = findTaskByRef(await st.loadAllPhases(), ref);
|
|
601
|
+
const found = findTaskByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
627
602
|
if (!found)
|
|
628
603
|
return text(`Task not found: ${ref}`);
|
|
629
|
-
return text(`${found.task.title} (${found.task.
|
|
604
|
+
return text(`${found.task.title} — ${taskCompositeRef(found.task, found.phase, (await st.loadFeatures()).features)}${found.task.shortId ? ` · ${found.task.shortId}` : ""} (${found.task.status}; phase ${formatPhaseRef(found.phase.number, featureNumberOfPhase(found.phase, (await st.loadFeatures()).features))})`, { task: found.task, phase: found.phase });
|
|
630
605
|
});
|
|
631
606
|
server.registerTool("planner-task-discuss", {
|
|
632
607
|
description: "Persist task execution notes/checklist.",
|
|
@@ -637,7 +612,7 @@ server.registerTool("planner-task-discuss", {
|
|
|
637
612
|
},
|
|
638
613
|
}, async ({ task: ref, description, checklist }) => {
|
|
639
614
|
const st = await requireStore();
|
|
640
|
-
const found = findTaskByRef(await st.loadAllPhases(), ref);
|
|
615
|
+
const found = findTaskByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
641
616
|
if (!found)
|
|
642
617
|
return text(`Task not found: ${ref}`);
|
|
643
618
|
let updatedTask;
|
|
@@ -670,7 +645,7 @@ server.registerTool("planner-task-update", {
|
|
|
670
645
|
},
|
|
671
646
|
}, async ({ task: ref, title, status, description, motivation, priority }) => {
|
|
672
647
|
const st = await requireStore();
|
|
673
|
-
const found = findTaskByRef(await st.loadAllPhases(), ref);
|
|
648
|
+
const found = findTaskByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
674
649
|
if (!found)
|
|
675
650
|
return text(`Task not found: ${ref}`);
|
|
676
651
|
// Validate motivation requirement for status transitions.
|
|
@@ -720,7 +695,7 @@ server.registerTool("planner-task-delete", {
|
|
|
720
695
|
inputSchema: { task: z.string().min(1) },
|
|
721
696
|
}, async ({ task: ref }) => {
|
|
722
697
|
const st = await requireStore();
|
|
723
|
-
const found = findTaskByRef(await st.loadAllPhases(), ref);
|
|
698
|
+
const found = findTaskByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
724
699
|
if (!found)
|
|
725
700
|
return text(`Task not found: ${ref}`);
|
|
726
701
|
await st.updatePhase(found.phase.id, (phase) => {
|
|
@@ -730,14 +705,15 @@ server.registerTool("planner-task-delete", {
|
|
|
730
705
|
return phase;
|
|
731
706
|
});
|
|
732
707
|
await st.syncTaskStatusRollup(found.phase.id);
|
|
733
|
-
|
|
708
|
+
const tdFeatures = (await st.loadFeatures()).features;
|
|
709
|
+
return writeAndSummarize(st, `Task deleted: ${taskCompositeRef(found.task, found.phase, tdFeatures)}${found.task.shortId ? ` · ${found.task.shortId}` : ""}`, { deleted: found.task.id });
|
|
734
710
|
});
|
|
735
711
|
server.registerTool("planner-task-start", {
|
|
736
712
|
description: "Set a task to in-progress.",
|
|
737
713
|
inputSchema: { task: z.string().min(1) },
|
|
738
714
|
}, async ({ task: ref }) => {
|
|
739
715
|
const st = await requireStore();
|
|
740
|
-
const found = findTaskByRef(await st.loadAllPhases(), ref);
|
|
716
|
+
const found = findTaskByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
741
717
|
if (!found)
|
|
742
718
|
return text(`Task not found: ${ref}`);
|
|
743
719
|
// Auto-archive the handoff on THIS task's phase (reason: task-started) — the
|
|
@@ -790,7 +766,7 @@ server.registerTool("planner-task-complete", {
|
|
|
790
766
|
},
|
|
791
767
|
}, async ({ task: ref, force, description_update }) => {
|
|
792
768
|
const st = await requireStore();
|
|
793
|
-
const found = findTaskByRef(await st.loadAllPhases(), ref);
|
|
769
|
+
const found = findTaskByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
794
770
|
if (!found)
|
|
795
771
|
return text(`Task not found: ${ref}`);
|
|
796
772
|
const unchecked = found.task.checklist.filter((item) => !item.checked);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-plan/mcp",
|
|
3
|
-
"version": "0.2.19-next.
|
|
3
|
+
"version": "0.2.19-next.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "MCP server for Agent Plan, exposing planner-* tools over stdio.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@modelcontextprotocol/sdk": "^1.17.0",
|
|
43
43
|
"zod": "^3.24.0",
|
|
44
|
-
"@agent-plan/core": "0.2.19-next.
|
|
45
|
-
"@agent-plan/server": "0.2.19-next.
|
|
44
|
+
"@agent-plan/core": "0.2.19-next.5",
|
|
45
|
+
"@agent-plan/server": "0.2.19-next.5"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"build": "tsc -p tsconfig.json",
|