@agent-plan/mcp 0.2.17 → 0.2.19-next.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.d.ts.map +1 -1
- package/dist/index.js +109 -41
- 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":";AA+5BA,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAItD"}
|
package/dist/index.js
CHANGED
|
@@ -3,11 +3,10 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
4
|
import * as z from "zod/v4";
|
|
5
5
|
import { join } from "node:path";
|
|
6
|
-
import { existsSync } from "node:fs";
|
|
7
6
|
import { pathToFileURL } from "node:url";
|
|
8
|
-
import { PlanStore, ExportService, withFeatureLock, needsMotivation } from "@agent-plan/core";
|
|
7
|
+
import { PlanStore, ExportService, withFeatureLock, needsMotivation, findPhaseByRef } from "@agent-plan/core";
|
|
9
8
|
import { serve } from "@agent-plan/server";
|
|
10
|
-
import { createChecklistItemId, createFeatureId, createPhaseId, createTaskId, clampSlug, normalizeSlug } from "@agent-plan/core/naming";
|
|
9
|
+
import { createChecklistItemId, createFeatureId, createPhaseId, createShortId, createTaskId, clampSlug, normalizeSlug, formatPhaseRef } from "@agent-plan/core/naming";
|
|
11
10
|
const STATUS_VALUES = ["planned", "in-progress", "done", "blocked", "canceled", "rejected", "deferred", "waiting"];
|
|
12
11
|
const PHASE_STATUS_VALUES = ["draft", "discovery", ...STATUS_VALUES];
|
|
13
12
|
function text(textValue, structuredContent) {
|
|
@@ -28,8 +27,14 @@ async function requireStore() {
|
|
|
28
27
|
const st = store();
|
|
29
28
|
if (!(await st.exists()))
|
|
30
29
|
throw new Error(`No .planner/ found at ${st.root}. Use planner-init first.`);
|
|
30
|
+
// One-time idempotent backfill of shortId + priority (safe, best-effort).
|
|
31
|
+
if (!planBackfillDone) {
|
|
32
|
+
planBackfillDone = true;
|
|
33
|
+
await st.ensureShortIdsAndPriority().catch(() => { });
|
|
34
|
+
}
|
|
31
35
|
return st;
|
|
32
36
|
}
|
|
37
|
+
let planBackfillDone = false;
|
|
33
38
|
// In-process web server handle, managed by the planner-web tool and planner-load.
|
|
34
39
|
// Lives as long as this MCP stdio process (i.e. the host session). Null when not running.
|
|
35
40
|
let webHandle = null;
|
|
@@ -53,7 +58,7 @@ async function ensureWebStarted() {
|
|
|
53
58
|
/** Build a consolidated planner recap (project state + active work + pending
|
|
54
59
|
* handoff + web URL). Harness-agnostic equivalent of Pi's buildStartupResumeSummary. */
|
|
55
60
|
async function buildRecapText(st, web) {
|
|
56
|
-
const [plan, resume,
|
|
61
|
+
const [plan, resume, handoffs] = await Promise.all([st.loadAll(), st.loadResume(), st.listHandoffs()]);
|
|
57
62
|
const allTasks = plan.phases.flatMap((p) => p.tasks.map((t) => ({ phase: p, task: t })));
|
|
58
63
|
const totalF = plan.features.features.length;
|
|
59
64
|
const doneF = plan.features.features.filter((f) => f.status === "done").length;
|
|
@@ -80,11 +85,13 @@ async function buildRecapText(st, web) {
|
|
|
80
85
|
}
|
|
81
86
|
if (resume?.nextSteps?.length)
|
|
82
87
|
lines.push(`Next step: ${resume.nextSteps[0]}`);
|
|
83
|
-
if (
|
|
84
|
-
lines.push("",
|
|
88
|
+
if (handoffs.length > 0) {
|
|
89
|
+
lines.push("", `## Pending phase handoffs (${handoffs.length})`);
|
|
90
|
+
handoffs.forEach((h, i) => lines.push(`[${i + 1}] ${h.compositeRef} — ${h.updatedAt} — "${h.firstLine}"`));
|
|
91
|
+
lines.push("", "→ Read the relevant one with planner-handoff-show <ref> (validate against current state), then call planner-handoff-clear <ref> once consumed (delete-on-resume).");
|
|
85
92
|
}
|
|
86
93
|
else if (activeT === 0) {
|
|
87
|
-
lines.push("", "No handoff pending and no task in-progress. Use planner-task-add / planner-task-start to begin work.");
|
|
94
|
+
lines.push("", "No phase handoff pending and no task in-progress. Use planner-task-add / planner-task-start to begin work.");
|
|
88
95
|
}
|
|
89
96
|
if (web.localUrl) {
|
|
90
97
|
lines.push("", "## Web UI", `🌐 ${web.localUrl}${web.lanUrl ? " (LAN: " + web.lanUrl + ")" : ""}`);
|
|
@@ -97,12 +104,6 @@ function findFeatureByRef(features, ref) {
|
|
|
97
104
|
?? features.find((feature) => feature.name.toLowerCase() === normalized)
|
|
98
105
|
?? features.find((feature) => feature.name.toLowerCase().includes(normalized));
|
|
99
106
|
}
|
|
100
|
-
function findPhaseByRef(phases, ref) {
|
|
101
|
-
const normalized = ref.trim().toLowerCase();
|
|
102
|
-
return phases.find((phase) => phase.id.toLowerCase() === normalized)
|
|
103
|
-
?? phases.find((phase) => phase.title.toLowerCase() === normalized)
|
|
104
|
-
?? phases.find((phase) => phase.title.toLowerCase().includes(normalized));
|
|
105
|
-
}
|
|
106
107
|
function findTaskByRef(phases, ref) {
|
|
107
108
|
const normalized = ref.trim().toLowerCase();
|
|
108
109
|
for (const phase of phases) {
|
|
@@ -136,6 +137,28 @@ const server = new McpServer({
|
|
|
136
137
|
name: "agent-plan-planner",
|
|
137
138
|
version: "0.1.0",
|
|
138
139
|
});
|
|
140
|
+
async function resolvePhaseForHandoff(st, ref) {
|
|
141
|
+
const phases = await st.loadAllPhases();
|
|
142
|
+
const features = (await st.loadFeatures()).features;
|
|
143
|
+
let phase;
|
|
144
|
+
if (ref && ref.trim()) {
|
|
145
|
+
phase = findPhaseByRef(phases, features, ref.trim());
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
phase = phases.find((p) => p.status === "in-progress")
|
|
149
|
+
?? phases.find((p) => p.tasks.some((t) => t.status === "in-progress"));
|
|
150
|
+
}
|
|
151
|
+
if (!phase) {
|
|
152
|
+
return {
|
|
153
|
+
ok: false,
|
|
154
|
+
error: ref && ref.trim()
|
|
155
|
+
? `Phase not found: "${ref.trim()}". Use P00x, P00x(F00x), UUID, or title.`
|
|
156
|
+
: "No in-progress phase. Specify a phaseRef (P00x or P00x(F00x)).",
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
const feat = phase.featureId ? features.find((f) => f.id === phase.featureId) : undefined;
|
|
160
|
+
return { ok: true, phase, compositeRef: formatPhaseRef(phase.number, feat?.number) };
|
|
161
|
+
}
|
|
139
162
|
server.registerTool("planner-export", {
|
|
140
163
|
description: "Export the project plan as a Markdown report. Supports a concise summary or full hierarchical detail.",
|
|
141
164
|
inputSchema: {
|
|
@@ -282,9 +305,13 @@ server.registerTool("planner-feature-add", {
|
|
|
282
305
|
const timestamp = nowISO();
|
|
283
306
|
const effectiveStatus = status ?? "planned";
|
|
284
307
|
const existingFeatures = (await st.loadFeatures()).features;
|
|
308
|
+
const shortId = createShortId(await st.assignedShortIds());
|
|
309
|
+
const priority = await st.nextPriority("feature");
|
|
285
310
|
const feature = {
|
|
286
311
|
id: createFeatureId(),
|
|
287
312
|
number: existingFeatures.length + 1,
|
|
313
|
+
shortId,
|
|
314
|
+
priority,
|
|
288
315
|
name: name.trim(),
|
|
289
316
|
description: description?.trim() ?? "",
|
|
290
317
|
status: effectiveStatus,
|
|
@@ -330,6 +357,7 @@ server.registerTool("planner-feature-update", {
|
|
|
330
357
|
workRemaining: z.string().optional(),
|
|
331
358
|
startDate: z.string().optional(),
|
|
332
359
|
endDate: z.string().optional(),
|
|
360
|
+
priority: z.number().int().nonnegative().optional().describe("Display order within the project (lower = higher). Tiebreak by number then createdAt."),
|
|
333
361
|
},
|
|
334
362
|
}, async ({ feature: ref, ...updates }) => {
|
|
335
363
|
const st = await requireStore();
|
|
@@ -355,6 +383,8 @@ server.registerTool("planner-feature-update", {
|
|
|
355
383
|
target.startDate = updates.startDate.trim();
|
|
356
384
|
if (updates.endDate !== undefined)
|
|
357
385
|
target.endDate = updates.endDate.trim();
|
|
386
|
+
if (updates.priority !== undefined)
|
|
387
|
+
target.priority = updates.priority;
|
|
358
388
|
target.updatedAt = nowISO();
|
|
359
389
|
return doc;
|
|
360
390
|
});
|
|
@@ -410,9 +440,13 @@ server.registerTool("planner-phase-add", {
|
|
|
410
440
|
const phases = await st.loadAllPhases();
|
|
411
441
|
const featurePhases = feature ? phases.filter((phase) => phase.featureId === feature.id) : phases;
|
|
412
442
|
const timestamp = nowISO();
|
|
443
|
+
const shortId = createShortId(await st.assignedShortIds());
|
|
444
|
+
const priority = await st.nextPriority("phase", feature?.id);
|
|
413
445
|
phase = {
|
|
414
446
|
id: createPhaseId(),
|
|
415
447
|
number: featurePhases.reduce((max, entry) => Math.max(max, entry.number), 0) + 1,
|
|
448
|
+
shortId,
|
|
449
|
+
priority,
|
|
416
450
|
slug: normalizeSlug(title),
|
|
417
451
|
title: title.trim(),
|
|
418
452
|
featureId: feature?.id,
|
|
@@ -436,6 +470,8 @@ server.registerTool("planner-phase-add", {
|
|
|
436
470
|
tasks: [],
|
|
437
471
|
createdAt: timestamp,
|
|
438
472
|
updatedAt: timestamp,
|
|
473
|
+
handoff: "",
|
|
474
|
+
handoffUpdatedAt: "",
|
|
439
475
|
};
|
|
440
476
|
await st.savePhase(phase);
|
|
441
477
|
if (feature) {
|
|
@@ -457,7 +493,7 @@ server.registerTool("planner-phase-show", {
|
|
|
457
493
|
inputSchema: { phase: z.string().min(1).describe("Phase id or name") },
|
|
458
494
|
}, async ({ phase: ref }) => {
|
|
459
495
|
const st = await requireStore();
|
|
460
|
-
const phase = findPhaseByRef(await st.loadAllPhases(), ref);
|
|
496
|
+
const phase = findPhaseByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
461
497
|
if (!phase)
|
|
462
498
|
return text(`Phase not found: ${ref}`);
|
|
463
499
|
return text(`${phase.title} (${phase.id}) — ${phase.status}; ${phase.tasks.length} tasks`, { phase });
|
|
@@ -476,7 +512,7 @@ server.registerTool("planner-phase-discuss", {
|
|
|
476
512
|
},
|
|
477
513
|
}, async ({ phase: ref, ...updates }) => {
|
|
478
514
|
const st = await requireStore();
|
|
479
|
-
const found = findPhaseByRef(await st.loadAllPhases(), ref);
|
|
515
|
+
const found = findPhaseByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
480
516
|
if (!found)
|
|
481
517
|
return text(`Phase not found: ${ref}`);
|
|
482
518
|
const phase = await st.updatePhase(found.id, (entry) => {
|
|
@@ -511,10 +547,11 @@ server.registerTool("planner-phase-update", {
|
|
|
511
547
|
status: z.enum(PHASE_STATUS_VALUES).optional(),
|
|
512
548
|
summary: z.string().optional(),
|
|
513
549
|
description: z.string().optional(),
|
|
550
|
+
priority: z.number().int().nonnegative().optional().describe("Display order within the feature (lower = higher)."),
|
|
514
551
|
},
|
|
515
552
|
}, async ({ phase: ref, ...updates }) => {
|
|
516
553
|
const st = await requireStore();
|
|
517
|
-
const found = findPhaseByRef(await st.loadAllPhases(), ref);
|
|
554
|
+
const found = findPhaseByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
518
555
|
if (!found)
|
|
519
556
|
return text(`Phase not found: ${ref}`);
|
|
520
557
|
const phase = await st.updatePhase(found.id, (entry) => {
|
|
@@ -526,6 +563,8 @@ server.registerTool("planner-phase-update", {
|
|
|
526
563
|
entry.summary = updates.summary.trim();
|
|
527
564
|
if (updates.description !== undefined)
|
|
528
565
|
entry.description = updates.description.trim();
|
|
566
|
+
if (updates.priority !== undefined)
|
|
567
|
+
entry.priority = updates.priority;
|
|
529
568
|
entry.updatedAt = nowISO();
|
|
530
569
|
return entry;
|
|
531
570
|
});
|
|
@@ -536,7 +575,7 @@ server.registerTool("planner-phase-delete", {
|
|
|
536
575
|
inputSchema: { phase: z.string().min(1) },
|
|
537
576
|
}, async ({ phase: ref }) => {
|
|
538
577
|
const st = await requireStore();
|
|
539
|
-
const phase = findPhaseByRef(await st.loadAllPhases(), ref);
|
|
578
|
+
const phase = findPhaseByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
540
579
|
if (!phase)
|
|
541
580
|
return text(`Phase not found: ${ref}`);
|
|
542
581
|
await st.deletePhase(phase.id);
|
|
@@ -557,15 +596,19 @@ server.registerTool("planner-task-add", {
|
|
|
557
596
|
},
|
|
558
597
|
}, async ({ phase: ref, title, description, checklist }) => {
|
|
559
598
|
const st = await requireStore();
|
|
560
|
-
const found = findPhaseByRef(await st.loadAllPhases(), ref);
|
|
599
|
+
const found = findPhaseByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
561
600
|
if (!found)
|
|
562
601
|
return text(`Phase not found: ${ref}`);
|
|
563
602
|
const timestamp = nowISO();
|
|
564
603
|
const taskId = createTaskId();
|
|
604
|
+
const shortId = createShortId(await st.assignedShortIds());
|
|
605
|
+
const priority = await st.nextPriority("task", found.id);
|
|
565
606
|
const task = {
|
|
566
607
|
id: taskId,
|
|
567
608
|
phaseId: found.id,
|
|
568
609
|
number: found.tasks.length + 1,
|
|
610
|
+
shortId,
|
|
611
|
+
priority,
|
|
569
612
|
shortName: clampSlug(title, 30, `task-${Date.now().toString(36)}`),
|
|
570
613
|
title: title.trim(),
|
|
571
614
|
status: "planned",
|
|
@@ -636,8 +679,9 @@ server.registerTool("planner-task-update", {
|
|
|
636
679
|
status: z.enum(STATUS_VALUES).optional(),
|
|
637
680
|
description: z.string().optional(),
|
|
638
681
|
motivation: z.string().optional(),
|
|
682
|
+
priority: z.number().int().nonnegative().optional().describe("Display order within the phase (lower = higher)."),
|
|
639
683
|
},
|
|
640
|
-
}, async ({ task: ref, title, status, description, motivation }) => {
|
|
684
|
+
}, async ({ task: ref, title, status, description, motivation, priority }) => {
|
|
641
685
|
const st = await requireStore();
|
|
642
686
|
const found = findTaskByRef(await st.loadAllPhases(), ref);
|
|
643
687
|
if (!found)
|
|
@@ -657,6 +701,8 @@ server.registerTool("planner-task-update", {
|
|
|
657
701
|
return phase;
|
|
658
702
|
if (title !== undefined)
|
|
659
703
|
task.title = title.trim();
|
|
704
|
+
if (priority !== undefined)
|
|
705
|
+
task.priority = priority;
|
|
660
706
|
if (description !== undefined)
|
|
661
707
|
task.description = description.trim();
|
|
662
708
|
if (status !== undefined && status !== task.status) {
|
|
@@ -706,8 +752,8 @@ server.registerTool("planner-task-start", {
|
|
|
706
752
|
// task_start — the handoff is a captured-context artifact, not a lock (e.g. a
|
|
707
753
|
// small modification after writing a handoff should start without forcing
|
|
708
754
|
// deletion, which would lose context).
|
|
709
|
-
const handoffNotice =
|
|
710
|
-
? "ℹ️
|
|
755
|
+
const handoffNotice = (await st.listHandoffs()).length > 0
|
|
756
|
+
? "ℹ️ One or more phases have a pending handoff — if relevant to the task you're starting, read it with planner-handoff-show <ref>, then clear with planner-handoff-clear. Proceeding with task start.\n"
|
|
711
757
|
: "";
|
|
712
758
|
const found = findTaskByRef(await st.loadAllPhases(), ref);
|
|
713
759
|
if (!found)
|
|
@@ -780,41 +826,63 @@ server.registerTool("planner-task-complete", {
|
|
|
780
826
|
updatedTask = task;
|
|
781
827
|
return phase;
|
|
782
828
|
});
|
|
783
|
-
await st.syncTaskStatusRollup(found.phase.id);
|
|
784
|
-
return writeAndSummarize(st, `✅ Task completed: ${found.task.id}`, { task: updatedTask ?? found.task });
|
|
829
|
+
const clearedRef = await st.syncTaskStatusRollup(found.phase.id);
|
|
830
|
+
return writeAndSummarize(st, `✅ Task completed: ${found.task.id}${clearedRef ? ` — phase handoff auto-cleared (${clearedRef})` : ""}`, { task: updatedTask ?? found.task });
|
|
785
831
|
});
|
|
786
|
-
server.registerTool("planner-handoff-
|
|
787
|
-
description: "
|
|
832
|
+
server.registerTool("planner-handoff-list", {
|
|
833
|
+
description: "List all phases with a non-empty entity-scoped handoff (phase.handoff field). Returns composite refs (P00x / P00x(F00x)) with the first line and last-updated time.",
|
|
788
834
|
}, async () => {
|
|
789
835
|
const st = await requireStore();
|
|
790
|
-
const
|
|
791
|
-
|
|
836
|
+
const list = await st.listHandoffs();
|
|
837
|
+
if (list.length === 0)
|
|
838
|
+
return text("No phase handoffs set.");
|
|
839
|
+
const lines = list.map((e) => `- ${e.compositeRef} — ${e.firstLine} (updated ${e.updatedAt})`);
|
|
840
|
+
return text(`Phase handoffs (${list.length}):\n${lines.join("\n")}`, { count: list.length, handoffs: list });
|
|
841
|
+
});
|
|
842
|
+
server.registerTool("planner-handoff-show", {
|
|
843
|
+
description: "Read the entity-scoped handoff of a phase. phaseRef accepts P00x, P00x(F00x), UUID, or title. Omit to target the current in-progress phase.",
|
|
844
|
+
inputSchema: { phaseRef: z.string().optional().describe("Phase ref: P00x | P00x(F00x) | UUID | title. Default: current in-progress phase.") },
|
|
845
|
+
}, async ({ phaseRef }) => {
|
|
846
|
+
const st = await requireStore();
|
|
847
|
+
const r = await resolvePhaseForHandoff(st, phaseRef);
|
|
848
|
+
if (!r.ok)
|
|
849
|
+
return text(`❌ ${r.error}`);
|
|
850
|
+
const content = await st.getPhaseHandoff(r.phase.id);
|
|
851
|
+
if (!content.trim())
|
|
852
|
+
return text(`No handoff set on ${r.compositeRef}.`, { phaseRef: r.compositeRef, empty: true });
|
|
853
|
+
return text(`Handoff for ${r.compositeRef}:\n\n${content}`, { phaseRef: r.compositeRef, phaseId: r.phase.id });
|
|
792
854
|
});
|
|
793
855
|
server.registerTool("planner-handoff-write", {
|
|
794
|
-
description: "Write .
|
|
856
|
+
description: "Write/refresh the entity-scoped handoff on a phase. Pass content (markdown). phaseRef optional (default: current in-progress phase). Captures design context for a resuming agent on that phase.",
|
|
795
857
|
inputSchema: {
|
|
796
|
-
|
|
797
|
-
|
|
858
|
+
phaseRef: z.string().optional().describe("Phase ref. Default: current in-progress phase."),
|
|
859
|
+
content: z.string().min(1).describe("Handoff text (markdown)."),
|
|
798
860
|
},
|
|
799
|
-
}, async ({
|
|
861
|
+
}, async ({ phaseRef, content }) => {
|
|
800
862
|
const st = await requireStore();
|
|
801
|
-
const
|
|
802
|
-
|
|
803
|
-
|
|
863
|
+
const r = await resolvePhaseForHandoff(st, phaseRef);
|
|
864
|
+
if (!r.ok)
|
|
865
|
+
return text(`❌ ${r.error}`);
|
|
866
|
+
await st.setPhaseHandoff(r.phase.id, content);
|
|
867
|
+
return text(`✅ Wrote handoff on ${r.compositeRef}.`, { phaseRef: r.compositeRef, phaseId: r.phase.id });
|
|
804
868
|
});
|
|
805
869
|
server.registerTool("planner-handoff-prepare", {
|
|
806
|
-
description: "Return instructions for the agent to prepare a canonical handoff, then call planner-handoff-write.",
|
|
870
|
+
description: "Return instructions for the agent to prepare a canonical handoff, then call planner-handoff-write (entity-scoped, phase.handoff).",
|
|
807
871
|
}, async () => text([
|
|
808
|
-
"Prepare the canonical session handoff and write it with planner-handoff-write.",
|
|
872
|
+
"Prepare the canonical session handoff and write it on the current in-progress phase with planner-handoff-write (omit phaseRef to target the in-progress phase).",
|
|
809
873
|
"Required sections: Created at, Updated at, Reason, Current focus, What was being done, How to resume, Files touched, Blockers, Next steps, Recent decisions, Reminder.",
|
|
810
|
-
"
|
|
874
|
+
"Stored on the phase.handoff field (entity-scoped). .planner/HANDOFF.md is deprecated.",
|
|
811
875
|
].join("\n")));
|
|
812
876
|
server.registerTool("planner-handoff-clear", {
|
|
813
|
-
description: "
|
|
814
|
-
|
|
877
|
+
description: "Clear the entity-scoped handoff of a phase (sets handoff to empty, keeps handoffUpdatedAt as an audit trail). phaseRef optional (default: current in-progress phase).",
|
|
878
|
+
inputSchema: { phaseRef: z.string().optional().describe("Phase ref. Default: current in-progress phase.") },
|
|
879
|
+
}, async ({ phaseRef }) => {
|
|
815
880
|
const st = await requireStore();
|
|
816
|
-
await st
|
|
817
|
-
|
|
881
|
+
const r = await resolvePhaseForHandoff(st, phaseRef);
|
|
882
|
+
if (!r.ok)
|
|
883
|
+
return text(`❌ ${r.error}`);
|
|
884
|
+
await st.clearPhaseHandoff(r.phase.id);
|
|
885
|
+
return text(`✅ Cleared handoff on ${r.compositeRef}. (handoffUpdatedAt preserved as audit)`, { phaseRef: r.compositeRef, phaseId: r.phase.id });
|
|
818
886
|
});
|
|
819
887
|
server.registerTool("planner-web", {
|
|
820
888
|
description: "Manage the planner web dashboard (start/status/stop) from MCP stdio. Runs an in-process HTTP+WS server bound to LAN; it lives as long as this MCP process. plan-root comes from AGENT_PLAN_ROOT or cwd()/.planner.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-plan/mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.19-next.0",
|
|
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.
|
|
45
|
-
"@agent-plan/server": "0.2.
|
|
44
|
+
"@agent-plan/core": "0.2.19-next.0",
|
|
45
|
+
"@agent-plan/server": "0.2.19-next.0"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|
|
48
48
|
"build": "tsc -p tsconfig.json",
|