@agent-plan/mcp 0.2.19-next.21 → 0.2.19-next.23

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAkvCA,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAItD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAgwCA,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, migrateToGlobalSequence, addChecklistItem, removeChecklistItem, toggleChecklistItem, buildPhaseContextBlock, recommendNextTask } from "@agent-plan/core";
7
+ import { PlanStore, ExportService, withFeatureLock, needsMotivation, findPhaseByRef, findTaskByRef, buildRecap, migrateToGlobalSequence, addChecklistItem, removeChecklistItem, toggleChecklistItem, buildPhaseContextBlock, checkExplicitTaskStart, recommendNextTask } from "@agent-plan/core";
8
8
  import { serve } from "@agent-plan/server";
9
9
  import { createChecklistItemId, createFeatureId, createPhaseId, createShortId, 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"];
@@ -649,7 +649,18 @@ server.registerTool("planner-phase-show", {
649
649
  const requirementsBlock = reqCount > 0
650
650
  ? `\n\nLinked requirements:\n${linkedRequirements.map((requirement) => `- ${requirement.title} (${requirement.status})`).join("\n")}`
651
651
  : "";
652
- return text(full ? `${summary}\n\n${phase.description || ""}${requirementsBlock}` : summary, { linkedRequirements });
652
+ return text(full ? `${summary}\n\n${phase.description || ""}${requirementsBlock}` : summary, {
653
+ phase: {
654
+ ref: formatPhaseRef(phase.number, featureNumberOfPhase(phase, features)),
655
+ shortId: phase.shortId,
656
+ title: phase.title,
657
+ summary: phase.summary,
658
+ status: phase.status,
659
+ taskCount: phase.tasks.length,
660
+ ...(full ? { description: phase.description } : {}),
661
+ },
662
+ linkedRequirements,
663
+ });
653
664
  });
654
665
  server.registerTool("planner-phase-discuss", {
655
666
  description: "Persist phase discovery fields and mark phase planned.",
@@ -1086,15 +1097,11 @@ server.registerTool("planner-task-start", {
1086
1097
  if (found.task.status === "done")
1087
1098
  return text(`Task ${found.task.id} is done. Use planner-task-update to reopen.`);
1088
1099
  const project = await st.loadProject();
1089
- const selection = recommendNextTask(features, await st.loadAllPhases(), project.workDeviations);
1090
- if (!selection.candidate || selection.candidate.task.id !== found.task.id) {
1091
- const recommended = selection.candidate ? ` Start ${selection.candidate.task.id} instead, or record a user-approved planner-task-deviation first.` : "";
1092
- return text(`Task start denied: ${selection.reason}.${recommended}`, {
1093
- kind: selection.kind,
1094
- reason: selection.reason,
1095
- recommendedTaskId: selection.candidate?.task.id,
1096
- });
1097
- }
1100
+ const phases = await st.loadAllPhases();
1101
+ const eligibility = checkExplicitTaskStart(features, phases, found.task.id, project.workDeviations);
1102
+ if (!eligibility.eligible)
1103
+ return text(`Task start denied: ${eligibility.reason}`, { reason: eligibility.reason });
1104
+ const selection = recommendNextTask(features, phases, project.workDeviations);
1098
1105
  // Assemble the mandatory parent context before changing task lifecycle state.
1099
1106
  const parentFeature = found.phase.featureId ? features.find((f) => f.id === found.phase.featureId) : undefined;
1100
1107
  const [phaseWithRequirements, featureRequirements] = await Promise.all([
@@ -1105,6 +1112,13 @@ server.registerTool("planner-task-start", {
1105
1112
  // A pending handoff is context, not a lock: task start RETAINS it. It is
1106
1113
  // archived only when the phase completes (auto) or the user explicitly
1107
1114
  // clears it.
1115
+ const advisory = selection.kind === "conflict"
1116
+ ? `\n\n⚠️ ${selection.reason} Explicit task request honored; reconcile active work before relying on automatic recommendations.`
1117
+ : selection.candidate && selection.candidate.task.id !== found.task.id
1118
+ ? selection.kind === "active"
1119
+ ? `\n\n⚠️ Active-task advisory: ${taskCompositeRef(selection.candidate.task, selection.candidate.phase, features)} is already in progress. Explicit task request honored.`
1120
+ : `\n\n⚠️ Priority advisory: ${taskCompositeRef(selection.candidate.task, selection.candidate.phase, features)} is the automatic recommendation. Explicit task request honored.`
1121
+ : "";
1108
1122
  const timestamp = nowISO();
1109
1123
  let updatedTask;
1110
1124
  await st.updatePhase(found.phase.id, (phase) => {
@@ -1129,11 +1143,11 @@ server.registerTool("planner-task-start", {
1129
1143
  return phase;
1130
1144
  });
1131
1145
  await st.syncTaskStatusRollup(found.phase.id);
1132
- if (selection.deviation?.temporaryTaskId === found.task.id && selection.deviation.state === "approved") {
1133
- await st.setWorkDeviationState(selection.deviation.id, "active", timestamp);
1134
- }
1146
+ const approvedDeviation = project.workDeviations.find((deviation) => deviation.temporaryTaskId === found.task.id && deviation.state === "approved");
1147
+ if (approvedDeviation)
1148
+ await st.setWorkDeviationState(approvedDeviation.id, "active", timestamp);
1135
1149
  const t = updatedTask ?? found.task;
1136
- return writeAndSummarize(st, `✅ Task started: ${taskCompositeRef(t, found.phase, features)} — ${t.title} (in-progress)${t.shortId ? ` · ${t.shortId}` : ""}${phaseContext}`);
1150
+ return writeAndSummarize(st, `✅ Task started: ${taskCompositeRef(t, found.phase, features)} — ${t.title} (in-progress)${t.shortId ? ` · ${t.shortId}` : ""}${phaseContext}${advisory}`);
1137
1151
  });
1138
1152
  server.registerTool("planner-task-complete", {
1139
1153
  description: "Set a task to done. Fails if checklist is incomplete unless force=true.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-plan/mcp",
3
- "version": "0.2.19-next.21",
3
+ "version": "0.2.19-next.23",
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/server": "0.2.19-next.21",
47
- "@agent-plan/core": "0.2.19-next.21"
46
+ "@agent-plan/core": "0.2.19-next.23",
47
+ "@agent-plan/server": "0.2.19-next.23"
48
48
  },
49
49
  "scripts": {
50
50
  "build": "tsc -p tsconfig.json",