@skyramp/mcp 0.0.64-rc.7 → 0.0.64-rc.8

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/build/index.js CHANGED
@@ -30,6 +30,7 @@ import { registerSubmitReportTool } from "./tools/submitReportTool.js";
30
30
  import { registerInitializeWorkspaceTool } from "./tools/workspace/initializeWorkspaceTool.js";
31
31
  import { registerOneClickTool } from "./tools/one-click/oneClickTool.js";
32
32
  import { registerAnalysisResources } from "./resources/analysisResources.js";
33
+ import { registerProgressResource } from "./resources/progressResource.js";
33
34
  import { AnalyticsService } from "./services/AnalyticsService.js";
34
35
  import { initCheck } from "./utils/initAgent.js";
35
36
  import { registerPlaywrightTools, registerTraceRecordingPrompt, getPlaywrightTraceService, } from "./playwright/index.js";
@@ -196,6 +197,7 @@ const codeQualityTools = [
196
197
  codeQualityTools.forEach((registerTool) => registerTool(server));
197
198
  // Register analysis resources (MCP Resources for enriched data access)
198
199
  registerAnalysisResources(server);
200
+ registerProgressResource(server);
199
201
  // Register unified test-management tools (replaces separate test-maintenance tools)
200
202
  registerAnalyzeChangesTool(server);
201
203
  registerAnalyzeTestHealthTool(server);
@@ -152,12 +152,17 @@ If a test generation tool call fails:
152
152
  5. Log skipped candidates in \`issuesFound\` with the error message.
153
153
 
154
154
  ### UI Test Execution Fix-up
155
- If a generated UI test fails with a timeout waiting for an element after navigation (e.g. \`TimeoutError\` on \`getByTestId\` or \`locator\`), add a hydration wait after each \`page.goto()\` call:
155
+ If a generated UI test fails with a timeout waiting for an element after navigation (e.g. \`TimeoutError\` on \`getByTestId\` or \`locator\`), add a dynamic wait after each \`page.goto()\` call that waits for the page to be ready instead of using a fixed delay:
156
156
  \`\`\`
157
- // Wait for React/framework hydration to complete
158
- await page.waitForTimeout(1500);
157
+ // Wait for the page to fully load and hydrate before interacting
158
+ await page.waitForLoadState('networkidle');
159
159
  \`\`\`
160
- Then re-run the test. This is a common issue with SSR/SPA frameworks where the DOM is rendered but not yet interactive.
160
+ If the test still fails, wait for the specific element the test needs before interacting:
161
+ \`\`\`
162
+ // Wait for a visible element that indicates the page content has loaded
163
+ await page.locator('[data-testid="some-element"]').waitFor({ state: 'visible', timeout: 10000 });
164
+ \`\`\`
165
+ Do NOT use \`page.waitForTimeout()\` with fixed delays — these are flaky in CI where container startup and network latency vary. Always prefer \`waitForLoadState\` or \`waitFor\` on a specific locator.
161
166
 
162
167
  **After generation, you MUST do exactly two things — nothing more, nothing less:**
163
168
  1. **Fix chaining**: replace hardcoded IDs with dynamic response values — path params like \`id = 'id'\` → \`skyramp.get_response_value(prev_response, "id")\`, and hardcoded IDs in request bodies → dynamic values from prior responses.
@@ -0,0 +1,14 @@
1
+ import { TOOL_PHASE_MAP } from "../tool-phases.js";
2
+ export function registerProgressResource(server) {
3
+ server.registerResource("progress_tool_phases", "skyramp://progress/tool-phases", {
4
+ title: "Tool Phase Mapping",
5
+ description: "Maps Skyramp MCP tool names to testbot progress phases.",
6
+ mimeType: "application/json",
7
+ }, () => ({
8
+ contents: [{
9
+ uri: "skyramp://progress/tool-phases",
10
+ mimeType: "application/json",
11
+ text: JSON.stringify(TOOL_PHASE_MAP),
12
+ }],
13
+ }));
14
+ }
@@ -0,0 +1,41 @@
1
+ import { TOOL_PHASE_MAP, TOOLS_WITHOUT_PHASE } from "./tool-phases.js";
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+ function findAllToolNames() {
5
+ const toolNames = [];
6
+ function walk(dir) {
7
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
8
+ const full = path.join(dir, entry.name);
9
+ if (entry.isDirectory()) {
10
+ walk(full);
11
+ continue;
12
+ }
13
+ if (!entry.name.endsWith(".ts"))
14
+ continue;
15
+ const content = fs.readFileSync(full, "utf-8");
16
+ const matches = content.matchAll(/const TOOL_NAME\s*=\s*["']([^"']+)["']/g);
17
+ for (const m of matches)
18
+ toolNames.push(m[1]);
19
+ }
20
+ }
21
+ walk(path.resolve(__dirname, "./tools"));
22
+ return toolNames;
23
+ }
24
+ describe("tool-phase-coverage", () => {
25
+ it("every registered tool has a phase or is explicitly excluded", () => {
26
+ const allTools = findAllToolNames();
27
+ expect(allTools.length).toBeGreaterThan(0);
28
+ const missing = allTools.filter(name => !(name in TOOL_PHASE_MAP) && !TOOLS_WITHOUT_PHASE.has(name));
29
+ if (missing.length > 0) {
30
+ throw new Error(`These tools are not in TOOL_PHASE_MAP or TOOLS_WITHOUT_PHASE in src/tool-phases.ts:\n` +
31
+ missing.map(n => ` - ${n}`).join("\n") +
32
+ `\nAdd them to the appropriate export in src/tool-phases.ts`);
33
+ }
34
+ });
35
+ it("TOOL_PHASE_MAP contains only valid phases", () => {
36
+ const validPhases = new Set(["analyzing", "generating", "executing", "maintaining", "reporting"]);
37
+ for (const [tool, phase] of Object.entries(TOOL_PHASE_MAP)) {
38
+ expect(validPhases.has(phase)).toBe(true);
39
+ }
40
+ });
41
+ });
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Canonical mapping of Skyramp MCP tool names to testbot progress phases.
3
+ *
4
+ * The testbot progress UI reads this map at runtime to know which tool calls
5
+ * correspond to which progress steps. When adding or renaming tools, update
6
+ * this map so the progress UI stays accurate.
7
+ *
8
+ * Tools not in this map must be listed in TOOLS_WITHOUT_PHASE.
9
+ *
10
+ * Phases: analyzing, generating, executing, maintaining, reporting
11
+ */
12
+ export const TOOL_PHASE_MAP = {
13
+ skyramp_recommend_tests: "analyzing",
14
+ skyramp_analyze_changes: "analyzing",
15
+ skyramp_smoke_test_generation: "generating",
16
+ skyramp_fuzz_test_generation: "generating",
17
+ skyramp_contract_test_generation: "generating",
18
+ skyramp_load_test_generation: "generating",
19
+ skyramp_integration_test_generation: "generating",
20
+ skyramp_e2e_test_generation: "generating",
21
+ skyramp_ui_test_generation: "generating",
22
+ skyramp_scenario_test_generation: "generating",
23
+ skyramp_mock_generation: "generating",
24
+ skyramp_execute_test: "executing",
25
+ skyramp_execute_tests: "executing",
26
+ skyramp_analyze_test_health: "maintaining",
27
+ skyramp_submit_report: "reporting",
28
+ };
29
+ /** Tools that intentionally have no progress phase (infrastructure/utility). */
30
+ export const TOOLS_WITHOUT_PHASE = new Set([
31
+ "skyramp_login",
32
+ "skyramp_logout",
33
+ "skyramp_initialize_workspace",
34
+ "skyramp_one_click_tool",
35
+ "skyramp_actions",
36
+ "skyramp_state_cleanup",
37
+ "skyramp_start_trace_collection",
38
+ "skyramp_stop_trace_collection",
39
+ "skyramp_fix_errors",
40
+ "skyramp_modularization",
41
+ "skyramp_reuse_code",
42
+ ]);
@@ -92,6 +92,15 @@ export class ContractTestService extends TestGenerationService {
92
92
  getTestType() {
93
93
  return TestType.CONTRACT;
94
94
  }
95
+ async handleApiAnalysis(params, generateOptions) {
96
+ // When apiSchema is provided, path parameters are resolved via parentRequestData
97
+ // provisioning — skip the base-class path-parameter validation prompt.
98
+ // Without apiSchema, fall through to normal validation.
99
+ if (params.apiSchema) {
100
+ return null;
101
+ }
102
+ return super.handleApiAnalysis(params, generateOptions);
103
+ }
95
104
  async generateTest(params) {
96
105
  const result = await super.generateTest(params);
97
106
  if (result.isError)
package/package.json CHANGED
@@ -1,7 +1,12 @@
1
1
  {
2
2
  "name": "@skyramp/mcp",
3
- "version": "0.0.64-rc.7",
3
+ "version": "0.0.64-rc.8",
4
4
  "main": "build/index.js",
5
+ "exports": {
6
+ ".": "./build/index.js",
7
+ "./tool-phases": "./build/tool-phases.js",
8
+ "./build/*": "./build/*"
9
+ },
5
10
  "type": "module",
6
11
  "bin": {
7
12
  "mcp": "./build/index.js"