@agent-plan/mcp 0.2.22-next.2 → 0.2.22-next.3
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 +33 -22
- 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":";AAyjDA,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, findTaskByRef, buildRecap, addChecklistItem, removeChecklistItem, toggleChecklistItem, buildPhaseContextBlock, checkExplicitTaskStart, recommendNextTask, buildResumeRequiredProposal, packageVersionFromModule, resolvedPackageVersion, markFeatureRead, markPhaseRead, markTaskRead,
|
|
7
|
+
import { PlanStore, ExportService, withFeatureLock, needsMotivation, findPhaseByRef, findTaskByRef, buildRecap, addChecklistItem, removeChecklistItem, toggleChecklistItem, buildPhaseContextBlock, checkExplicitTaskStart, recommendNextTask, buildResumeRequiredProposal, packageVersionFromModule, resolvedPackageVersion, markFeatureRead, markPhaseRead, markTaskRead, contextReadEligibility, hasReadRequirements, markRequirementRead, invalidateReads } from "@agent-plan/core";
|
|
8
8
|
import { serve } from "@agent-plan/server";
|
|
9
9
|
import { createChecklistItemId, createFeatureId, createPhaseId, createTaskId, clampSlug, normalizeSlug, formatPhaseRef, formatFeatureRef, validateResolvedTarget } from "@agent-plan/core/naming";
|
|
10
10
|
const STATUS_VALUES = ["planned", "in-progress", "done", "blocked", "canceled", "rejected", "deferred", "waiting"];
|
|
@@ -450,7 +450,8 @@ server.registerTool("planner-feature-show", {
|
|
|
450
450
|
if (!resolvedFeature.ok)
|
|
451
451
|
return text(resolvedFeature.error);
|
|
452
452
|
const feature = resolvedFeature.feature;
|
|
453
|
-
|
|
453
|
+
if (full)
|
|
454
|
+
markFeatureRead(feature.id);
|
|
454
455
|
const phases = (await st.loadAllPhases()).filter((phase) => phase.featureId === feature.id);
|
|
455
456
|
const summary = `${feature.name} — ${formatFeatureRef(feature.number)}${feature.shortId ? ` · ${feature.shortId}` : ""} (${feature.status}; ${phases.length} phases)`;
|
|
456
457
|
return text(full ? `${summary}\n\n${feature.description || ""}` : summary);
|
|
@@ -658,7 +659,8 @@ server.registerTool("planner-phase-show", {
|
|
|
658
659
|
const phase = findPhaseByRef(await st.loadAllPhases(), features, ref);
|
|
659
660
|
if (!phase)
|
|
660
661
|
return text(`Phase not found: ${ref}`);
|
|
661
|
-
|
|
662
|
+
if (full)
|
|
663
|
+
markPhaseRead(phase.id, phase.featureId);
|
|
662
664
|
const linkedRequirements = await st.linkedRequirementsForPhase(phase.id);
|
|
663
665
|
const reqCount = linkedRequirements.length;
|
|
664
666
|
const summary = `${phase.title} — ${formatPhaseRef(phase.number, featureNumberOfPhase(phase, features))}${phase.shortId ? ` · ${phase.shortId}` : ""} (${phase.status}; ${phase.tasks.length} tasks${reqCount ? `; ${reqCount} linked requirement${reqCount === 1 ? "" : "s"}` : ""})`;
|
|
@@ -849,7 +851,8 @@ server.registerTool("planner-task-show", {
|
|
|
849
851
|
const found = findTaskByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
850
852
|
if (!found)
|
|
851
853
|
return text(`Task not found: ${ref}`);
|
|
852
|
-
|
|
854
|
+
if (full)
|
|
855
|
+
markTaskRead(found.task.id, found.phase.id, found.phase.featureId);
|
|
853
856
|
const features = (await st.loadFeatures()).features;
|
|
854
857
|
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))})`;
|
|
855
858
|
if (!full)
|
|
@@ -929,8 +932,8 @@ server.registerTool("planner-task-update", {
|
|
|
929
932
|
const found = findTaskByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
930
933
|
if (!found)
|
|
931
934
|
return text(`Task not found: ${ref}`);
|
|
932
|
-
if (
|
|
933
|
-
return text("
|
|
935
|
+
if (status === "in-progress" && status !== found.task.status) {
|
|
936
|
+
return text("Task start/resume transitions require planner-task-start so lifecycle state, checkpoints, and return stacks remain consistent.");
|
|
934
937
|
}
|
|
935
938
|
// Validate motivation requirement for status transitions.
|
|
936
939
|
if (status !== undefined && needsMotivation(found.task.status, status)) {
|
|
@@ -1222,6 +1225,16 @@ server.registerTool("planner-task-switch", {
|
|
|
1222
1225
|
if (source.task.status !== "in-progress" && !source.task.pauseSnapshot) {
|
|
1223
1226
|
return text(`Task switch denied: source is ${source.task.status}; only in-progress or checkpointed work can be switched.`);
|
|
1224
1227
|
}
|
|
1228
|
+
const contextEligibility = contextReadEligibility(target.task.id, target.phase.id, target.phase.featureId);
|
|
1229
|
+
if (!contextEligibility.eligible)
|
|
1230
|
+
return text(`Task switch denied: context reads required. ${contextEligibility.reason}`, contextEligibility);
|
|
1231
|
+
const linkedRequirementIds = [
|
|
1232
|
+
...(await st.linkedRequirementsForPhase(target.phase.id)).map((requirement) => requirement.id),
|
|
1233
|
+
...(target.phase.featureId ? (await st.linkedRequirementsForFeature(target.phase.featureId)).map((requirement) => requirement.id) : []),
|
|
1234
|
+
];
|
|
1235
|
+
if (!hasReadRequirements(linkedRequirementIds)) {
|
|
1236
|
+
return text("Task switch denied: read the requirements linked to the target phase and feature before switching.", { requirementIds: linkedRequirementIds });
|
|
1237
|
+
}
|
|
1225
1238
|
const eligibility = checkExplicitTaskStart(features, phases, target.task.id, project.workDeviations);
|
|
1226
1239
|
if (!eligibility.eligible)
|
|
1227
1240
|
return text(`Task switch denied: ${eligibility.reason}`);
|
|
@@ -1310,22 +1323,16 @@ server.registerTool("planner-task-switch", {
|
|
|
1310
1323
|
await st.syncTaskStatusRollup(source.phase.id);
|
|
1311
1324
|
if (target.phase.id !== source.phase.id)
|
|
1312
1325
|
await st.syncTaskStatusRollup(target.phase.id);
|
|
1313
|
-
|
|
1314
|
-
const targetRequirementAdvisory = requirementReadAdvisory([
|
|
1315
|
-
...(await st.linkedRequirementsForPhase(target.phase.id)).map((r) => r.id),
|
|
1316
|
-
...(target.phase.featureId ? (await st.linkedRequirementsForFeature(target.phase.featureId)).map((r) => r.id) : []),
|
|
1317
|
-
]);
|
|
1326
|
+
invalidateReads();
|
|
1318
1327
|
return writeAndSummarize(st, [
|
|
1319
1328
|
`🔀 Task switched: ${taskCompositeRef(source.task, source.phase, features)} → ${taskCompositeRef(target.task, target.phase, features)}`,
|
|
1320
1329
|
`Resume checkpoint: ${snapshot.whatWasBeingDone}`,
|
|
1321
1330
|
`Return target: ${taskCompositeRef(source.task, source.phase, features)} from ${snapshot.resumeLocation}`,
|
|
1322
1331
|
`Normal priority was deliberately overridden; completing the temporary task will emit RESUME REQUIRED.`,
|
|
1323
|
-
|
|
1324
|
-
...(targetRequirementAdvisory ? [targetRequirementAdvisory.trimStart()] : []),
|
|
1325
|
-
].join("\n"), { deviation: record, snapshot, resumeTaskId: source.task.id, temporaryTaskId: target.task.id, ...(targetReadAdvisory || targetRequirementAdvisory ? { readRequired: true } : {}) });
|
|
1332
|
+
].join("\n"), { deviation: record, snapshot, resumeTaskId: source.task.id, temporaryTaskId: target.task.id });
|
|
1326
1333
|
});
|
|
1327
1334
|
server.registerTool("planner-task-start", {
|
|
1328
|
-
description: "Set a task to in-progress or resume checkpointed work. BEFORE calling, use planner-task-show
|
|
1335
|
+
description: "Set a task to in-progress or resume checkpointed work. BEFORE calling, use planner-task-show(full=true), then planner-phase-show(full=true), then planner-feature-show(full=true) for the same lineage, in that exact order. Read linked requirements with planner-requirement-list when present. A different active task must first be suspended through planner-task-switch.",
|
|
1329
1336
|
inputSchema: { task: z.string().min(1) },
|
|
1330
1337
|
}, async ({ task: ref }) => {
|
|
1331
1338
|
const st = await requireStore();
|
|
@@ -1337,6 +1344,16 @@ server.registerTool("planner-task-start", {
|
|
|
1337
1344
|
return text(`Task ${found.task.id} is already in-progress.`);
|
|
1338
1345
|
if (found.task.status === "done")
|
|
1339
1346
|
return text(`Task ${found.task.id} is done. Use planner-task-update to reopen.`);
|
|
1347
|
+
const contextEligibility = contextReadEligibility(found.task.id, found.phase.id, found.phase.featureId);
|
|
1348
|
+
if (!contextEligibility.eligible)
|
|
1349
|
+
return text(`Task start denied: context reads required. ${contextEligibility.reason}`, contextEligibility);
|
|
1350
|
+
const linkedRequirementIds = [
|
|
1351
|
+
...(await st.linkedRequirementsForPhase(found.phase.id)).map((requirement) => requirement.id),
|
|
1352
|
+
...(found.phase.featureId ? (await st.linkedRequirementsForFeature(found.phase.featureId)).map((requirement) => requirement.id) : []),
|
|
1353
|
+
];
|
|
1354
|
+
if (!hasReadRequirements(linkedRequirementIds)) {
|
|
1355
|
+
return text("Task start denied: read the requirements linked to the task's phase and feature first.", { requirementIds: linkedRequirementIds });
|
|
1356
|
+
}
|
|
1340
1357
|
const project = await st.loadProject();
|
|
1341
1358
|
const phases = await st.loadAllPhases();
|
|
1342
1359
|
const eligibility = checkExplicitTaskStart(features, phases, found.task.id, project.workDeviations);
|
|
@@ -1429,14 +1446,8 @@ server.registerTool("planner-task-start", {
|
|
|
1429
1446
|
if (resumedDeviation)
|
|
1430
1447
|
await st.setWorkDeviationState(resumedDeviation.id, "resumed", timestamp);
|
|
1431
1448
|
const t = updatedTask ?? found.task;
|
|
1432
|
-
|
|
1433
|
-
const requirementAdvisory = requirementReadAdvisory([
|
|
1434
|
-
...(phaseWithRequirements.linkedRequirements ?? []).map((r) => r.id),
|
|
1435
|
-
...featureRequirements.map((r) => r.id),
|
|
1436
|
-
]);
|
|
1437
|
-
return writeAndSummarize(st, `✅ Task started: ${taskCompositeRef(t, found.phase, features)} — ${t.title} (in-progress)${t.shortId ? ` · ${t.shortId}` : ""}${phaseContext}${advisory}${readAdvisory}${requirementAdvisory}`, {
|
|
1449
|
+
return writeAndSummarize(st, `✅ Task started: ${taskCompositeRef(t, found.phase, features)} — ${t.title} (in-progress)${t.shortId ? ` · ${t.shortId}` : ""}${phaseContext}${advisory}`, {
|
|
1438
1450
|
...(resumeProposal ? { resumeRequired: resumeProposal.structured } : {}),
|
|
1439
|
-
...(readAdvisory || requirementAdvisory ? { readRequired: true } : {}),
|
|
1440
1451
|
});
|
|
1441
1452
|
});
|
|
1442
1453
|
server.registerTool("planner-task-complete", {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-plan/mcp",
|
|
3
|
-
"version": "0.2.22-next.
|
|
3
|
+
"version": "0.2.22-next.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "MCP server for Agent Plan, exposing planner-* tools over stdio.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -43,8 +43,8 @@
|
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"@modelcontextprotocol/sdk": "^1.17.0",
|
|
45
45
|
"zod": "^3.24.0",
|
|
46
|
-
"@agent-plan/core": "0.2.22-next.
|
|
47
|
-
"@agent-plan/server": "0.2.22-next.
|
|
46
|
+
"@agent-plan/core": "0.2.22-next.3",
|
|
47
|
+
"@agent-plan/server": "0.2.22-next.3"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "tsc -p tsconfig.json",
|