@agent-plan/mcp 0.4.1 → 0.4.2
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 +25 -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":";AA4BA,KAAK,UAAU,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AA2LrI;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,UAAU,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAUzE;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA4BA,KAAK,UAAU,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AA2LrI;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,UAAU,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAUzE;AAi4FD,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAItD"}
|
package/dist/index.js
CHANGED
|
@@ -1484,7 +1484,7 @@ server.registerTool("planner-task-show", {
|
|
|
1484
1484
|
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))})`;
|
|
1485
1485
|
if (!full)
|
|
1486
1486
|
return text(summary);
|
|
1487
|
-
const project = await st.loadProject();
|
|
1487
|
+
const project = await st.loadProject(plannerSessionId);
|
|
1488
1488
|
const pendingDeviation = found.task.status === "done" || found.task.status === "canceled" || found.task.status === "rejected"
|
|
1489
1489
|
? undefined
|
|
1490
1490
|
: project.workDeviations
|
|
@@ -1707,7 +1707,8 @@ server.registerTool("planner-task-update", {
|
|
|
1707
1707
|
checklist: z.array(z.string()).optional().describe("Replace the task checklist (implementation steps, plain strings). Ticks carry over by exact title match, and by position when the new list is the same length (so renaming an item keeps its tick); an item that cannot be matched loses its tick and that loss is reported. Agents should tick steps via planner-task-checklist-toggle, not write DONE in titles, and use planner-task-checklist-add/remove for granular edits."),
|
|
1708
1708
|
subtasks: z.array(z.object({ id: z.string().optional(), title: z.string().min(1), description: z.string().optional(), status: z.enum(STATUS_VALUES).optional() })).optional().describe("Replace subtasks; existing IDs must belong to this task and omitted IDs are planner-generated."),
|
|
1709
1709
|
},
|
|
1710
|
-
}, async ({ task: ref, title, status, description, descriptionRef: rawDescriptionRef, notes, decisions, motivation, priority, checklist, subtasks }) => {
|
|
1710
|
+
}, async ({ task: ref, title, status, description, descriptionRef: rawDescriptionRef, notes, decisions, motivation, priority, checklist, subtasks }, extra) => {
|
|
1711
|
+
const plannerSessionId = plannerSessionIdFor(extra);
|
|
1711
1712
|
const st = await requireStore();
|
|
1712
1713
|
const found = findTaskByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
1713
1714
|
if (!found)
|
|
@@ -1813,7 +1814,7 @@ server.registerTool("planner-task-update", {
|
|
|
1813
1814
|
let resumeNotice = "";
|
|
1814
1815
|
let resumeRequired;
|
|
1815
1816
|
if (status && status !== "in-progress" && status !== found.task.status) {
|
|
1816
|
-
const deviation = (await st.loadProject()).workDeviations
|
|
1817
|
+
const deviation = (await st.loadProject(plannerSessionId)).workDeviations
|
|
1817
1818
|
.filter((entry) => (entry.state === "approved" || entry.state === "active") && entry.temporaryTaskId === found.task.id)
|
|
1818
1819
|
.sort((left, right) => right.createdAt.localeCompare(left.createdAt))[0];
|
|
1819
1820
|
if (deviation) {
|
|
@@ -1999,17 +2000,17 @@ server.registerTool("planner-task-delete", {
|
|
|
1999
2000
|
server.registerTool("planner-task-recommend", {
|
|
2000
2001
|
description: "Return the harness-agnostic next-work chain: active task if present, otherwise the lowest-priority ready feature → phase → task, plus bounded typed claims. Only persisted resume-ready handoffs are actionable; Markdown prose and terminal archives are not authority. Does not start or block work.",
|
|
2001
2002
|
inputSchema: {},
|
|
2002
|
-
}, async () => {
|
|
2003
|
+
}, async (_args, extra) => {
|
|
2004
|
+
const plannerSessionId = plannerSessionIdFor(extra);
|
|
2003
2005
|
const st = await requireStore();
|
|
2004
|
-
const [features, phases,
|
|
2006
|
+
const [features, phases, resume, handoffs, archivedHandoffs] = await Promise.all([
|
|
2005
2007
|
st.loadFeatures(),
|
|
2006
2008
|
st.loadAllPhases(),
|
|
2007
|
-
st.
|
|
2008
|
-
st.loadResume(),
|
|
2009
|
+
st.loadResume(plannerSessionId),
|
|
2009
2010
|
st.listHandoffs(),
|
|
2010
2011
|
st.listArchivedHandoffs(),
|
|
2011
2012
|
]);
|
|
2012
|
-
const result = recommendNextWork(features.features, phases,
|
|
2013
|
+
const result = recommendNextWork(features.features, phases, await st.listAllWorkDeviations(), resume?.currentPhaseId, plannerSessionId, {
|
|
2013
2014
|
handoffs: handoffs.map((handoff) => ({
|
|
2014
2015
|
compositeRef: handoff.compositeRef,
|
|
2015
2016
|
firstLine: handoff.firstLine,
|
|
@@ -2023,13 +2024,14 @@ server.registerTool("planner-task-recommend", {
|
|
|
2023
2024
|
server.registerTool("planner-task-deviation", {
|
|
2024
2025
|
description: "Record a user-approved temporary task deviation. It preserves the recommended/resume task and never starts, pauses, or blocks work; use normal lifecycle tools for those transitions.",
|
|
2025
2026
|
inputSchema: { temporary_task: z.string().min(1), resume_task: z.string().min(1).optional(), reason: z.string().min(1) },
|
|
2026
|
-
}, async ({ temporary_task, resume_task, reason }) => {
|
|
2027
|
+
}, async ({ temporary_task, resume_task, reason }, extra) => {
|
|
2028
|
+
const plannerSessionId = plannerSessionIdFor(extra);
|
|
2027
2029
|
const st = await requireStore();
|
|
2028
|
-
const [features, phases,
|
|
2030
|
+
const [features, phases, focus] = await Promise.all([st.loadFeatures(), st.loadAllPhases(), st.loadResume(plannerSessionId)]);
|
|
2029
2031
|
const temporary = findTaskByRef(phases, features.features, temporary_task);
|
|
2030
2032
|
if (!temporary)
|
|
2031
2033
|
return text(`Task not found: ${temporary_task}`);
|
|
2032
|
-
const selected = recommendNextTask(features.features, phases,
|
|
2034
|
+
const selected = recommendNextTask(features.features, phases, await st.listAllWorkDeviations(), focus?.currentPhaseId, plannerSessionId);
|
|
2033
2035
|
const resume = resume_task ? findTaskByRef(phases, features.features, resume_task) : selected.candidate;
|
|
2034
2036
|
if (!resume)
|
|
2035
2037
|
return text(`No resume task is available. Provide resume_task explicitly. ${selected.reason}`);
|
|
@@ -2044,7 +2046,7 @@ server.registerTool("planner-task-deviation", {
|
|
|
2044
2046
|
requestedBy: "user", approvedBy: "user", state: "approved",
|
|
2045
2047
|
createdAt: timestamp, activatedAt: "", resumeRequiredAt: "", resolvedAt: "", resumedAt: "",
|
|
2046
2048
|
};
|
|
2047
|
-
await st.addWorkDeviation(record);
|
|
2049
|
+
await st.addWorkDeviation(record, plannerSessionId);
|
|
2048
2050
|
return writeAndSummarize(st, `✅ Approved deviation: ${taskCompositeRef(temporary.task, temporary.phase, features.features)} temporarily overrides ${taskCompositeRef(resume.task, resume.phase, features.features)}. Resume target retained.`, { deviation: record });
|
|
2049
2051
|
});
|
|
2050
2052
|
server.registerTool("planner-task-pause", {
|
|
@@ -2074,7 +2076,7 @@ server.registerTool("planner-task-pause", {
|
|
|
2074
2076
|
invalidateReads(plannerSessionId);
|
|
2075
2077
|
const checkpointed = await st.pauseTask(found.phase.id, found.task.id, snapshot);
|
|
2076
2078
|
await st.syncTaskStatusRollup(found.phase.id);
|
|
2077
|
-
const activeDeviation = (await st.loadProject()).workDeviations
|
|
2079
|
+
const activeDeviation = (await st.loadProject(plannerSessionId)).workDeviations
|
|
2078
2080
|
.filter((deviation) => (deviation.state === "approved" || deviation.state === "active")
|
|
2079
2081
|
&& deviation.temporaryTaskId === found.task.id)
|
|
2080
2082
|
.sort((left, right) => right.createdAt.localeCompare(left.createdAt))[0];
|
|
@@ -2108,7 +2110,7 @@ server.registerTool("planner-task-switch", {
|
|
|
2108
2110
|
}, async ({ from_task, to_task, reason, what_was_being_done, resume_location, how_to_resume, switched_by }, extra) => {
|
|
2109
2111
|
const plannerSessionId = plannerSessionIdFor(extra);
|
|
2110
2112
|
const st = await requireStore();
|
|
2111
|
-
const [featuresDoc, phases, project, focus] = await Promise.all([st.loadFeatures(), st.loadAllPhases(), st.loadProject(), st.loadResume()]);
|
|
2113
|
+
const [featuresDoc, phases, project, focus] = await Promise.all([st.loadFeatures(), st.loadAllPhases(), st.loadProject(plannerSessionId), st.loadResume(plannerSessionId)]);
|
|
2112
2114
|
const features = featuresDoc.features;
|
|
2113
2115
|
const source = findTaskByRef(phases, features, from_task);
|
|
2114
2116
|
const target = findTaskByRef(phases, features, to_task);
|
|
@@ -2172,7 +2174,7 @@ server.registerTool("planner-task-switch", {
|
|
|
2172
2174
|
resumeLocation: resume_location, howToResume: how_to_resume,
|
|
2173
2175
|
relatedTaskId: target.task.id, pausedAt: timestamp, pausedBy: switched_by?.trim() ?? "",
|
|
2174
2176
|
};
|
|
2175
|
-
const selection = recommendNextTask(features, phases,
|
|
2177
|
+
const selection = recommendNextTask(features, phases, await st.listAllWorkDeviations(), focus?.currentPhaseId, plannerSessionId);
|
|
2176
2178
|
const record = {
|
|
2177
2179
|
id: crypto.randomUUID(), recommendedTaskId: selection.candidate?.task.id ?? source.task.id,
|
|
2178
2180
|
temporaryTaskId: target.task.id, resumeTaskId: source.task.id, reason, snapshot,
|
|
@@ -2222,7 +2224,7 @@ server.registerTool("planner-task-switch", {
|
|
|
2222
2224
|
});
|
|
2223
2225
|
}
|
|
2224
2226
|
targetStarted = true;
|
|
2225
|
-
await st.addWorkDeviation(record);
|
|
2227
|
+
await st.addWorkDeviation(record, plannerSessionId);
|
|
2226
2228
|
if (target.task.pauseSnapshot) {
|
|
2227
2229
|
const resumedDeviation = project.workDeviations
|
|
2228
2230
|
.filter((deviation) => deviation.resumeTaskId === target.task.id
|
|
@@ -2306,7 +2308,7 @@ server.registerTool("planner-task-start", {
|
|
|
2306
2308
|
const featureRef = parentFeature ? formatFeatureRef(parentFeature.number) : "";
|
|
2307
2309
|
if (found.task.status === "done")
|
|
2308
2310
|
return taskStartError(taskStartDenied("TASK_DONE", `Task ${taskRef} is done and was not reopened.`, [`Use planner-task-reopen with task=${taskRef} and confirmed=true after explicit user confirmation.`, `Retry planner-task-start ${taskRef} only if reopening is not the intended operation.`], { taskId: found.task.id }));
|
|
2309
|
-
const project = await st.loadProject();
|
|
2311
|
+
const project = await st.loadProject(plannerSessionId);
|
|
2310
2312
|
// Targeted stale-context refresh (P102(F005)/T404): task-start delivery
|
|
2311
2313
|
// stays scoped to feature/phase/task context, but a session that already
|
|
2312
2314
|
// did a full planner-load gets a non-blocking advisory when project-level
|
|
@@ -2350,11 +2352,11 @@ server.registerTool("planner-task-start", {
|
|
|
2350
2352
|
const phaseOrderAdvisory = higherPriorityOpenPhaseAdvisory(higherPriorityPhase);
|
|
2351
2353
|
return text(`✅ Task already started: ${taskRef} — ${found.task.title} (in-progress)\nstarted: true${projectContextAdvisory}${phaseOrderAdvisory}`, { ...outcome, task: found.task, projectContextStale: projectContextReadState === "stale", higherPriorityOpenPhase: higherPriorityPhase });
|
|
2352
2354
|
}
|
|
2353
|
-
const [phases, focus] = await Promise.all([st.loadAllPhases(), st.loadResume()]);
|
|
2355
|
+
const [phases, focus] = await Promise.all([st.loadAllPhases(), st.loadResume(plannerSessionId)]);
|
|
2354
2356
|
const eligibility = checkExplicitTaskStart(features, phases, found.task.id, project.workDeviations);
|
|
2355
2357
|
if (!eligibility.eligible)
|
|
2356
2358
|
return taskStartError(taskStartDenied("START_NOT_ALLOWED", eligibility.reason, ["Resolve the reported task readiness condition, then retry planner-task-start."], { taskId: found.task.id }), { eligibility });
|
|
2357
|
-
const selection = recommendNextTask(features, phases,
|
|
2359
|
+
const selection = recommendNextTask(features, phases, await st.listAllWorkDeviations(), focus?.currentPhaseId, plannerSessionId);
|
|
2358
2360
|
if (selection.kind === "conflict") {
|
|
2359
2361
|
return taskStartError(taskStartDenied("ACTIVE_TASK_CONFLICT", selection.reason, ["Pause or reconcile the active tasks.", `Retry planner-task-start ${taskRef}.`], { taskId: found.task.id }), { selection });
|
|
2360
2362
|
}
|
|
@@ -2464,7 +2466,8 @@ server.registerTool("planner-task-complete", {
|
|
|
2464
2466
|
motivation: z.string().optional().describe("Required when force=true overrides unchecked checklist items: why the checklist no longer matches the work."),
|
|
2465
2467
|
description_update: z.string().min(10).describe("Required evidence: shipped work, verification level including partial verification, remaining/unverified work, files, decisions, and updated code references."),
|
|
2466
2468
|
},
|
|
2467
|
-
}, async ({ task: ref, force, motivation, description_update }) => {
|
|
2469
|
+
}, async ({ task: ref, force, motivation, description_update }, extra) => {
|
|
2470
|
+
const plannerSessionId = plannerSessionIdFor(extra);
|
|
2468
2471
|
const st = await requireStore();
|
|
2469
2472
|
const found = findTaskByRef(await st.loadAllPhases(), (await st.loadFeatures()).features, ref);
|
|
2470
2473
|
if (!found)
|
|
@@ -2510,7 +2513,7 @@ server.registerTool("planner-task-complete", {
|
|
|
2510
2513
|
return phase;
|
|
2511
2514
|
});
|
|
2512
2515
|
const clearedRef = await st.syncTaskStatusRollup(found.phase.id);
|
|
2513
|
-
const completedDeviation = (await st.loadProject()).workDeviations
|
|
2516
|
+
const completedDeviation = (await st.loadProject(plannerSessionId)).workDeviations
|
|
2514
2517
|
.filter((deviation) => (deviation.state === "approved" || deviation.state === "active") && deviation.temporaryTaskId === found.task.id)
|
|
2515
2518
|
.sort((left, right) => right.createdAt.localeCompare(left.createdAt))[0];
|
|
2516
2519
|
if (completedDeviation)
|
|
@@ -3167,7 +3170,7 @@ server.registerTool("planner-load", {
|
|
|
3167
3170
|
const plannerSkill = await st.syncPlannerSkill();
|
|
3168
3171
|
await st.syncGrillMeSkill();
|
|
3169
3172
|
const web = await ensureWebStarted();
|
|
3170
|
-
const recap = await buildRecap(st, web, { harness: "mcp" });
|
|
3173
|
+
const recap = await buildRecap(st, web, { harness: "mcp", sessionId: plannerSessionId });
|
|
3171
3174
|
const plan = await st.loadAll();
|
|
3172
3175
|
// Explicit planner load must deliver the complete project-level context
|
|
3173
3176
|
// (P102(F005)/T404), attested through the same lossless contract used
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-plan/mcp",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
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/
|
|
47
|
-
"@agent-plan/
|
|
46
|
+
"@agent-plan/server": "0.4.2",
|
|
47
|
+
"@agent-plan/core": "0.4.2"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "tsc -p tsconfig.json",
|