@mandujs/mcp 0.16.0 โ†’ 0.17.1

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/README.md CHANGED
@@ -167,6 +167,17 @@ bunx @mandujs/mcp --root /path/to/project
167
167
  | `mandu_list_changes` | View change history |
168
168
  | `mandu_prune_history` | Clean old snapshots |
169
169
 
170
+ ### ATE (Automation Test Engine) ๐Ÿ†•
171
+
172
+ | Tool | Description |
173
+ |------|-------------|
174
+ | `mandu.ate.extract` | Extract interaction graph from codebase |
175
+ | `mandu.ate.generate` | Generate Playwright test scenarios |
176
+ | `mandu.ate.run` | Execute Playwright tests with artifacts |
177
+ | `mandu.ate.report` | Generate test summary report |
178
+ | `mandu.ate.heal` | Auto-suggest fixes for failed tests |
179
+ | `mandu.ate.impact` | Compute affected routes (subset testing) |
180
+
170
181
  ---
171
182
 
172
183
  ## Resources
@@ -323,6 +334,91 @@ Agent:
323
334
  โ†’ Stops watching
324
335
  ```
325
336
 
337
+ ### ATE E2E Testing Workflow
338
+
339
+ ```mermaid
340
+ graph TD
341
+ A[mandu.ate.extract] -->|interaction-graph.json| B[mandu.ate.generate]
342
+ B -->|Playwright specs| C[mandu.ate.run]
343
+ C -->|Test results| D{Success?}
344
+ D -->|Yes| E[mandu.ate.report]
345
+ D -->|No| F[mandu.ate.heal]
346
+ F -->|Suggestions| G[Apply fixes]
347
+ G --> C
348
+
349
+ H[mandu.ate.impact] -->|Affected routes| B
350
+
351
+ style A fill:#e1f5ff
352
+ style B fill:#e1f5ff
353
+ style C fill:#fff4e1
354
+ style D fill:#ffe1e1
355
+ style E fill:#e1ffe1
356
+ style F fill:#ffe1e1
357
+ style H fill:#f5e1ff
358
+ ```
359
+
360
+ **Example: Full ATE Pipeline**
361
+
362
+ ```typescript
363
+ // 1. Extract interaction graph
364
+ await mandu.ate.extract({
365
+ repoRoot: process.cwd(),
366
+ routeGlobs: ["app/**/page.tsx"]
367
+ });
368
+
369
+ // 2. Optional: Compute impact for subset testing
370
+ const impact = mandu.ate.impact({
371
+ repoRoot: process.cwd(),
372
+ base: "main",
373
+ head: "HEAD"
374
+ });
375
+
376
+ // 3. Generate test scenarios
377
+ mandu.ate.generate({
378
+ repoRoot: process.cwd(),
379
+ oracleLevel: "L1",
380
+ onlyRoutes: impact.selectedRoutes // Subset testing
381
+ });
382
+
383
+ // 4. Run tests
384
+ const result = await mandu.ate.run({
385
+ repoRoot: process.cwd(),
386
+ baseURL: "http://localhost:3333",
387
+ ci: true
388
+ });
389
+
390
+ // 5. Generate report
391
+ await mandu.ate.report({
392
+ repoRoot: process.cwd(),
393
+ runId: result.runId,
394
+ startedAt: result.startedAt,
395
+ finishedAt: result.finishedAt,
396
+ exitCode: result.exitCode,
397
+ oracleLevel: "L1"
398
+ });
399
+
400
+ // 6. Heal if failed
401
+ if (result.exitCode !== 0) {
402
+ const healing = mandu.ate.heal({
403
+ repoRoot: process.cwd(),
404
+ runId: result.runId
405
+ });
406
+
407
+ console.log("Healing suggestions:");
408
+ healing.suggestions.forEach(s => console.log(s.diff));
409
+ }
410
+ ```
411
+
412
+ **ATE Use Cases:**
413
+
414
+ - ๐Ÿค– **Agent-driven testing**: Claude Code generates and runs E2E tests
415
+ - ๐Ÿ”„ **Self-healing tests**: Auto-suggest selector fixes when tests fail
416
+ - ๐ŸŽฏ **Impact-based testing**: Run only tests affected by code changes
417
+ - ๐Ÿ“Š **Multi-oracle validation**: L0 (smoke) โ†’ L1 (structure) โ†’ L2 (behavior) โ†’ L3 (domain)
418
+ - ๐Ÿš€ **CI/CD ready**: GitHub Actions, GitLab CI integration
419
+
420
+ **Learn More**: [ATE MCP Integration Guide](../ate/docs/mcp-integration.md)
421
+
326
422
  ---
327
423
 
328
424
  ## Architecture Integration
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mandujs/mcp",
3
- "version": "0.16.0",
3
+ "version": "0.17.1",
4
4
  "description": "Mandu MCP Server - Agent-native interface for Mandu framework operations",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -33,7 +33,7 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@mandujs/core": "^0.16.0",
36
- "@mandujs/ate": "0.16.0",
36
+ "@mandujs/ate": "0.17.0",
37
37
  "@modelcontextprotocol/sdk": "^1.25.3"
38
38
  },
39
39
  "engines": {
package/src/tools/ate.ts CHANGED
@@ -1,5 +1,15 @@
1
1
  import type { Tool } from "@modelcontextprotocol/sdk/types.js";
2
- import { ateExtract, ateGenerate, ateRun, ateReport, ateHeal, ateImpact } from "@mandujs/ate";
2
+ import {
3
+ ateExtract,
4
+ ateGenerate,
5
+ ateRun,
6
+ ateReport,
7
+ ateHeal,
8
+ ateImpact,
9
+ runFullPipeline,
10
+ analyzeFeedback,
11
+ applyHeal,
12
+ } from "@mandujs/ate";
3
13
 
4
14
  export const ateToolDefinitions: Tool[] = [
5
15
  {
@@ -46,7 +56,7 @@ export const ateToolDefinitions: Tool[] = [
46
56
  },
47
57
  {
48
58
  name: "mandu.ate.report",
49
- description: "ATE: summary.json ์ƒ์„ฑ",
59
+ description: "ATE: ํ…Œ์ŠคํŠธ ๋ฆฌํฌํŠธ ์ƒ์„ฑ (JSON, HTML, ๋˜๋Š” both)",
50
60
  inputSchema: {
51
61
  type: "object",
52
62
  properties: {
@@ -56,6 +66,7 @@ export const ateToolDefinitions: Tool[] = [
56
66
  finishedAt: { type: "string" },
57
67
  exitCode: { type: "number" },
58
68
  oracleLevel: { type: "string", enum: ["L0", "L1", "L2", "L3"] },
69
+ format: { type: "string", enum: ["json", "html", "both"], description: "๋ฆฌํฌํŠธ ํฌ๋งท (๊ธฐ๋ณธ๊ฐ’: both)" },
59
70
  impact: {
60
71
  type: "object",
61
72
  properties: {
@@ -94,6 +105,63 @@ export const ateToolDefinitions: Tool[] = [
94
105
  required: ["repoRoot"],
95
106
  },
96
107
  },
108
+ {
109
+ name: "mandu.ate.auto_pipeline",
110
+ description: "ATE: ์ „์ฒด ํŒŒ์ดํ”„๋ผ์ธ ์ž๋™ ์‹คํ–‰ (Extract โ†’ Generate โ†’ Run โ†’ Report โ†’ Heal)",
111
+ inputSchema: {
112
+ type: "object",
113
+ properties: {
114
+ repoRoot: { type: "string" },
115
+ baseURL: { type: "string" },
116
+ oracleLevel: { type: "string", enum: ["L0", "L1", "L2", "L3"] },
117
+ ci: { type: "boolean" },
118
+ useImpactAnalysis: { type: "boolean" },
119
+ base: { type: "string" },
120
+ head: { type: "string" },
121
+ autoHeal: { type: "boolean" },
122
+ tsconfigPath: { type: "string" },
123
+ routeGlobs: { type: "array", items: { type: "string" } },
124
+ buildSalt: { type: "string" },
125
+ },
126
+ required: ["repoRoot"],
127
+ },
128
+ },
129
+ {
130
+ name: "mandu.ate.feedback",
131
+ description: "ATE: ํ…Œ์ŠคํŠธ ์‹คํŒจ ์›์ธ ๋ถ„์„ ๋ฐ heal ์ œ์•ˆ ํ‰๊ฐ€",
132
+ inputSchema: {
133
+ type: "object",
134
+ properties: {
135
+ repoRoot: { type: "string", description: "ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ" },
136
+ runId: { type: "string", description: "ํ…Œ์ŠคํŠธ ์‹คํ–‰ ID" },
137
+ autoApply: {
138
+ type: "boolean",
139
+ description: "์ž๋™ ์ ์šฉ ๊ฐ€๋Šฅ ์—ฌ๋ถ€ (selector-map๋งŒ ์•ˆ์ „)",
140
+ },
141
+ },
142
+ required: ["repoRoot", "runId"],
143
+ },
144
+ },
145
+ {
146
+ name: "mandu.ate.apply_heal",
147
+ description: "ATE: heal diff๋ฅผ ์‹ค์ œ ์ฝ”๋“œ์— ์ ์šฉ (rollback ๊ฐ€๋Šฅ)",
148
+ inputSchema: {
149
+ type: "object",
150
+ properties: {
151
+ repoRoot: { type: "string", description: "ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ ๋””๋ ‰ํ† ๋ฆฌ" },
152
+ runId: { type: "string", description: "ํ…Œ์ŠคํŠธ ์‹คํ–‰ ID" },
153
+ healIndex: {
154
+ type: "number",
155
+ description: "์ ์šฉํ•  heal suggestion์˜ ์ธ๋ฑ์Šค (0๋ถ€ํ„ฐ ์‹œ์ž‘)",
156
+ },
157
+ createBackup: {
158
+ type: "boolean",
159
+ description: "๋ฐฑ์—… ์ƒ์„ฑ ์—ฌ๋ถ€ (๊ธฐ๋ณธ๊ฐ’: true, ํ•„์ˆ˜ ๊ถŒ์žฅ)",
160
+ },
161
+ },
162
+ required: ["repoRoot", "runId", "healIndex"],
163
+ },
164
+ },
97
165
  ];
98
166
 
99
167
  export function ateTools(projectRoot: string) {
@@ -116,6 +184,7 @@ export function ateTools(projectRoot: string) {
116
184
  finishedAt: input.finishedAt,
117
185
  exitCode: input.exitCode,
118
186
  oracleLevel: input.oracleLevel ?? "L1",
187
+ format: input.format ?? "both",
119
188
  impact: input.impact,
120
189
  });
121
190
  },
@@ -125,5 +194,26 @@ export function ateTools(projectRoot: string) {
125
194
  "mandu.ate.impact": async (args: Record<string, unknown>) => {
126
195
  return ateImpact(args as any);
127
196
  },
197
+ "mandu.ate.auto_pipeline": async (args: Record<string, unknown>) => {
198
+ return await runFullPipeline(args as any);
199
+ },
200
+ "mandu.ate.feedback": async (args: Record<string, unknown>) => {
201
+ const result = analyzeFeedback(args as any);
202
+ return {
203
+ ok: true,
204
+ category: result.category,
205
+ autoApplicable: result.autoApplicable,
206
+ priority: result.priority,
207
+ reasoning: result.reasoning,
208
+ suggestions: result.suggestions,
209
+ };
210
+ },
211
+ "mandu.ate.apply_heal": async (args: Record<string, unknown>) => {
212
+ const result = applyHeal(args as any);
213
+ return {
214
+ ok: result.success,
215
+ ...result,
216
+ };
217
+ },
128
218
  };
129
219
  }