@agent-plan/mcp 0.2.19-next.4 → 0.2.19-next.6
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 +96 -60
- 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":";AAg8BA,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
|
}
|
|
@@ -261,17 +234,70 @@ server.registerTool("planner-project-discuss", {
|
|
|
261
234
|
return writeAndSummarize(st, `Project discussed/updated: ${project.name}`);
|
|
262
235
|
});
|
|
263
236
|
server.registerTool("planner-feature-list", {
|
|
264
|
-
description: "List features
|
|
265
|
-
|
|
237
|
+
description: "List features (compact: F00x · shortId — name (status; N phases, M tasks)). Pass featureRef to filter. Use this to discover refs cheaply — do NOT read .planner/ files or planner-plan-get full=true to find entities.",
|
|
238
|
+
inputSchema: { featureRef: z.string().optional().describe("Optional: filter to one feature (F00x/shortId/UUID/name).") },
|
|
239
|
+
}, async ({ featureRef }) => {
|
|
266
240
|
const st = await requireStore();
|
|
267
|
-
const
|
|
241
|
+
const allFeatures = (await st.loadFeatures()).features;
|
|
242
|
+
const features = featureRef ? allFeatures.filter((f) => f.id === findFeatureByRef(allFeatures, featureRef)?.id) : allFeatures;
|
|
268
243
|
const phases = await st.loadAllPhases();
|
|
269
244
|
const lines = features.map((feature) => {
|
|
270
245
|
const featurePhases = phases.filter((phase) => phase.featureId === feature.id);
|
|
271
246
|
const taskCount = featurePhases.reduce((total, phase) => total + phase.tasks.length, 0);
|
|
272
|
-
return `- ${feature.
|
|
247
|
+
return `- ${formatFeatureRef(feature.number)}${feature.shortId ? ` · ${feature.shortId}` : ""} — ${feature.name} (${feature.status}; ${featurePhases.length} phases, ${taskCount} tasks)`;
|
|
248
|
+
});
|
|
249
|
+
return text(lines.join("\n") || "No features");
|
|
250
|
+
});
|
|
251
|
+
server.registerTool("planner-phase-list", {
|
|
252
|
+
description: "List phases (compact: F00x/P00x · shortId — title (status; N tasks) [F00x]). Filters: featureRef, status. Cheap discovery — do NOT read .planner/ files or planner-plan-get full=true.",
|
|
253
|
+
inputSchema: { featureRef: z.string().optional().describe("Optional: filter to one feature (F00x/shortId/UUID/name)."), status: z.string().optional().describe("Optional: filter by status name.") },
|
|
254
|
+
}, async ({ featureRef, status }) => {
|
|
255
|
+
const st = await requireStore();
|
|
256
|
+
const features = (await st.loadFeatures()).features;
|
|
257
|
+
let phases = await st.loadAllPhases();
|
|
258
|
+
if (featureRef) {
|
|
259
|
+
const f = findFeatureByRef(features, featureRef);
|
|
260
|
+
if (!f)
|
|
261
|
+
return text(`Feature not found: ${featureRef}`);
|
|
262
|
+
phases = phases.filter((p) => p.featureId === f.id);
|
|
263
|
+
}
|
|
264
|
+
if (status)
|
|
265
|
+
phases = phases.filter((p) => p.status === status);
|
|
266
|
+
const lines = phases.map((phase) => {
|
|
267
|
+
const fNum = featureNumberOfPhase(phase, features);
|
|
268
|
+
const fTag = fNum !== undefined ? ` [F${String(fNum).padStart(3, "0")}]` : "";
|
|
269
|
+
return `- ${formatPhaseRef(phase.number, fNum)}${phase.shortId ? ` · ${phase.shortId}` : ""} — ${phase.title} (${phase.status}; ${phase.tasks.length} tasks)${fTag}`;
|
|
273
270
|
});
|
|
274
|
-
return text(lines.join("\n") || "No
|
|
271
|
+
return text(lines.join("\n") || "No phases");
|
|
272
|
+
});
|
|
273
|
+
server.registerTool("planner-task-list", {
|
|
274
|
+
description: "List tasks (compact: F00x/P00x/T00x · shortId — title (status)). Filters: featureRef, phaseRef, status. Cheap discovery — do NOT read .planner/ files or planner-plan-get full=true.",
|
|
275
|
+
inputSchema: { featureRef: z.string().optional(), phaseRef: z.string().optional(), status: z.string().optional().describe("Optional: filter by status name.") },
|
|
276
|
+
}, async ({ featureRef, phaseRef, status }) => {
|
|
277
|
+
const st = await requireStore();
|
|
278
|
+
const features = (await st.loadFeatures()).features;
|
|
279
|
+
let phases = await st.loadAllPhases();
|
|
280
|
+
if (featureRef) {
|
|
281
|
+
const f = findFeatureByRef(features, featureRef);
|
|
282
|
+
if (!f)
|
|
283
|
+
return text(`Feature not found: ${featureRef}`);
|
|
284
|
+
phases = phases.filter((p) => p.featureId === f.id);
|
|
285
|
+
}
|
|
286
|
+
if (phaseRef) {
|
|
287
|
+
const p = findPhaseByRef(phases, features, phaseRef);
|
|
288
|
+
if (!p)
|
|
289
|
+
return text(`Phase not found: ${phaseRef}`);
|
|
290
|
+
phases = [p];
|
|
291
|
+
}
|
|
292
|
+
const out = [];
|
|
293
|
+
for (const phase of phases) {
|
|
294
|
+
for (const task of phase.tasks) {
|
|
295
|
+
if (status && task.status !== status)
|
|
296
|
+
continue;
|
|
297
|
+
out.push(`- ${taskCompositeRef(task, phase, features)}${task.shortId ? ` · ${task.shortId}` : ""} — ${task.title} (${task.status})`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return text(out.join("\n") || "No tasks");
|
|
275
301
|
});
|
|
276
302
|
server.registerTool("planner-feature-add", {
|
|
277
303
|
description: "Create a feature with a rich description. REQUIRED: description must include code references (file:line), current implementation state (what exists, what is unimplemented), systems/structs/traits involved, concrete goals, and behaviors to preserve. The description is the primary context for future agents resuming this feature; one-liners cause misalignment.",
|
|
@@ -289,7 +315,7 @@ server.registerTool("planner-feature-add", {
|
|
|
289
315
|
const priority = await st.nextPriority("feature");
|
|
290
316
|
const feature = {
|
|
291
317
|
id: createFeatureId(),
|
|
292
|
-
number:
|
|
318
|
+
number: await st.allocFeatureNumber(),
|
|
293
319
|
shortId,
|
|
294
320
|
priority,
|
|
295
321
|
name: name.trim(),
|
|
@@ -316,20 +342,21 @@ server.registerTool("planner-feature-add", {
|
|
|
316
342
|
});
|
|
317
343
|
server.registerTool("planner-feature-show", {
|
|
318
344
|
description: "Show a feature by id or name.",
|
|
319
|
-
inputSchema: { feature: z.string().min(1).describe("Feature
|
|
320
|
-
}, async ({ feature: ref }) => {
|
|
345
|
+
inputSchema: { feature: z.string().min(1).describe("Feature ref. Accepts F00x/P00x/T00x composite, bare P00x/T00x (global), 5-char shortId, UUID, or title."), full: z.boolean().optional().describe("If true, include the feature description. Default: compact identity only (saves tokens).") },
|
|
346
|
+
}, async ({ feature: ref, full }) => {
|
|
321
347
|
const st = await requireStore();
|
|
322
348
|
const features = (await st.loadFeatures()).features;
|
|
323
349
|
const feature = findFeatureByRef(features, ref);
|
|
324
350
|
if (!feature)
|
|
325
351
|
return text(`Feature not found: ${ref}`);
|
|
326
352
|
const phases = (await st.loadAllPhases()).filter((phase) => phase.featureId === feature.id);
|
|
327
|
-
|
|
353
|
+
const summary = `${feature.name} — ${formatFeatureRef(feature.number)}${feature.shortId ? ` · ${feature.shortId}` : ""} (${feature.status}; ${phases.length} phases)`;
|
|
354
|
+
return text(full ? `${summary}\n\n${feature.description || ""}` : summary);
|
|
328
355
|
});
|
|
329
356
|
server.registerTool("planner-feature-update", {
|
|
330
357
|
description: "Update a feature.",
|
|
331
358
|
inputSchema: {
|
|
332
|
-
feature: z.string().min(1).describe("Feature
|
|
359
|
+
feature: z.string().min(1).describe("Feature ref. Accepts F00x/P00x/T00x composite, bare P00x/T00x (global), 5-char shortId, UUID, or title."),
|
|
333
360
|
name: z.string().optional(),
|
|
334
361
|
description: z.string().optional(),
|
|
335
362
|
status: z.enum(STATUS_VALUES).optional(),
|
|
@@ -374,7 +401,7 @@ server.registerTool("planner-feature-update", {
|
|
|
374
401
|
server.registerTool("planner-feature-delete", {
|
|
375
402
|
description: "Delete a feature. By default, phases are unlinked rather than deleted.",
|
|
376
403
|
inputSchema: {
|
|
377
|
-
feature: z.string().min(1).describe("Feature
|
|
404
|
+
feature: z.string().min(1).describe("Feature ref. Accepts F00x/P00x/T00x composite, bare P00x/T00x (global), 5-char shortId, UUID, or title."),
|
|
378
405
|
cascade: z.boolean().optional().describe("Also delete phases belonging to this feature"),
|
|
379
406
|
},
|
|
380
407
|
}, async ({ feature: ref, cascade }) => {
|
|
@@ -404,7 +431,7 @@ server.registerTool("planner-phase-add", {
|
|
|
404
431
|
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
432
|
inputSchema: {
|
|
406
433
|
title: z.string().min(1),
|
|
407
|
-
feature: z.string().optional().describe("Feature
|
|
434
|
+
feature: z.string().optional().describe("Feature ref. Accepts F00x/P00x/T00x composite, bare P00x/T00x (global), 5-char shortId, UUID, or title."),
|
|
408
435
|
summary: z.string().optional().describe("One-line summary of the phase"),
|
|
409
436
|
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
437
|
},
|
|
@@ -424,7 +451,7 @@ server.registerTool("planner-phase-add", {
|
|
|
424
451
|
const priority = await st.nextPriority("phase", feature?.id);
|
|
425
452
|
phase = {
|
|
426
453
|
id: createPhaseId(),
|
|
427
|
-
number:
|
|
454
|
+
number: await st.allocPhaseNumber(),
|
|
428
455
|
shortId,
|
|
429
456
|
priority,
|
|
430
457
|
slug: normalizeSlug(title),
|
|
@@ -472,18 +499,20 @@ server.registerTool("planner-phase-add", {
|
|
|
472
499
|
});
|
|
473
500
|
server.registerTool("planner-phase-show", {
|
|
474
501
|
description: "Show a phase by id or name.",
|
|
475
|
-
inputSchema: { phase: z.string().min(1).describe("Phase
|
|
476
|
-
}, async ({ phase: ref }) => {
|
|
502
|
+
inputSchema: { phase: z.string().min(1).describe("Phase ref. Accepts F00x/P00x/T00x composite, bare P00x/T00x (global), 5-char shortId, UUID, or title."), full: z.boolean().optional().describe("If true, include the phase description. Default: compact identity only (saves tokens).") },
|
|
503
|
+
}, async ({ phase: ref, full }) => {
|
|
477
504
|
const st = await requireStore();
|
|
478
|
-
const
|
|
505
|
+
const features = (await st.loadFeatures()).features;
|
|
506
|
+
const phase = findPhaseByRef(await st.loadAllPhases(), features, ref);
|
|
479
507
|
if (!phase)
|
|
480
508
|
return text(`Phase not found: ${ref}`);
|
|
481
|
-
|
|
509
|
+
const summary = `${phase.title} — ${formatPhaseRef(phase.number, featureNumberOfPhase(phase, features))}${phase.shortId ? ` · ${phase.shortId}` : ""} (${phase.status}; ${phase.tasks.length} tasks)`;
|
|
510
|
+
return text(full ? `${summary}\n\n${phase.description || ""}` : summary);
|
|
482
511
|
});
|
|
483
512
|
server.registerTool("planner-phase-discuss", {
|
|
484
513
|
description: "Persist phase discovery fields and mark phase planned.",
|
|
485
514
|
inputSchema: {
|
|
486
|
-
phase: z.string().min(1).describe("Phase
|
|
515
|
+
phase: z.string().min(1).describe("Phase ref. Accepts F00x/P00x/T00x composite, bare P00x/T00x (global), 5-char shortId, UUID, or title."),
|
|
487
516
|
goal: z.string().optional(),
|
|
488
517
|
summary: z.string().optional(),
|
|
489
518
|
scope: z.string().optional(),
|
|
@@ -568,12 +597,13 @@ server.registerTool("planner-phase-delete", {
|
|
|
568
597
|
feature.phaseIds = feature.phaseIds.filter((id) => id !== phase.id);
|
|
569
598
|
return doc;
|
|
570
599
|
});
|
|
571
|
-
|
|
600
|
+
const dFeat = (await st.loadFeatures()).features.find((f) => f.id === phase.featureId);
|
|
601
|
+
return writeAndSummarize(st, `Phase deleted: ${formatPhaseRef(phase.number, dFeat?.number)}${phase.shortId ? ` · ${phase.shortId}` : ""}`, { deleted: phase.id });
|
|
572
602
|
});
|
|
573
603
|
server.registerTool("planner-task-add", {
|
|
574
604
|
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
605
|
inputSchema: {
|
|
576
|
-
phase: z.string().min(1).describe("Phase
|
|
606
|
+
phase: z.string().min(1).describe("Phase ref. Accepts F00x/P00x/T00x composite, bare P00x/T00x (global), 5-char shortId, UUID, or title."),
|
|
577
607
|
title: z.string().min(1),
|
|
578
608
|
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
609
|
checklist: z.array(z.string()).optional(),
|
|
@@ -590,7 +620,7 @@ server.registerTool("planner-task-add", {
|
|
|
590
620
|
const task = {
|
|
591
621
|
id: taskId,
|
|
592
622
|
phaseId: found.id,
|
|
593
|
-
number:
|
|
623
|
+
number: await st.allocTaskNumber(),
|
|
594
624
|
shortId,
|
|
595
625
|
priority,
|
|
596
626
|
shortName: clampSlug(title, 30, `task-${Date.now().toString(36)}`),
|
|
@@ -620,13 +650,18 @@ server.registerTool("planner-task-add", {
|
|
|
620
650
|
});
|
|
621
651
|
server.registerTool("planner-task-show", {
|
|
622
652
|
description: "Show a task by id or name.",
|
|
623
|
-
inputSchema: { task: z.string().min(1).describe("Task
|
|
624
|
-
}, async ({ task: ref }) => {
|
|
653
|
+
inputSchema: { task: z.string().min(1).describe("Task ref. Accepts F00x/P00x/T00x composite, bare P00x/T00x (global), 5-char shortId, UUID, or title."), full: z.boolean().optional().describe("If true, include the task description + statusLog. Default: compact identity only (saves tokens).") },
|
|
654
|
+
}, async ({ task: ref, full }) => {
|
|
625
655
|
const st = await requireStore();
|
|
626
|
-
const found = findTaskByRef(await st.loadAllPhases(), ref);
|
|
656
|
+
const found = findTaskByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
627
657
|
if (!found)
|
|
628
658
|
return text(`Task not found: ${ref}`);
|
|
629
|
-
|
|
659
|
+
const features = (await st.loadFeatures()).features;
|
|
660
|
+
const summary = `${found.task.title} — ${taskCompositeRef(found.task, found.phase, features)}${found.task.shortId ? ` · ${found.task.shortId}` : ""} (${found.task.status}; phase ${formatPhaseRef(found.phase.number, featureNumberOfPhase(found.phase, features))})`;
|
|
661
|
+
if (!full)
|
|
662
|
+
return text(summary);
|
|
663
|
+
const log = (found.task.statusLog ?? []).map((e) => ` - ${e.date.slice(0, 10)} ${e.title}`).join("\n");
|
|
664
|
+
return text(`${summary}\n\n${found.task.description || ""}${log ? `\n\nStatus log:\n${log}` : ""}`);
|
|
630
665
|
});
|
|
631
666
|
server.registerTool("planner-task-discuss", {
|
|
632
667
|
description: "Persist task execution notes/checklist.",
|
|
@@ -637,7 +672,7 @@ server.registerTool("planner-task-discuss", {
|
|
|
637
672
|
},
|
|
638
673
|
}, async ({ task: ref, description, checklist }) => {
|
|
639
674
|
const st = await requireStore();
|
|
640
|
-
const found = findTaskByRef(await st.loadAllPhases(), ref);
|
|
675
|
+
const found = findTaskByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
641
676
|
if (!found)
|
|
642
677
|
return text(`Task not found: ${ref}`);
|
|
643
678
|
let updatedTask;
|
|
@@ -670,7 +705,7 @@ server.registerTool("planner-task-update", {
|
|
|
670
705
|
},
|
|
671
706
|
}, async ({ task: ref, title, status, description, motivation, priority }) => {
|
|
672
707
|
const st = await requireStore();
|
|
673
|
-
const found = findTaskByRef(await st.loadAllPhases(), ref);
|
|
708
|
+
const found = findTaskByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
674
709
|
if (!found)
|
|
675
710
|
return text(`Task not found: ${ref}`);
|
|
676
711
|
// Validate motivation requirement for status transitions.
|
|
@@ -720,7 +755,7 @@ server.registerTool("planner-task-delete", {
|
|
|
720
755
|
inputSchema: { task: z.string().min(1) },
|
|
721
756
|
}, async ({ task: ref }) => {
|
|
722
757
|
const st = await requireStore();
|
|
723
|
-
const found = findTaskByRef(await st.loadAllPhases(), ref);
|
|
758
|
+
const found = findTaskByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
724
759
|
if (!found)
|
|
725
760
|
return text(`Task not found: ${ref}`);
|
|
726
761
|
await st.updatePhase(found.phase.id, (phase) => {
|
|
@@ -730,14 +765,15 @@ server.registerTool("planner-task-delete", {
|
|
|
730
765
|
return phase;
|
|
731
766
|
});
|
|
732
767
|
await st.syncTaskStatusRollup(found.phase.id);
|
|
733
|
-
|
|
768
|
+
const tdFeatures = (await st.loadFeatures()).features;
|
|
769
|
+
return writeAndSummarize(st, `Task deleted: ${taskCompositeRef(found.task, found.phase, tdFeatures)}${found.task.shortId ? ` · ${found.task.shortId}` : ""}`, { deleted: found.task.id });
|
|
734
770
|
});
|
|
735
771
|
server.registerTool("planner-task-start", {
|
|
736
772
|
description: "Set a task to in-progress.",
|
|
737
773
|
inputSchema: { task: z.string().min(1) },
|
|
738
774
|
}, async ({ task: ref }) => {
|
|
739
775
|
const st = await requireStore();
|
|
740
|
-
const found = findTaskByRef(await st.loadAllPhases(), ref);
|
|
776
|
+
const found = findTaskByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
741
777
|
if (!found)
|
|
742
778
|
return text(`Task not found: ${ref}`);
|
|
743
779
|
// Auto-archive the handoff on THIS task's phase (reason: task-started) — the
|
|
@@ -790,7 +826,7 @@ server.registerTool("planner-task-complete", {
|
|
|
790
826
|
},
|
|
791
827
|
}, async ({ task: ref, force, description_update }) => {
|
|
792
828
|
const st = await requireStore();
|
|
793
|
-
const found = findTaskByRef(await st.loadAllPhases(), ref);
|
|
829
|
+
const found = findTaskByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
794
830
|
if (!found)
|
|
795
831
|
return text(`Task not found: ${ref}`);
|
|
796
832
|
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.6",
|
|
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.6",
|
|
45
|
+
"@agent-plan/server": "0.2.19-next.6"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"build": "tsc -p tsconfig.json",
|