levante 0.3.1 → 0.3.4
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 +11 -11
- package/agents/0.init-agent.md +1 -1
- package/dist/cli.js +1 -1
- package/dist/mcp.js +24 -24
- package/package.json +5 -3
- package/templates/workflow.md +3 -3
package/README.md
CHANGED
|
@@ -173,17 +173,17 @@ Add to your MCP client config (e.g., `claude_desktop_config.json`):
|
|
|
173
173
|
|
|
174
174
|
| Tool | Description |
|
|
175
175
|
|------|-------------|
|
|
176
|
-
| `
|
|
177
|
-
| `
|
|
178
|
-
| `
|
|
179
|
-
| `
|
|
180
|
-
| `
|
|
181
|
-
| `
|
|
182
|
-
| `
|
|
183
|
-
| `
|
|
184
|
-
| `
|
|
185
|
-
| `
|
|
186
|
-
| `
|
|
176
|
+
| `levante_plan_workflow` | Get ordered step list with prerequisite checks |
|
|
177
|
+
| `levante_execute_step` | Execute a single pipeline step |
|
|
178
|
+
| `levante_get_workflow_guide` | Get the full workflow guide |
|
|
179
|
+
| `levante_scan_codebase` | Scan project for test infrastructure |
|
|
180
|
+
| `levante_validate_context` | Validate context.md completeness |
|
|
181
|
+
| `levante_read_agent` | Load an agent prompt by name |
|
|
182
|
+
| `levante_get_example` | Get example context.md template |
|
|
183
|
+
| `levante_scan_ast` | Run AST scanner |
|
|
184
|
+
| `levante_scan_ast_detail` | Drill into routes/components/hooks |
|
|
185
|
+
| `levante_build_qa_map` | Build and validate QA map |
|
|
186
|
+
| `levante_read_qa_map` | Load existing QA map |
|
|
187
187
|
|
|
188
188
|
## Configuration
|
|
189
189
|
|
package/agents/0.init-agent.md
CHANGED
|
@@ -10,7 +10,7 @@ You are a codebase analysis assistant for the levante test automation tool. Your
|
|
|
10
10
|
|
|
11
11
|
This agent is designed to be used directly in your AI tool (Claude Code, Cursor, Gemini CLI, etc.). Start a conversation and ask it to generate your project context.
|
|
12
12
|
|
|
13
|
-
**If the levante MCP server is configured**, call `
|
|
13
|
+
**If the levante MCP server is configured**, call `levante_scan_codebase` to get scan results, then follow this agent's instructions to produce the context file.
|
|
14
14
|
|
|
15
15
|
**If no MCP server**, manually explore the codebase: look at test files, fixtures, playwright config, tsconfig paths, and helper modules.
|
|
16
16
|
|
package/dist/cli.js
CHANGED
|
@@ -75308,7 +75308,7 @@ function registerInit(program2) {
|
|
|
75308
75308
|
if (!isReInit) {
|
|
75309
75309
|
console.log(import_picocolors5.default.bold("Next steps:"));
|
|
75310
75310
|
console.log(` 1. Use the ${import_picocolors5.default.cyan("init-agent")} in your AI tool to generate ${import_picocolors5.default.cyan(`${CONFIG_DIR}/context.md`)}`);
|
|
75311
|
-
console.log(` (or use the MCP server: ${import_picocolors5.default.cyan("
|
|
75311
|
+
console.log(` (or use the MCP server: ${import_picocolors5.default.cyan("levante_scan_codebase")} + ${import_picocolors5.default.cyan("levante_read_agent")})`);
|
|
75312
75312
|
console.log(` 2. Review the generated ${import_picocolors5.default.cyan(`${CONFIG_DIR}/context.md`)}`);
|
|
75313
75313
|
console.log(` 3. Run: ${import_picocolors5.default.cyan("levante run --key PROJ-101")}`);
|
|
75314
75314
|
} else {
|
package/dist/mcp.js
CHANGED
|
@@ -32900,18 +32900,18 @@ NEVER run multiple pipeline steps at once. Each step is a separate job with its
|
|
|
32900
32900
|
|
|
32901
32901
|
## Protocol
|
|
32902
32902
|
|
|
32903
|
-
1. **Plan first.** Call \`
|
|
32903
|
+
1. **Plan first.** Call \`levante_plan_workflow\` with the user's goal. This returns a structured todo list of steps.
|
|
32904
32904
|
2. **Check prerequisites.** The plan includes a \`ready\` boolean and \`missingPrerequisites\` array. If \`ready\` is false, show the user what's missing (API keys, config, etc.) and **wait for them to fix it** before proceeding. Do NOT attempt to execute any step while prerequisites are missing.
|
|
32905
32905
|
3. **Present the plan.** Show the user the ordered step list with descriptions. Ask for confirmation or adjustments before proceeding.
|
|
32906
32906
|
4. **Execute one step at a time.** For each step in the approved plan:
|
|
32907
32907
|
a. Tell the user which step you're about to run and why.
|
|
32908
|
-
b. Call \`
|
|
32908
|
+
b. Call \`levante_execute_step\` with the step name and parameters.
|
|
32909
32909
|
c. Report the result to the user (success, key output, any warnings).
|
|
32910
32910
|
d. If the step fails, stop and discuss with the user before continuing.
|
|
32911
32911
|
e. Move to the next step only after the current one succeeds.
|
|
32912
32912
|
5. **Use subagents when available.** If your AI platform supports subagents (e.g., Claude Code Agent tool), dispatch each step as a dedicated subagent to preserve context. Each subagent should:
|
|
32913
32913
|
- Receive only the context it needs (step name, key, relevant file paths)
|
|
32914
|
-
- Call \`
|
|
32914
|
+
- Call \`levante_execute_step\` to do its work
|
|
32915
32915
|
- Return the result to the orchestrator
|
|
32916
32916
|
|
|
32917
32917
|
## Step Dependencies
|
|
@@ -32941,19 +32941,19 @@ The \`record\` step opens a browser and requires user interaction. When the plan
|
|
|
32941
32941
|
- **Scanner pipeline**: scan → analyze → push
|
|
32942
32942
|
- **Single step**: any individual command
|
|
32943
32943
|
|
|
32944
|
-
Always use \`
|
|
32944
|
+
Always use \`levante_plan_workflow\` to determine the right steps — don't guess.
|
|
32945
32945
|
|
|
32946
32946
|
## Scanner Analysis (Interactive QA Map)
|
|
32947
32947
|
|
|
32948
32948
|
For deep codebase analysis and QA map generation, use the interactive scanner workflow instead of the CLI pipeline:
|
|
32949
32949
|
|
|
32950
|
-
1. **Load the protocol.** Call \`
|
|
32951
|
-
2. **Scan.** Call \`
|
|
32952
|
-
3. **Explore.** Use \`
|
|
32950
|
+
1. **Load the protocol.** Call \`levante_read_agent("scanner-agent")\` — this returns the full interactive protocol.
|
|
32951
|
+
2. **Scan.** Call \`levante_scan_ast()\` to run the AST scanner and get a compact summary.
|
|
32952
|
+
3. **Explore.** Use \`levante_scan_ast_detail()\` to drill into routes, components, hooks, or files.
|
|
32953
32953
|
4. **Propose & discuss.** Present candidate features to the user, ask clarifying questions.
|
|
32954
|
-
5. **Build.** Construct the QA map payload and validate with \`
|
|
32955
|
-
6. **Write.** Once validated and approved, call \`
|
|
32956
|
-
7. **Read existing.** Use \`
|
|
32954
|
+
5. **Build.** Construct the QA map payload and validate with \`levante_build_qa_map({ dryRun: true })\`.
|
|
32955
|
+
6. **Write.** Once validated and approved, call \`levante_build_qa_map({ dryRun: false })\` to save.
|
|
32956
|
+
7. **Read existing.** Use \`levante_read_qa_map()\` to load a previously generated QA map for incremental updates.
|
|
32957
32957
|
|
|
32958
32958
|
This approach is preferred over \`scan → analyze\` CLI steps because it allows interactive refinement with the user.
|
|
32959
32959
|
`.trim();
|
|
@@ -33258,7 +33258,7 @@ ${stderr}`,
|
|
|
33258
33258
|
}
|
|
33259
33259
|
}
|
|
33260
33260
|
var server = new McpServer({ name: "levante", version: "1.5.1" }, { instructions: SERVER_INSTRUCTIONS });
|
|
33261
|
-
server.registerTool("
|
|
33261
|
+
server.registerTool("levante_scan_codebase", {
|
|
33262
33262
|
title: "Scan Codebase",
|
|
33263
33263
|
description: "Scan a project directory for test files, configs, fixtures, path aliases, and sample test content. Use this during project setup or to understand test infrastructure.",
|
|
33264
33264
|
inputSchema: exports_external.object({
|
|
@@ -33271,7 +33271,7 @@ server.registerTool("e2e_ai_scan_codebase", {
|
|
|
33271
33271
|
content: [{ type: "text", text: JSON.stringify(scan, null, 2) }]
|
|
33272
33272
|
};
|
|
33273
33273
|
});
|
|
33274
|
-
server.registerTool("
|
|
33274
|
+
server.registerTool("levante_validate_context", {
|
|
33275
33275
|
title: "Validate Context",
|
|
33276
33276
|
description: "Validate that a context markdown file contains all required sections (Application, Test Infrastructure, Feature Methods, Import Conventions, Selector Conventions, Test Structure Template, Utility Patterns).",
|
|
33277
33277
|
inputSchema: exports_external.object({
|
|
@@ -33283,7 +33283,7 @@ server.registerTool("e2e_ai_validate_context", {
|
|
|
33283
33283
|
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
33284
33284
|
};
|
|
33285
33285
|
});
|
|
33286
|
-
server.registerTool("
|
|
33286
|
+
server.registerTool("levante_read_agent", {
|
|
33287
33287
|
title: "Read Agent",
|
|
33288
33288
|
description: "Read an agent prompt definition by name. Returns the agent system prompt and config. Agents: transcript-agent, scenario-agent, playwright-generator-agent, refactor-agent, self-healing-agent, qa-testcase-agent, feature-analyzer-agent, scenario-planner-agent, scanner-agent, init-agent.",
|
|
33289
33289
|
inputSchema: exports_external.object({
|
|
@@ -33309,7 +33309,7 @@ server.registerTool("e2e_ai_read_agent", {
|
|
|
33309
33309
|
};
|
|
33310
33310
|
}
|
|
33311
33311
|
});
|
|
33312
|
-
server.registerTool("
|
|
33312
|
+
server.registerTool("levante_get_example", {
|
|
33313
33313
|
title: "Get Example Context",
|
|
33314
33314
|
description: `Returns the full example context markdown file that shows the expected format for ${CONFIG_DIR}/context.md.`,
|
|
33315
33315
|
inputSchema: exports_external.object({})
|
|
@@ -33327,7 +33327,7 @@ server.registerTool("e2e_ai_get_example", {
|
|
|
33327
33327
|
};
|
|
33328
33328
|
}
|
|
33329
33329
|
});
|
|
33330
|
-
server.registerTool("
|
|
33330
|
+
server.registerTool("levante_plan_workflow", {
|
|
33331
33331
|
title: "Plan Workflow",
|
|
33332
33332
|
description: "Plan a levante automation workflow. Call this FIRST when the user asks to run any automation. " + "Returns an ordered list of steps (todo list) that should be executed one at a time. " + "Present the plan to the user for approval before executing any step.",
|
|
33333
33333
|
inputSchema: exports_external.object({
|
|
@@ -33348,7 +33348,7 @@ server.registerTool("e2e_ai_plan_workflow", {
|
|
|
33348
33348
|
}]
|
|
33349
33349
|
};
|
|
33350
33350
|
});
|
|
33351
|
-
server.registerTool("
|
|
33351
|
+
server.registerTool("levante_execute_step", {
|
|
33352
33352
|
title: "Execute Pipeline Step",
|
|
33353
33353
|
description: "Execute a single levante pipeline step. Call this ONE STEP AT A TIME from an approved plan. " + "Each step produces artifacts consumed by later steps. " + "If your AI platform supports subagents, run each step in a dedicated subagent to preserve context. " + 'The "record" step is interactive and will open a browser window — the user must interact with it.',
|
|
33354
33354
|
inputSchema: exports_external.object({
|
|
@@ -33405,7 +33405,7 @@ Ask the user to provide these before retrying.`
|
|
|
33405
33405
|
}]
|
|
33406
33406
|
};
|
|
33407
33407
|
});
|
|
33408
|
-
server.registerTool("
|
|
33408
|
+
server.registerTool("levante_get_workflow_guide", {
|
|
33409
33409
|
title: "Get Workflow Guide",
|
|
33410
33410
|
description: "Returns the levante workflow guide explaining how the pipeline works, step by step. Useful for understanding what each step does and how they connect.",
|
|
33411
33411
|
inputSchema: exports_external.object({})
|
|
@@ -33429,9 +33429,9 @@ server.registerTool("e2e_ai_get_workflow_guide", {
|
|
|
33429
33429
|
};
|
|
33430
33430
|
}
|
|
33431
33431
|
});
|
|
33432
|
-
server.registerTool("
|
|
33432
|
+
server.registerTool("levante_scan_ast", {
|
|
33433
33433
|
title: "Scan AST",
|
|
33434
|
-
description: "Run the deep AST scanner on the codebase. Returns a compact summary (stats, routes, components, hooks, directory groups). " + `The full AST is saved to ${CONFIG_DIR}/ast-scan.json for follow-up queries via
|
|
33434
|
+
description: "Run the deep AST scanner on the codebase. Returns a compact summary (stats, routes, components, hooks, directory groups). " + `The full AST is saved to ${CONFIG_DIR}/ast-scan.json for follow-up queries via levante_scan_ast_detail.`,
|
|
33435
33435
|
inputSchema: exports_external.object({
|
|
33436
33436
|
scanDir: exports_external.string().optional().describe('Directory to scan (defaults to "src")'),
|
|
33437
33437
|
include: exports_external.array(exports_external.string()).optional().describe('Glob patterns to include (defaults to ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"])'),
|
|
@@ -33463,9 +33463,9 @@ server.registerTool("e2e_ai_scan_ast", {
|
|
|
33463
33463
|
};
|
|
33464
33464
|
}
|
|
33465
33465
|
});
|
|
33466
|
-
server.registerTool("
|
|
33466
|
+
server.registerTool("levante_scan_ast_detail", {
|
|
33467
33467
|
title: "Scan AST Detail",
|
|
33468
|
-
description: "Retrieve a filtered slice of the AST scan. Requires a prior
|
|
33468
|
+
description: "Retrieve a filtered slice of the AST scan. Requires a prior levante_scan_ast call. " + "Use to drill into routes, components, hooks, dependencies, or files.",
|
|
33469
33469
|
inputSchema: exports_external.object({
|
|
33470
33470
|
category: exports_external.enum(["routes", "components", "hooks", "dependencies", "files"]).describe("Which AST category to retrieve"),
|
|
33471
33471
|
filter: exports_external.string().optional().describe('Glob pattern to filter results (e.g. "src/app/**", "Dashboard*")'),
|
|
@@ -33476,7 +33476,7 @@ server.registerTool("e2e_ai_scan_ast_detail", {
|
|
|
33476
33476
|
const astPath = join5(process.cwd(), CONFIG_DIR, "ast-scan.json");
|
|
33477
33477
|
if (!existsSync5(astPath)) {
|
|
33478
33478
|
return {
|
|
33479
|
-
content: [{ type: "text", text: "Error: No AST scan found. Run
|
|
33479
|
+
content: [{ type: "text", text: "Error: No AST scan found. Run levante_scan_ast first." }],
|
|
33480
33480
|
isError: true
|
|
33481
33481
|
};
|
|
33482
33482
|
}
|
|
@@ -33492,7 +33492,7 @@ server.registerTool("e2e_ai_scan_ast_detail", {
|
|
|
33492
33492
|
};
|
|
33493
33493
|
}
|
|
33494
33494
|
});
|
|
33495
|
-
server.registerTool("
|
|
33495
|
+
server.registerTool("levante_build_qa_map", {
|
|
33496
33496
|
title: "Build QA Map",
|
|
33497
33497
|
description: "Validate and optionally write a QAMapV2Payload. Use dryRun: true to validate without writing. " + "Returns validation result with errors, warnings, and stats.",
|
|
33498
33498
|
inputSchema: exports_external.object({
|
|
@@ -33545,7 +33545,7 @@ server.registerTool("e2e_ai_build_qa_map", {
|
|
|
33545
33545
|
};
|
|
33546
33546
|
}
|
|
33547
33547
|
});
|
|
33548
|
-
server.registerTool("
|
|
33548
|
+
server.registerTool("levante_read_qa_map", {
|
|
33549
33549
|
title: "Read QA Map",
|
|
33550
33550
|
description: "Read an existing QA map file. Returns the parsed QAMapV2Payload or null if not found.",
|
|
33551
33551
|
inputSchema: exports_external.object({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "levante",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"levante": "./dist/cli.js",
|
|
@@ -24,6 +24,10 @@
|
|
|
24
24
|
"peerDependencies": {
|
|
25
25
|
"@playwright/test": ">=1.40.0"
|
|
26
26
|
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"picocolors": "^1.1.1",
|
|
29
|
+
"ws": "^8.19.0"
|
|
30
|
+
},
|
|
27
31
|
"devDependencies": {
|
|
28
32
|
"@inquirer/prompts": "^8.3.0",
|
|
29
33
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
@@ -36,11 +40,9 @@
|
|
|
36
40
|
"ink": "^5",
|
|
37
41
|
"ink-text-input": "^6",
|
|
38
42
|
"ora": "^9.3.0",
|
|
39
|
-
"picocolors": "^1.1.1",
|
|
40
43
|
"react": "^18",
|
|
41
44
|
"react-devtools-core": "^7.0.1",
|
|
42
45
|
"typescript": "^5.8.3",
|
|
43
|
-
"ws": "^8.19.0",
|
|
44
46
|
"yaml": "^2.7.1",
|
|
45
47
|
"zod": "^4.0.5"
|
|
46
48
|
}
|
package/templates/workflow.md
CHANGED
|
@@ -24,7 +24,7 @@ record → transcribe → scenario → generate → refine → test → heal →
|
|
|
24
24
|
|
|
25
25
|
After running `levante init`, you need a **context file** (`.qai/levante/context.md`) that teaches the AI about your project's test conventions — fixtures, helpers, selectors, login flows, etc.
|
|
26
26
|
|
|
27
|
-
**How to create it:** Use the `init-agent` in your AI tool (Claude Code, Cursor, etc.). If you have the MCP server configured, the AI can scan your codebase automatically with `
|
|
27
|
+
**How to create it:** Use the `init-agent` in your AI tool (Claude Code, Cursor, etc.). If you have the MCP server configured, the AI can scan your codebase automatically with `levante_scan_codebase`.
|
|
28
28
|
|
|
29
29
|
---
|
|
30
30
|
|
|
@@ -207,10 +207,10 @@ This is independent from the test pipeline — use it to get an overview of your
|
|
|
207
207
|
If you have the levante MCP server configured, you can ask your AI assistant to run the pipeline for you. The MCP server teaches the AI how to orchestrate the workflow:
|
|
208
208
|
|
|
209
209
|
1. **You say:** "Run the full test pipeline for PROJ-101" (or any variation)
|
|
210
|
-
2. **AI plans:** Calls `
|
|
210
|
+
2. **AI plans:** Calls `levante_plan_workflow` → gets an ordered step list
|
|
211
211
|
3. **AI shows plan:** Presents the steps and asks for your approval
|
|
212
212
|
4. **You adjust:** "Skip voice" / "Start from generate" / "Looks good, go"
|
|
213
|
-
5. **AI executes:** Runs each step one at a time via `
|
|
213
|
+
5. **AI executes:** Runs each step one at a time via `levante_execute_step`, reporting results between steps
|
|
214
214
|
|
|
215
215
|
Each step runs as a separate subagent (when supported by the AI platform) to keep context clean and focused. If a step fails, the AI stops and asks you what to do.
|
|
216
216
|
|