@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 +96 -0
- package/package.json +2 -2
- package/src/tools/ate.ts +92 -2
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.
|
|
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.
|
|
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 {
|
|
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:
|
|
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
|
}
|