@agent-plan/mcp 0.3.0 → 0.3.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 +19 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +83 -39
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
type ToolResult = {
|
|
3
|
+
content: Array<{
|
|
4
|
+
type: "text";
|
|
5
|
+
text: string;
|
|
6
|
+
}>;
|
|
7
|
+
structuredContent?: Record<string, unknown>;
|
|
8
|
+
isError?: boolean;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Claude Code gives the agent only `structuredContent` when a result has
|
|
12
|
+
* one, and drops `content[].text`. Anything a tool says in text — a handoff
|
|
13
|
+
* body, a phase work map, task-start context, an advisory — would never
|
|
14
|
+
* reach the agent. So every result with a structured part also carries its
|
|
15
|
+
* text there, as `text`. `content` keeps the text for clients that read
|
|
16
|
+
* only that. Applied once, to every tool, by the registerTool wrapper below;
|
|
17
|
+
* no handler needs to know.
|
|
18
|
+
*/
|
|
19
|
+
export declare function foldTextIntoStructured<T extends ToolResult>(result: T): T;
|
|
2
20
|
export declare function startStdioServer(): Promise<void>;
|
|
21
|
+
export {};
|
|
3
22
|
//# sourceMappingURL=index.d.ts.map
|
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":";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;AA83FD,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAItD"}
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import * as z from "zod/v4";
|
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
7
7
|
import { pathToFileURL } from "node:url";
|
|
8
|
-
import { PlanStore, PlanStoreError, ExportService, withFeatureLock, needsMotivation, findPhaseByRef, findTaskByRef, findIdeaByRef, buildRecap, addChecklistItem, removeChecklistItem, toggleChecklistItem, replaceChecklist, buildPhaseContextBlock, buildPhaseWorkMap, buildBoundedAcceptedDecisionContext, renderAcceptedDecisionsSection, checkExplicitTaskStart, recommendNextTask, recommendNextWork, buildResumeRequiredProposal, packageVersionFromModule, resolvedPackageVersion, runtimeCapabilities, runtimePackagesDiagnostic, markCanonicalFullReadForSessionId, contextReadEligibilityForSession, requirementReadEligibilityForSession, hasValidSessionAttestation, markRequirementReadForSessionId, startReadSession, invalidateReads, taskStartDenied, taskStartSucceeded, taskStartGateState, taskStartGateStateLine, noMutableFieldsReceived, normalizeDescriptionRef, projectGuidelinesReadStateForSession, reconcileRequirementMacroTasks, RequirementMacroTaskError, HANDOFF_COMPLETENESS_AUDIT_VERSION, HANDOFF_COMPLETENESS_CATEGORIES, HANDOFF_COLD_START_INVENTORY_VERSION, HANDOFF_COLD_START_INVENTORY_CATEGORIES, HandoffContractError, buildHandoffShowReply, buildHandoffPrepareReply, buildProjectContextLoadReply, DEFAULT_PROJECT_CONTEXT_CHUNK_CHARS, projectContextStaleAdvisory, LEGACY_DECISIONS_ARRAY_READ_ONLY_MESSAGE, LEGACY_DECISIONS_ARRAY_READ_ONLY_ERROR_CODE, buildMutationReply, longTextFieldLimitNotice, buildRecommendationReply, buildTaskOrderContext, taskOrderContextLine, taskCreatedPriorityFragment, findHigherPriorityOpenPhase, higherPriorityOpenPhaseAdvisory, listOpenPhaseWork, openPhaseWorkLines, boundedOpenPhaseWork, deleteFeatureCascade, evaluateTaskCompletionGate, taskCompletionChecklistRefusal, taskCompletionForceMotivationRequired, taskCompletionOverrideNote, taskCompletionMismatchLine, boundedPage, nowISO, resolveFeatureRefStrict, resolveAcceptedDecisionTarget, applyTaskLifecycleDates, handoffContractFailureReply, derivedStatusReadOnlyReply, acceptedDecisionMutationFailureReply, legacyContextMigrationSummary } from "@agent-plan/core";
|
|
8
|
+
import { PlanStore, PlanStoreError, ExportService, withFeatureLock, needsMotivation, findPhaseByRef, findTaskByRef, findIdeaByRef, buildRecap, addChecklistItem, removeChecklistItem, toggleChecklistItem, replaceChecklist, buildPhaseContextBlock, buildPhaseWorkMap, buildBoundedAcceptedDecisionContext, renderAcceptedDecisionsSection, checkExplicitTaskStart, recommendNextTask, recommendNextWork, buildResumeRequiredProposal, packageVersionFromModule, resolvedPackageVersion, createStaleProcessCheck, runtimeCapabilities, runtimePackagesDiagnostic, markCanonicalFullReadForSessionId, contextReadEligibilityForSession, requirementReadEligibilityForSession, hasValidSessionAttestation, markRequirementReadForSessionId, startReadSession, invalidateReads, taskStartDenied, taskStartSucceeded, taskStartGateState, taskStartGateStateLine, noMutableFieldsReceived, normalizeDescriptionRef, projectGuidelinesReadStateForSession, reconcileRequirementMacroTasks, RequirementMacroTaskError, HANDOFF_COMPLETENESS_AUDIT_VERSION, HANDOFF_COMPLETENESS_CATEGORIES, HANDOFF_COLD_START_INVENTORY_VERSION, HANDOFF_COLD_START_INVENTORY_CATEGORIES, HandoffContractError, buildHandoffShowReply, buildHandoffPrepareReply, buildProjectContextLoadReply, buildPlannerLoadReply, buildScopedDecisionContext, DEFAULT_PROJECT_CONTEXT_CHUNK_CHARS, projectContextStaleAdvisory, LEGACY_DECISIONS_ARRAY_READ_ONLY_MESSAGE, LEGACY_DECISIONS_ARRAY_READ_ONLY_ERROR_CODE, buildMutationReply, longTextFieldLimitNotice, buildRecommendationReply, buildTaskOrderContext, taskOrderContextLine, taskCreatedPriorityFragment, findHigherPriorityOpenPhase, higherPriorityOpenPhaseAdvisory, listOpenPhaseWork, openPhaseWorkLines, boundedOpenPhaseWork, deleteFeatureCascade, evaluateTaskCompletionGate, taskCompletionChecklistRefusal, taskCompletionForceMotivationRequired, taskCompletionOverrideNote, taskCompletionMismatchLine, boundedPage, nowISO, resolveFeatureRefStrict, resolveAcceptedDecisionTarget, applyTaskLifecycleDates, handoffContractFailureReply, derivedStatusReadOnlyReply, acceptedDecisionMutationFailureReply, legacyContextMigrationSummary, moveTasks, buildTaskMoveReply } from "@agent-plan/core";
|
|
9
9
|
import { serve } from "@agent-plan/server";
|
|
10
10
|
import { createChecklistItemId, createFeatureId, createPhaseId, createRequirementId, createTaskId, clampSlug, normalizeSlug, formatPhaseRef, formatFeatureRef, formatIdeaRef, featureNumberOfPhase, validateResolvedTarget } from "@agent-plan/core/naming";
|
|
11
11
|
const STATUS_VALUES = ["planned", "in-progress", "done", "blocked", "canceled", "rejected", "deferred", "waiting"];
|
|
@@ -83,6 +83,7 @@ function mcpContextReadActions(eligibility, refs, projectGuidelinesReadRequired,
|
|
|
83
83
|
}
|
|
84
84
|
const MCP_PACKAGE = packageVersionFromModule(import.meta.url, "@agent-plan/mcp");
|
|
85
85
|
const CORE_PACKAGE = resolvedPackageVersion("@agent-plan/core", import.meta.url);
|
|
86
|
+
const staleServerNotice = createStaleProcessCheck(MCP_PACKAGE);
|
|
86
87
|
function planRoot() {
|
|
87
88
|
return process.env.AGENT_PLAN_ROOT || join(process.cwd(), ".planner");
|
|
88
89
|
}
|
|
@@ -169,6 +170,44 @@ const server = new McpServer({
|
|
|
169
170
|
name: "agent-plan-planner",
|
|
170
171
|
version: MCP_PACKAGE.version,
|
|
171
172
|
});
|
|
173
|
+
/**
|
|
174
|
+
* Claude Code gives the agent only `structuredContent` when a result has
|
|
175
|
+
* one, and drops `content[].text`. Anything a tool says in text — a handoff
|
|
176
|
+
* body, a phase work map, task-start context, an advisory — would never
|
|
177
|
+
* reach the agent. So every result with a structured part also carries its
|
|
178
|
+
* text there, as `text`. `content` keeps the text for clients that read
|
|
179
|
+
* only that. Applied once, to every tool, by the registerTool wrapper below;
|
|
180
|
+
* no handler needs to know.
|
|
181
|
+
*/
|
|
182
|
+
export function foldTextIntoStructured(result) {
|
|
183
|
+
if (!result?.structuredContent)
|
|
184
|
+
return result;
|
|
185
|
+
const replyText = result.content
|
|
186
|
+
.filter((part) => part.type === "text" && typeof part.text === "string")
|
|
187
|
+
.map((part) => part.text)
|
|
188
|
+
.join("\n\n");
|
|
189
|
+
// A reply that already uses `text` for something else is left as it is;
|
|
190
|
+
// the MCP tests fail on that, so it never ships.
|
|
191
|
+
if (!replyText || "text" in result.structuredContent)
|
|
192
|
+
return result;
|
|
193
|
+
return { ...result, structuredContent: { text: replyText, ...result.structuredContent } };
|
|
194
|
+
}
|
|
195
|
+
/** Add one line to a reply when this server is older than what is now
|
|
196
|
+
* installed (see createStaleProcessCheck). */
|
|
197
|
+
function withStaleServerNotice(result) {
|
|
198
|
+
const notice = staleServerNotice();
|
|
199
|
+
if (!notice || !result?.content)
|
|
200
|
+
return result;
|
|
201
|
+
return { ...result, content: [...result.content, { type: "text", text: notice }] };
|
|
202
|
+
}
|
|
203
|
+
{
|
|
204
|
+
const registerToolUnwrapped = server.registerTool.bind(server);
|
|
205
|
+
server.registerTool = (...args) => {
|
|
206
|
+
const handler = args[args.length - 1];
|
|
207
|
+
const wrapped = async (...handlerArgs) => foldTextIntoStructured(withStaleServerNotice(await handler(...handlerArgs)));
|
|
208
|
+
return registerToolUnwrapped(...args.slice(0, -1), wrapped);
|
|
209
|
+
};
|
|
210
|
+
}
|
|
172
211
|
async function resolveRequirementPhaseRefs(st, refs) {
|
|
173
212
|
if (!refs || refs.length === 0)
|
|
174
213
|
return { ok: false, error: "linkedPhaseIds must contain at least one phase reference." };
|
|
@@ -235,7 +274,7 @@ server.registerTool("planner-export", {
|
|
|
235
274
|
return text(`Project export generated. Summary results:\n\n${markdown.slice(0, 1000)}${markdown.length > 1000 ? "... (full report in .planner/EXPORT.md)" : ""}`);
|
|
236
275
|
});
|
|
237
276
|
server.registerTool("planner-authorize-bypass", {
|
|
238
|
-
description: "Authorize a temporary guard bypass (default 15 minutes)
|
|
277
|
+
description: "Authorize a temporary guard bypass (default 15 minutes) that silences the no-task warning. Edits are never blocked; this only stops the agent being warned when it changes project code with no task in-progress. Use ONLY after the user explicitly authorizes working without a task. Harness-agnostic: stored in resume.json so all adapters (Pi, Claude Code, Codex, ...) respect it.",
|
|
239
278
|
inputSchema: {
|
|
240
279
|
durationMinutes: z.number().optional().describe("Bypass window in minutes. Default 15."),
|
|
241
280
|
},
|
|
@@ -1610,7 +1649,7 @@ server.registerTool("planner-task-discuss", {
|
|
|
1610
1649
|
return writeAndSummarize(st, taskDiscussReply.text, taskDiscussReply.structured);
|
|
1611
1650
|
});
|
|
1612
1651
|
server.registerTool("planner-task-dependency-add", {
|
|
1613
|
-
description: "Add a validated task dependency atomically;
|
|
1652
|
+
description: "Add a validated task dependency atomically. A task may depend on any task in any phase; the dependency is rejected only when the target does not exist, is the task itself, or would create a cycle.",
|
|
1614
1653
|
inputSchema: { task: z.string().min(1), dependsOn: z.string().min(1) },
|
|
1615
1654
|
}, async ({ task: ref, dependsOn }) => {
|
|
1616
1655
|
const st = await requireStore();
|
|
@@ -1812,6 +1851,32 @@ server.registerTool("planner-task-update", {
|
|
|
1812
1851
|
});
|
|
1813
1852
|
return writeAndSummarize(st, taskUpdateReply.text, taskUpdateReply.structured);
|
|
1814
1853
|
});
|
|
1854
|
+
server.registerTool("planner-task-move", {
|
|
1855
|
+
description: "Move one or more tasks to a different phase, atomically, without recreating them: id, number, shortId, status, statusLog, checklist, subtasks, acceptedDecisions, pause history, notes, description and dependsOn all survive — only the composite ref changes. Every other task's dependsOn keeps resolving (ids never change). An in-progress task may move. Refused into a terminal (done/canceled/rejected) target phase. Costs almost nothing regardless of task size: pass refs only, never task text; the reply echoes only old ref → new ref, id/shortId/title/status per task.",
|
|
1856
|
+
inputSchema: {
|
|
1857
|
+
tasks: z.array(z.string().min(1)).min(1).describe("Task refs to move. Accepts F00x/P00x/T00x composite, bare T00x (global), 5-char shortId, UUID, or title."),
|
|
1858
|
+
targetPhase: z.string().min(1).describe("Destination phase ref. Accepts F00x/P00x, bare P00x, 5-char shortId, UUID, or title."),
|
|
1859
|
+
},
|
|
1860
|
+
}, async ({ tasks: refs, targetPhase: targetRef }) => {
|
|
1861
|
+
const st = await requireStore();
|
|
1862
|
+
const phases = await st.loadAllPhases();
|
|
1863
|
+
const features = (await st.loadFeatures()).features;
|
|
1864
|
+
const target = findPhaseByRef(phases, features, targetRef);
|
|
1865
|
+
if (!target)
|
|
1866
|
+
return { ...text(`Target phase not found: ${targetRef}`, { moved: false, errorCode: "TARGET_PHASE_NOT_FOUND" }), isError: true };
|
|
1867
|
+
const foundTasks = [];
|
|
1868
|
+
for (const ref of refs) {
|
|
1869
|
+
const found = findTaskByRef(phases, features, ref);
|
|
1870
|
+
if (!found)
|
|
1871
|
+
return { ...text(`Task not found: ${ref}`, { moved: false, errorCode: "TASK_NOT_FOUND" }), isError: true };
|
|
1872
|
+
foundTasks.push(found);
|
|
1873
|
+
}
|
|
1874
|
+
const outcome = await moveTasks(st, foundTasks.map((entry) => entry.task.id), target.id);
|
|
1875
|
+
if (!outcome.ok)
|
|
1876
|
+
return { ...text(`❌ ${outcome.error}`, { moved: false, errorCode: outcome.errorCode }), isError: true };
|
|
1877
|
+
const reply = buildTaskMoveReply(outcome.result, `planner-task-show ${outcome.result.targetPhaseRef} full=true`);
|
|
1878
|
+
return writeAndSummarize(st, reply.text, reply.structured);
|
|
1879
|
+
});
|
|
1815
1880
|
server.registerTool("planner-task-checklist-toggle", {
|
|
1816
1881
|
description: "Tick/untick a task checklist item (a 'step') without rewriting the whole list. Accepts the item as C{n} (e.g. C2), the item id, or the title (case-insensitive, first match). Pass checked=true/false to set explicitly, or omit to toggle. Use this instead of writing DONE in step titles. Items are numbered C1/C2… per task.",
|
|
1817
1882
|
inputSchema: {
|
|
@@ -3079,7 +3144,7 @@ server.registerTool("planner-web", {
|
|
|
3079
3144
|
return text("planner-web not running. Use planner-web with action=start to start the dashboard.", { running: false, address: "", localUrl: "", lanUrl: "", host: "", port: 0, mode: "" });
|
|
3080
3145
|
});
|
|
3081
3146
|
server.registerTool("planner-load", {
|
|
3082
|
-
description: "Load/refresh the planner on explicit user request (NOT automatic): starts the web dashboard on LAN and returns a
|
|
3147
|
+
description: "Load/refresh the planner on explicit user request (NOT automatic): starts the web dashboard on LAN and returns one text with, in order: a recap under '## Recap — show this to the user verbatim', then agent-only context under '## Agent-only context' (the complete project-level context — description, goal, scope, out-of-scope, technologies, tools, language preferences, Project Guidelines, every Requirement, every project Accepted Decision — then Accepted Decisions of features, phases and tasks, then where the Agent Plan operating guide lives). Call it ONLY when the user runs /planner load or /planner recap (or asks to load the planner). Show the user ONLY the recap section, verbatim, including its final Web UI line; never quote the agent-only context. If structuredContent.projectContext.contextComplete is false, the project-level context was NOT delivered — follow structuredContent.projectContext.nextActions and retry before relying on it. A pending handoff is read-only context: NEVER call planner-handoff-show or planner-handoff-clear as part of load/recap. Archive it only when every phase task is done/canceled, when replacing it with a new handoff, or after an explicit user handoff-clear request. Do NOT start the planner/web or show the web URL unless the user explicitly asks (load/recap/web status).",
|
|
3083
3148
|
inputSchema: {
|
|
3084
3149
|
maxChars: z.number().int().positive().optional().describe(`Single-response bound (chars) for the project-context delivery. Default ${DEFAULT_PROJECT_CONTEXT_CHUNK_CHARS}. Raise this and retry if a prior call returned projectContext.contextComplete=false.`),
|
|
3085
3150
|
},
|
|
@@ -3104,50 +3169,29 @@ server.registerTool("planner-load", {
|
|
|
3104
3169
|
const web = await ensureWebStarted();
|
|
3105
3170
|
const recap = await buildRecap(st, web, { harness: "mcp" });
|
|
3106
3171
|
const plan = await st.loadAll();
|
|
3107
|
-
const acceptedDecisionContext = buildBoundedAcceptedDecisionContext([
|
|
3108
|
-
{ scope: "project", decisions: plan.project.acceptedDecisions },
|
|
3109
|
-
...plan.features.features.map((feature) => ({ scope: `feature ${formatFeatureRef(feature.number)}`, decisions: feature.acceptedDecisions })),
|
|
3110
|
-
...plan.phases.map((phase) => ({ scope: `phase ${formatPhaseRef(phase.number, featureNumberOfPhase(phase, plan.features.features))}`, decisions: phase.acceptedDecisions })),
|
|
3111
|
-
...plan.phases.flatMap((phase) => phase.tasks.map((task) => ({
|
|
3112
|
-
scope: `task ${taskCompositeRef(task, phase, plan.features.features)}`,
|
|
3113
|
-
decisions: task.acceptedDecisions,
|
|
3114
|
-
}))),
|
|
3115
|
-
]);
|
|
3116
3172
|
// Explicit planner load must deliver the complete project-level context
|
|
3117
3173
|
// (P102(F005)/T404), attested through the same lossless contract used
|
|
3118
3174
|
// everywhere else: loadProjectContextDelivery + recordProjectContextRead.
|
|
3119
|
-
// buildProjectContextLoadReply is the single shared shaping for this reply
|
|
3120
|
-
// (Pi's planner-load and /planner load use the identical builder).
|
|
3121
3175
|
const boundedMaxChars = maxChars ?? DEFAULT_PROJECT_CONTEXT_CHUNK_CHARS;
|
|
3122
3176
|
const projectContextDelivery = await st.loadProjectContextDelivery(boundedMaxChars);
|
|
3123
3177
|
const projectContextReply = buildProjectContextLoadReply(projectContextDelivery, boundedMaxChars);
|
|
3124
3178
|
if (projectContextReply.structured.contextComplete) {
|
|
3125
3179
|
await st.recordProjectContextRead({ sessionId: plannerSessionId, chunks: projectContextDelivery.chunks });
|
|
3126
3180
|
}
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
content: plannerSkill.content,
|
|
3142
|
-
status: plannerSkill.status,
|
|
3143
|
-
customized: plannerSkill.customized,
|
|
3144
|
-
message: plannerSkill.message,
|
|
3145
|
-
instruction: "Read and retain this project-local planner usage skill, project context, and Accepted Decision context. Do not quote it, the project context, or the Accepted Decision context in the human-facing recap.",
|
|
3146
|
-
projectContext: { text: projectContextReply.text },
|
|
3147
|
-
acceptedDecisions: acceptedDecisionContext,
|
|
3148
|
-
},
|
|
3149
|
-
},
|
|
3150
|
-
};
|
|
3181
|
+
// One text, each piece once (shared with Pi via buildPlannerLoadReply).
|
|
3182
|
+
// The guide body is not resent: the /planner command already carries it,
|
|
3183
|
+
// and a bare planner-load call is pointed at the project-local copy.
|
|
3184
|
+
const reply = buildPlannerLoadReply({
|
|
3185
|
+
recap: preparation.changed ? `${preparation.legacyProjectContext.summary}\n\n${recap}` : recap,
|
|
3186
|
+
projectContext: projectContextReply,
|
|
3187
|
+
scopedDecisions: buildScopedDecisionContext(plan),
|
|
3188
|
+
plannerGuide: { mode: "pointer", path: ".planner/SKILL.md", customized: plannerSkill.customized, message: plannerSkill.message },
|
|
3189
|
+
});
|
|
3190
|
+
return text(reply.text, {
|
|
3191
|
+
...reply.structured,
|
|
3192
|
+
webUi: plannerWebMetadata(web),
|
|
3193
|
+
preparation: preparation.legacyProjectContext,
|
|
3194
|
+
});
|
|
3151
3195
|
});
|
|
3152
3196
|
server.registerTool("planner-disable", {
|
|
3153
3197
|
description: "MCP no-op equivalent of Pi /planner disable. Stop the MCP process from the host to disable it.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-plan/mcp",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.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/core": "0.3.
|
|
47
|
-
"@agent-plan/server": "0.3.
|
|
46
|
+
"@agent-plan/core": "0.3.2",
|
|
47
|
+
"@agent-plan/server": "0.3.2"
|
|
48
48
|
},
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "tsc -p tsconfig.json",
|