@mandujs/mcp 0.9.18 → 0.9.19

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/tools/slot.ts +3 -199
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mandujs/mcp",
3
- "version": "0.9.18",
3
+ "version": "0.9.19",
4
4
  "description": "Mandu MCP Server - Agent-native interface for Mandu framework operations",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
package/src/tools/slot.ts CHANGED
@@ -3,12 +3,10 @@ import {
3
3
  loadManifest,
4
4
  validateSlotContent,
5
5
  correctSlotContent,
6
- runSlotCorrection,
7
6
  summarizeValidationIssues,
8
7
  } from "@mandujs/core";
9
8
  import { getProjectPaths, isInsideProject } from "../utils/project.js";
10
9
  import path from "path";
11
- import fs from "fs/promises";
12
10
 
13
11
  export const slotToolDefinitions: Tool[] = [
14
12
  {
@@ -25,40 +23,6 @@ export const slotToolDefinitions: Tool[] = [
25
23
  required: ["routeId"],
26
24
  },
27
25
  },
28
- {
29
- name: "mandu_write_slot",
30
- description:
31
- "Write or update the contents of a slot file with optional auto-correction",
32
- inputSchema: {
33
- type: "object",
34
- properties: {
35
- routeId: {
36
- type: "string",
37
- description: "The route ID whose slot file to write",
38
- },
39
- content: {
40
- type: "string",
41
- description: "The TypeScript content to write to the slot file",
42
- },
43
- autoCorrect: {
44
- type: "boolean",
45
- description:
46
- "If true, automatically fix correctable issues (default: false)",
47
- },
48
- maxRetries: {
49
- type: "number",
50
- description:
51
- "Maximum correction attempts when autoCorrect is true (default: 3)",
52
- },
53
- validateOnly: {
54
- type: "boolean",
55
- description:
56
- "If true, only validate without writing (default: false)",
57
- },
58
- },
59
- required: ["routeId", "content"],
60
- },
61
- },
62
26
  {
63
27
  name: "mandu_validate_slot",
64
28
  description:
@@ -141,166 +105,6 @@ export function slotTools(projectRoot: string) {
141
105
  }
142
106
  },
143
107
 
144
- mandu_write_slot: async (args: Record<string, unknown>) => {
145
- const {
146
- routeId,
147
- content,
148
- autoCorrect = false,
149
- maxRetries = 3,
150
- validateOnly = false,
151
- } = args as {
152
- routeId: string;
153
- content: string;
154
- autoCorrect?: boolean;
155
- maxRetries?: number;
156
- validateOnly?: boolean;
157
- };
158
-
159
- // Load manifest to find the route
160
- const manifestResult = await loadManifest(paths.manifestPath);
161
- if (!manifestResult.success || !manifestResult.data) {
162
- return { error: manifestResult.errors };
163
- }
164
-
165
- const route = manifestResult.data.routes.find((r) => r.id === routeId);
166
- if (!route) {
167
- return { error: `Route not found: ${routeId}` };
168
- }
169
-
170
- if (!route.slotModule) {
171
- return {
172
- error: `Route '${routeId}' does not have a slotModule defined`,
173
- tip: "Add slotModule to the route spec first",
174
- };
175
- }
176
-
177
- const slotPath = path.join(projectRoot, route.slotModule);
178
-
179
- // Security check
180
- if (!isInsideProject(slotPath, projectRoot)) {
181
- return { error: "Slot path is outside project directory" };
182
- }
183
-
184
- // 1. 초기 검증
185
- const initialValidation = validateSlotContent(content);
186
-
187
- // validateOnly 모드면 검증 결과만 반환
188
- if (validateOnly) {
189
- return {
190
- validateOnly: true,
191
- valid: initialValidation.valid,
192
- summary: summarizeValidationIssues(initialValidation.issues),
193
- issues: initialValidation.issues,
194
- tip: initialValidation.valid
195
- ? "Content is valid and ready to write"
196
- : "Fix the issues and try again, or use autoCorrect: true",
197
- };
198
- }
199
-
200
- // 2. autoCorrect 모드
201
- let finalContent = content;
202
- let correctionResult = null;
203
-
204
- if (autoCorrect && !initialValidation.valid) {
205
- correctionResult = await runSlotCorrection(
206
- content,
207
- validateSlotContent,
208
- maxRetries
209
- );
210
- finalContent = correctionResult.finalContent;
211
-
212
- // 여전히 에러가 있으면 쓰기 거부
213
- if (!correctionResult.success) {
214
- const errors = correctionResult.remainingIssues.filter(
215
- (i) => i.severity === "error"
216
- );
217
- if (errors.length > 0) {
218
- return {
219
- success: false,
220
- autoCorrectAttempted: true,
221
- attempts: correctionResult.attempts,
222
- appliedFixes: correctionResult.allFixes,
223
- remainingErrors: errors,
224
- summary: `${correctionResult.allFixes.length}개 문제 수정, ${errors.length}개 에러 남음`,
225
- tip: "수동으로 수정이 필요한 에러가 있습니다",
226
- suggestedContent: finalContent, // 부분적으로 수정된 내용 제공
227
- };
228
- }
229
- }
230
- } else if (!autoCorrect && !initialValidation.valid) {
231
- // autoCorrect 없이 에러가 있으면 경고와 함께 진행 여부 결정
232
- const errors = initialValidation.issues.filter(
233
- (i) => i.severity === "error"
234
- );
235
- if (errors.length > 0) {
236
- return {
237
- success: false,
238
- valid: false,
239
- errors,
240
- summary: summarizeValidationIssues(initialValidation.issues),
241
- tip: "Use autoCorrect: true to attempt automatic fixes, or fix manually",
242
- autoFixable: initialValidation.issues
243
- .filter((i) => i.autoFixable)
244
- .map((i) => i.code),
245
- };
246
- }
247
- }
248
-
249
- // 3. 파일 쓰기
250
- try {
251
- // Ensure directory exists
252
- const slotDir = path.dirname(slotPath);
253
- await fs.mkdir(slotDir, { recursive: true });
254
-
255
- // Check if file exists (for backup/warning)
256
- const file = Bun.file(slotPath);
257
- const existed = await file.exists();
258
- let previousContent: string | null = null;
259
-
260
- if (existed) {
261
- previousContent = await file.text();
262
- }
263
-
264
- // Write the new content
265
- await Bun.write(slotPath, finalContent);
266
-
267
- // 최종 검증
268
- const finalValidation = validateSlotContent(finalContent);
269
-
270
- const result: Record<string, unknown> = {
271
- success: true,
272
- slotPath: route.slotModule,
273
- action: existed ? "updated" : "created",
274
- lineCount: finalContent.split("\n").length,
275
- previousLineCount: previousContent
276
- ? previousContent.split("\n").length
277
- : null,
278
- validation: {
279
- valid: finalValidation.valid,
280
- summary: summarizeValidationIssues(finalValidation.issues),
281
- warnings: finalValidation.issues.filter(
282
- (i) => i.severity === "warning"
283
- ),
284
- },
285
- };
286
-
287
- // autoCorrect 결과 추가
288
- if (correctionResult) {
289
- result.autoCorrection = {
290
- applied: true,
291
- attempts: correctionResult.attempts,
292
- fixes: correctionResult.allFixes,
293
- };
294
- }
295
-
296
- return result;
297
- } catch (error) {
298
- return {
299
- error: `Failed to write slot file: ${error instanceof Error ? error.message : String(error)}`,
300
- };
301
- }
302
- },
303
-
304
108
  mandu_validate_slot: async (args: Record<string, unknown>) => {
305
109
  const { content } = args as { content: string };
306
110
 
@@ -342,10 +146,10 @@ export function slotTools(projectRoot: string) {
342
146
  })),
343
147
  correctionPreview,
344
148
  tip: validation.valid
345
- ? "Content is valid"
149
+ ? "Content is valid. Use Edit tool to write the slot file."
346
150
  : autoFixable.length > 0
347
- ? "Use mandu_write_slot with autoCorrect: true to auto-fix"
348
- : "Manual fixes required before writing",
151
+ ? "Auto-fixable issues found. Apply corrections and use Edit tool to write."
152
+ : "Manual fixes required before writing. Use Edit tool after fixing.",
349
153
  };
350
154
  },
351
155
  };