@skyramp/mcp 0.2.6 → 0.2.7

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 (184) hide show
  1. package/build/commands/commandLibrary.d.ts +12 -0
  2. package/build/commands/recommendTestsAndExecuteCommand.d.ts +2 -0
  3. package/build/commands/testThisEndpointCommand.d.ts +2 -0
  4. package/build/index.d.ts +2 -0
  5. package/build/index.js +1 -2
  6. package/build/playwright/PlaywrightTraceService.d.ts +32 -0
  7. package/build/playwright/index.d.ts +3 -0
  8. package/build/playwright/registerPlaywrightTools.d.ts +8 -0
  9. package/build/playwright/registerPlaywrightTools.js +12 -11
  10. package/build/playwright/traceRecordingPrompt.d.ts +13 -0
  11. package/build/playwright/traceRecordingPrompt.js +3 -11
  12. package/build/prompts/code-reuse.d.ts +1 -0
  13. package/build/prompts/enhance-assertions/contractProviderAssertionsPrompt.d.ts +2 -0
  14. package/build/prompts/enhance-assertions/integrationAssertionsPrompt.d.ts +2 -0
  15. package/build/prompts/enhance-assertions/sharedAssertionRules.d.ts +15 -0
  16. package/build/prompts/enhance-assertions/uiAssertionsPrompt.d.ts +2 -0
  17. package/build/prompts/fix-error-prompt.d.ts +1 -0
  18. package/build/prompts/initialize-workspace/initializeWorkspacePrompt.d.ts +1 -0
  19. package/build/prompts/modularization/integration-test-modularization.d.ts +1 -0
  20. package/build/prompts/modularization/ui-test-modularization.d.ts +1 -0
  21. package/build/prompts/personas.d.ts +21 -0
  22. package/build/prompts/pom-aware-code-reuse.d.ts +1 -0
  23. package/build/prompts/startTraceCollectionPrompts.d.ts +2 -0
  24. package/build/prompts/test-maintenance/actionsInstructions.d.ts +35 -0
  25. package/build/prompts/test-maintenance/drift-analysis-prompt.d.ts +4 -0
  26. package/build/prompts/test-maintenance/driftAnalysisSections.d.ts +13 -0
  27. package/build/prompts/test-recommendation/analysisOutputPrompt.d.ts +84 -0
  28. package/build/prompts/test-recommendation/analysisOutputPrompt.test.d.ts +1 -0
  29. package/build/prompts/test-recommendation/analysisOutputPrompt.test.js +1 -0
  30. package/build/prompts/test-recommendation/diffExecutionPlan.d.ts +17 -0
  31. package/build/prompts/test-recommendation/diffExecutionPlan.js +7 -16
  32. package/build/prompts/test-recommendation/fullRepoCatalog.d.ts +7 -0
  33. package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.d.ts +1 -0
  34. package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.js +1 -0
  35. package/build/prompts/test-recommendation/promptPlan.d.ts +203 -0
  36. package/build/prompts/test-recommendation/promptPlan.test.d.ts +1 -0
  37. package/build/prompts/test-recommendation/recommendationSections.d.ts +35 -0
  38. package/build/prompts/test-recommendation/recommendationShared.d.ts +31 -0
  39. package/build/prompts/test-recommendation/registerRecommendTestsPrompt.d.ts +7 -0
  40. package/build/prompts/test-recommendation/scopeAssessment.d.ts +55 -0
  41. package/build/prompts/test-recommendation/scopeAssessment.js +2 -2
  42. package/build/prompts/test-recommendation/scopeAssessment.test.d.ts +1 -0
  43. package/build/prompts/test-recommendation/scopeAssessment.test.js +1 -0
  44. package/build/prompts/test-recommendation/test-recommendation-prompt.d.ts +6 -0
  45. package/build/prompts/test-recommendation/test-recommendation-prompt.js +4 -4
  46. package/build/prompts/test-recommendation/test-recommendation-prompt.test.d.ts +1 -0
  47. package/build/prompts/test-recommendation/test-recommendation-prompt.test.js +6 -99
  48. package/build/prompts/testbot/testbot-prompts.d.ts +11 -0
  49. package/build/prompts/testbot/testbot-prompts.js +198 -34
  50. package/build/prompts/testbot/testbot-prompts.test.d.ts +1 -0
  51. package/build/prompts/testbot/testbot-prompts.test.js +15 -73
  52. package/build/resources/analysisResources.d.ts +17 -0
  53. package/build/resources/progressResource.d.ts +2 -0
  54. package/build/resources/testbotResource.d.ts +2 -0
  55. package/build/services/AnalyticsService.d.ts +13 -0
  56. package/build/services/AnalyticsService.test.d.ts +1 -0
  57. package/build/services/AnalyticsService.test.js +86 -0
  58. package/build/services/ModularizationService.d.ts +11 -0
  59. package/build/services/ScenarioGenerationService.d.ts +37 -0
  60. package/build/services/ScenarioGenerationService.integration.test.d.ts +1 -0
  61. package/build/services/ScenarioGenerationService.integration.test.js +4 -0
  62. package/build/services/ScenarioGenerationService.test.d.ts +1 -0
  63. package/build/services/TestDiscoveryService.d.ts +128 -0
  64. package/build/services/TestDiscoveryService.test.d.ts +1 -0
  65. package/build/services/TestDiscoveryService.test.js +4 -3
  66. package/build/services/TestExecutionService.d.ts +46 -0
  67. package/build/services/TestExecutionService.test.d.ts +1 -0
  68. package/build/services/TestExecutionService.test.js +33 -25
  69. package/build/services/TestGenerationService.d.ts +56 -0
  70. package/build/services/TestGenerationService.test.d.ts +1 -0
  71. package/build/services/TestGenerationService.test.js +10 -8
  72. package/build/services/containerEnv.d.ts +14 -0
  73. package/build/tool-phase-coverage.test.d.ts +1 -0
  74. package/build/tool-phase-coverage.test.js +2 -0
  75. package/build/tool-phases.d.ts +38 -0
  76. package/build/tools/auth/loginTool.d.ts +2 -0
  77. package/build/tools/auth/logoutTool.d.ts +2 -0
  78. package/build/tools/code-refactor/codeReuseTool.d.ts +2 -0
  79. package/build/tools/code-refactor/enhanceAssertionsTool.d.ts +2 -0
  80. package/build/tools/code-refactor/modularizationTool.d.ts +2 -0
  81. package/build/tools/executeSkyrampTestTool.d.ts +2 -0
  82. package/build/tools/fixErrorTool.d.ts +2 -0
  83. package/build/tools/generate-tests/generateBatchScenarioRestTool.d.ts +45 -0
  84. package/build/tools/generate-tests/generateBatchScenarioRestTool.test.d.ts +1 -0
  85. package/build/tools/generate-tests/generateBatchScenarioRestTool.test.js +11 -9
  86. package/build/tools/generate-tests/generateContractRestTool.d.ts +31 -0
  87. package/build/tools/generate-tests/generateE2ERestTool.d.ts +13 -0
  88. package/build/tools/generate-tests/generateFuzzRestTool.d.ts +10 -0
  89. package/build/tools/generate-tests/generateIntegrationRestTool.d.ts +16 -0
  90. package/build/tools/generate-tests/generateLoadRestTool.d.ts +18 -0
  91. package/build/tools/generate-tests/generateLoadRestTool.test.d.ts +1 -0
  92. package/build/tools/generate-tests/generateMockRestTool.d.ts +64 -0
  93. package/build/tools/generate-tests/generateSmokeRestTool.d.ts +8 -0
  94. package/build/tools/generate-tests/generateUIRestTool.d.ts +14 -0
  95. package/build/tools/generate-tests/generateUIRestTool.js +1 -1
  96. package/build/tools/generate-tests/loadTestSchema.d.ts +39 -0
  97. package/build/tools/one-click/oneClickTool.d.ts +11 -0
  98. package/build/tools/submitReportTool.d.ts +384 -0
  99. package/build/tools/submitReportTool.js +144 -2
  100. package/build/tools/submitReportTool.test.d.ts +1 -0
  101. package/build/tools/submitReportTool.test.js +215 -5
  102. package/build/tools/test-management/actionsTool.d.ts +10 -0
  103. package/build/tools/test-management/analyzeChangesTool.d.ts +27 -0
  104. package/build/tools/test-management/analyzeChangesTool.js +44 -7
  105. package/build/tools/test-management/analyzeChangesTool.test.d.ts +1 -0
  106. package/build/tools/test-management/analyzeChangesTool.test.js +76 -39
  107. package/build/tools/test-management/analyzeTestHealthTool.d.ts +2 -0
  108. package/build/tools/test-management/index.d.ts +3 -0
  109. package/build/tools/test-management/index.js +0 -1
  110. package/build/tools/trace/resolveSaveStoragePath.d.ts +7 -0
  111. package/build/tools/trace/resolveSaveStoragePath.test.d.ts +1 -0
  112. package/build/tools/trace/resolveSessionPaths.d.ts +40 -0
  113. package/build/tools/trace/resolveSessionPaths.test.d.ts +1 -0
  114. package/build/tools/trace/sessionState.d.ts +2 -0
  115. package/build/tools/trace/sessionState.test.d.ts +1 -0
  116. package/build/tools/trace/startTraceCollectionTool.d.ts +2 -0
  117. package/build/tools/trace/stopTraceCollectionTool.d.ts +2 -0
  118. package/build/tools/workspace/initScanWorkspaceTool.d.ts +4 -0
  119. package/build/tools/workspace/initializeWorkspaceTool.d.ts +2 -0
  120. package/build/tools/workspace/initializeWorkspaceTool.test.d.ts +1 -0
  121. package/build/tools/workspace/initializeWorkspaceTool.test.js +134 -0
  122. package/build/types/OneClickCommands.d.ts +68 -0
  123. package/build/types/RepositoryAnalysis.d.ts +3004 -0
  124. package/build/types/TestAnalysis.d.ts +96 -0
  125. package/build/types/TestExecution.d.ts +53 -0
  126. package/build/types/TestRecommendation.d.ts +12 -0
  127. package/build/types/TestTypes.d.ts +234 -0
  128. package/build/utils/AnalysisStateManager.d.ts +182 -0
  129. package/build/utils/AnalysisStateManager.test.d.ts +1 -0
  130. package/build/utils/analyze-openapi.d.ts +1 -0
  131. package/build/utils/branchDiff.d.ts +18 -0
  132. package/build/utils/dartRouteExtractor.d.ts +45 -0
  133. package/build/utils/dartRouteExtractor.test.d.ts +1 -0
  134. package/build/utils/docker.d.ts +19 -0
  135. package/build/utils/docker.test.d.ts +1 -0
  136. package/build/utils/docker.test.js +10 -9
  137. package/build/utils/featureFlags.d.ts +37 -0
  138. package/build/utils/featureFlags.test.d.ts +1 -0
  139. package/build/utils/gitStaging.d.ts +24 -0
  140. package/build/utils/gitStaging.test.d.ts +1 -0
  141. package/build/utils/gitStaging.test.js +13 -7
  142. package/build/utils/httpDefaults.d.ts +10 -0
  143. package/build/utils/httpDefaults.test.d.ts +1 -0
  144. package/build/utils/initAgent.d.ts +36 -0
  145. package/build/utils/language-helper.d.ts +6 -0
  146. package/build/utils/logger.d.ts +11 -0
  147. package/build/utils/normalizeParams.d.ts +14 -0
  148. package/build/utils/normalizeSkyrampImports.d.ts +13 -0
  149. package/build/utils/pr-comment-parser.d.ts +31 -0
  150. package/build/utils/pr-comment-parser.test.d.ts +1 -0
  151. package/build/utils/pr-comment-parser.test.js +6 -5
  152. package/build/utils/projectMetadata.d.ts +15 -0
  153. package/build/utils/projectMetadata.test.d.ts +1 -0
  154. package/build/utils/proxy-terminal.d.ts +2 -0
  155. package/build/utils/repoScanner.d.ts +27 -0
  156. package/build/utils/repoScanner.test.d.ts +1 -0
  157. package/build/utils/routeParsers.d.ts +63 -0
  158. package/build/utils/routeParsers.test.d.ts +1 -0
  159. package/build/utils/scenarioDrafting.d.ts +71 -0
  160. package/build/utils/scenarioDrafting.test.d.ts +1 -0
  161. package/build/utils/skyrampMdContent.d.ts +5 -0
  162. package/build/utils/sourceRouteExtractor.d.ts +48 -0
  163. package/build/utils/sourceRouteExtractor.test.d.ts +1 -0
  164. package/build/utils/telemetry.d.ts +32 -0
  165. package/build/utils/telemetry.test.d.ts +1 -0
  166. package/build/utils/trace-parser.d.ts +32 -0
  167. package/build/utils/trace-parser.test.d.ts +6 -0
  168. package/build/utils/uiPageEnumerator.d.ts +146 -0
  169. package/build/utils/uiPageEnumerator.js +58 -14
  170. package/build/utils/uiPageEnumerator.test.d.ts +1 -0
  171. package/build/utils/uiPageEnumerator.test.js +223 -43
  172. package/build/utils/utils.d.ts +39 -0
  173. package/build/utils/utils.test.d.ts +1 -0
  174. package/build/utils/versions.d.ts +3 -0
  175. package/build/utils/versions.js +1 -1
  176. package/build/utils/workspaceAuth.d.ts +127 -0
  177. package/build/utils/workspaceAuth.test.d.ts +1 -0
  178. package/build/utils/workspaceAuth.test.js +25 -25
  179. package/build/workspace/index.d.ts +1 -0
  180. package/build/workspace/workspace.d.ts +390 -0
  181. package/build/workspace/workspace.test.d.ts +1 -0
  182. package/package.json +8 -3
  183. package/build/tools/test-management/uiAnalyzeChangesTool.js +0 -155
  184. package/build/tools/test-management/uiAnalyzeChangesTool.test.js +0 -147
@@ -0,0 +1,12 @@
1
+ import type { OneClickCommandId, OneClickCommandDef } from "../types/OneClickCommands.js";
2
+ export declare function getCommand(id: OneClickCommandId): OneClickCommandDef;
3
+ export declare function getAllCommands(): OneClickCommandDef[];
4
+ export declare function getCommandIds(): OneClickCommandId[];
5
+ /**
6
+ * Look up a command by its string ID. Accepts any string so the tool handler
7
+ * does not need to cast; throws with a helpful message listing valid IDs if
8
+ * the ID is not found.
9
+ */
10
+ export declare function lookupCommand(id: string): OneClickCommandDef;
11
+ export { TEST_GIVEN_ENDPOINT_COMPREHENSIVELY_COMMAND } from "./testThisEndpointCommand.js";
12
+ export { FULLREPO_RECOMMEND_GENERATE_EXECUTE_TOPN_TESTS_COMMAND } from "./recommendTestsAndExecuteCommand.js";
@@ -0,0 +1,2 @@
1
+ import type { OneClickCommandDef } from "../types/OneClickCommands.js";
2
+ export declare const FULLREPO_RECOMMEND_GENERATE_EXECUTE_TOPN_TESTS_COMMAND: OneClickCommandDef;
@@ -0,0 +1,2 @@
1
+ import type { OneClickCommandDef } from "../types/OneClickCommands.js";
2
+ export declare const TEST_GIVEN_ENDPOINT_COMPREHENSIVELY_COMMAND: OneClickCommandDef;
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/build/index.js CHANGED
@@ -24,7 +24,7 @@ import { registerCodeReuseTool } from "./tools/code-refactor/codeReuseTool.js";
24
24
  import { registerEnhanceAssertionsTool } from "./tools/code-refactor/enhanceAssertionsTool.js";
25
25
  import { registerBatchScenarioTestTool } from "./tools/generate-tests/generateBatchScenarioRestTool.js";
26
26
  import { registerMockTool } from "./tools/generate-tests/generateMockRestTool.js";
27
- import { registerAnalyzeChangesTool, registerUiAnalyzeChangesTool, registerAnalyzeTestHealthTool, registerActionsTool, } from "./tools/test-management/index.js";
27
+ import { registerAnalyzeChangesTool, registerAnalyzeTestHealthTool, registerActionsTool, } from "./tools/test-management/index.js";
28
28
  import { registerTestbotPrompt } from "./prompts/testbot/testbot-prompts.js";
29
29
  import { registerTestbotResource } from "./resources/testbotResource.js";
30
30
  import { registerSubmitReportTool } from "./tools/submitReportTool.js";
@@ -152,7 +152,6 @@ codeQualityTools.forEach((registerTool) => registerTool(server));
152
152
  registerAnalysisResources(server);
153
153
  registerProgressResource(server);
154
154
  // Register unified test-management tools (replaces separate test-maintenance tools)
155
- registerUiAnalyzeChangesTool(server);
156
155
  registerAnalyzeChangesTool(server);
157
156
  registerAnalyzeTestHealthTool(server);
158
157
  registerActionsTool(server);
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Service that manages a Playwright TraceRecordingBackend instance,
3
+ * exposing browser tools + skyramp_export_zip for use by the Skyramp MCP.
4
+ *
5
+ * The Playwright fork is CJS; this project is ESM. We use createRequire
6
+ * to bridge the module systems.
7
+ */
8
+ import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
9
+ interface McpTool {
10
+ name: string;
11
+ description?: string;
12
+ inputSchema: Record<string, unknown>;
13
+ [key: string]: unknown;
14
+ }
15
+ export interface PlaywrightTraceOptions {
16
+ /** Run the browser in headless mode. */
17
+ headless?: boolean;
18
+ /** Directory for output files (zip, HAR). Defaults to cwd. */
19
+ outputDir?: string;
20
+ }
21
+ export declare class PlaywrightTraceService {
22
+ private _backend;
23
+ private _tools;
24
+ private _options;
25
+ constructor(options?: PlaywrightTraceOptions);
26
+ initialize(): Promise<void>;
27
+ isInitialized(): boolean;
28
+ getTools(): McpTool[];
29
+ callTool(name: string, args: Record<string, unknown>): Promise<CallToolResult>;
30
+ shutdown(): Promise<void>;
31
+ }
32
+ export {};
@@ -0,0 +1,3 @@
1
+ export { PlaywrightTraceService, type PlaywrightTraceOptions, } from "./PlaywrightTraceService.js";
2
+ export { registerPlaywrightTools, getPlaywrightTraceService, } from "./registerPlaywrightTools.js";
3
+ export { registerTraceRecordingPrompt } from "./traceRecordingPrompt.js";
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Registers all Playwright browser tools (+ skyramp_export_zip) as passthrough
3
+ * tools in the Skyramp MCP server, delegating calls to PlaywrightTraceService.
4
+ */
5
+ import { PlaywrightTraceService, type PlaywrightTraceOptions } from "./PlaywrightTraceService.js";
6
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
7
+ export declare function getPlaywrightTraceService(): PlaywrightTraceService | null;
8
+ export declare function registerPlaywrightTools(server: McpServer, options?: PlaywrightTraceOptions): Promise<void>;
@@ -26,11 +26,17 @@ export async function registerPlaywrightTools(server, options) {
26
26
  // The full set (23 tools) overwhelms the LLM and causes it to use
27
27
  // browser_evaluate/browser_run_code instead of the simpler tools.
28
28
  //
29
- // The DOM Analyzer group (browser_blueprint*, browser_sitemap_*,
30
- // browser_widget_contract_lookup) is referenced by skyramp_testbot's
31
- // Task 1 UI Recommendation Grounding and Task 2 capture-act-capture
32
- // discipline. Omitting them here would silently make the prompt's
33
- // instructions uncallable.
29
+ // browser_blueprint is the only DOM Analyzer tool registered — it handles
30
+ // both full captures and same-URL deltas via the URL-cache (isFullCapture).
31
+ // browser_blueprint_diff, browser_sitemap_build, browser_sitemap_query fire
32
+ // 0 times in production evals and have no active call path in the testbot prompt.
33
+ //
34
+ // browser_widget_contract_lookup / browser_widget_contract_cache are
35
+ // intentionally excluded: the curated fingerprint library only covers
36
+ // test fixtures (not production widgets), and the LLM can handle custom
37
+ // widgets via snapshot-driven trial-and-error without the tool.
38
+ // The widgetType field on blueprint elements still signals "custom" to
39
+ // the agent — no guidance is lost.
34
40
  const ESSENTIAL_TOOLS = new Set([
35
41
  'browser_navigate',
36
42
  'browser_snapshot',
@@ -53,13 +59,8 @@ export async function registerPlaywrightTools(server, options) {
53
59
  'browser_visual_snapshot',
54
60
  'skyramp_export_zip',
55
61
  'skyramp_load_trace',
56
- 'browser_mouse_action',
57
- // DOM Analyzer tools (Phase C)
62
+ // DOM Analyzer: blueprint capture (capture-act-capture pattern)
58
63
  'browser_blueprint',
59
- 'browser_blueprint_diff',
60
- 'browser_sitemap_build',
61
- 'browser_sitemap_query',
62
- 'browser_widget_contract_lookup',
63
64
  ]);
64
65
  const filteredTools = tools.filter((t) => ESSENTIAL_TOOLS.has(t.name));
65
66
  logger.info(`Filtering to ${filteredTools.length} essential tools (from ${tools.length} total)`);
@@ -0,0 +1,13 @@
1
+ /**
2
+ * MCP prompt that guides the LLM through the Playwright-based trace recording
3
+ * and Skyramp test generation flow.
4
+ */
5
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
+ export interface TraceRecordingPromptOpts {
7
+ /** Directory where zip files should be written. Defaults to same dir as test file. */
8
+ outputDir?: string;
9
+ /** Whether to run skyramp_modularization after generation. Default: true. Set false in CI. */
10
+ modularize?: boolean;
11
+ }
12
+ export declare function getTraceRecordingPromptText(opts?: TraceRecordingPromptOpts): string;
13
+ export declare function registerTraceRecordingPrompt(server: McpServer): void;
@@ -42,20 +42,12 @@ Then execute in strict order:
42
42
  - **No Docker required**: the \`browser_*\` tools run a local browser session managed by the MCP server. Docker is ONLY used by \`skyramp_start_trace_collection\` (manual recording mode). Never suggest or check for Docker when using AI-driven recording.
43
43
  ${modularizeNote}
44
44
 
45
- ### Tool discipline — three concepts, don't conflate
45
+ ### Tool discipline — two concepts, don't conflate
46
46
 
47
- These concepts drive the DOM Analyzer capture tools (\`browser_sitemap_build\`, \`browser_sitemap_query\`, \`browser_blueprint\`) and constrain how their outputs flow into generated test code:
47
+ These concepts drive the DOM Analyzer capture tools and constrain how their outputs flow into generated test code:
48
48
 
49
49
  - **\`browser_snapshot\` — ephemeral refs**: the \`ref=e29\` values change on every call. Use them ONLY for dispatching the next 1–2 interactions (\`browser_click\`, \`browser_type\`, etc.). **Never put refs in generated test code** — they will not exist at playback time.
50
- - **\`browser_blueprint\` — stable logical names**: logical names like \`add_order_btn\` and their derived \`getByRole\` locators survive page reloads and playback. Use them in generated test code. Call \`browser_blueprint\` only when the DOM has changed since the last known-good blueprint (modal opens, form submits, filter changes, mutable actions); for pure navigation to an already-crawled URL, reuse the Sitemap cache via \`browser_sitemap_query\`.
51
- - **\`browser_sitemap_build\` — cached once per session**: crawls the whole app into a Sitemap. Call it once at the start of a session; subsequent calls within ~30 minutes reuse the cache unless \`refresh: true\` is passed. Read already-crawled pages via \`browser_sitemap_query\` (modes: \`page\`, \`edges\`, \`mapJson\`, \`outline\`) — do not re-call \`browser_sitemap_build\` to "check."
52
-
53
- ### Tool discipline — delta tools (consumers of captures)
54
-
55
- These consume the outputs of the capture tools above; they don't capture state themselves.
56
-
57
- - **\`browser_blueprint_diff\` — structured before/after delta**: takes two \`browser_blueprint\` results and returns \`elementsAdded\`, \`elementsRemoved\`, \`textChanges\`, \`repeatingCountChanges\`, \`urlChanged\`. Use it to derive assertions from observable state changes rather than guessing at what "success" looks like — capture before an action, perform the action, capture after, diff. An empty diff is itself a meaningful signal (e.g. a silent failure worth catching).
58
- - **\`browser_widget_contract_lookup\` — custom widget interaction recipes**: when a blueprint element has \`widgetType: "custom"\` or \`"unknown"\`, look up its interaction recipe by \`fingerprint\` + \`ref\`. On \`"found"\`, the returned contract specifies the interaction steps (e.g. for a Radix Select: click trigger → wait for portal → click option). On \`"needs_inference"\`, fall through to snapshot-driven trial clicks. Use this so generated tests interact with custom widgets through stable contracts, not brittle positional clicks.
50
+ - **\`browser_blueprint\` — stable logical names**: logical names like \`add_order_btn\` and their derived \`getByRole\` locators survive page reloads and playback. Use them in generated test code. Call \`browser_blueprint\` before and after each meaningful action to capture state changes.
59
51
 
60
52
  ### Assertions
61
53
  Call \`browser_assert\` when assertions are needed. Always provide the \`expected\` value.
@@ -0,0 +1 @@
1
+ export declare function getCodeReusePrompt(testFile: string, language: string, framework?: string): string;
@@ -0,0 +1,2 @@
1
+ import { EnhanceType } from "./sharedAssertionRules.js";
2
+ export declare function getContractProviderAssertionsPrompt(testFile: string, enhanceType: EnhanceType): string;
@@ -0,0 +1,2 @@
1
+ import { EnhanceType } from "./sharedAssertionRules.js";
2
+ export declare function getIntegrationAssertionsPrompt(testFile: string, enhanceType: EnhanceType): string;
@@ -0,0 +1,15 @@
1
+ export type EnhanceType = "generation" | "maintenance";
2
+ export declare const MAINTENANCE_SCOPE_NOTE = "Apply only to new test functions you are adding and existing test functions affected by changes in the diff. Do NOT modify test functions unrelated to the diff.";
3
+ export declare function maintenanceTaskSuffix(enhanceType: EnhanceType): string;
4
+ export interface AssertionEnrichmentExample {
5
+ language: string;
6
+ code: string;
7
+ }
8
+ export interface AssertionEnrichmentRule {
9
+ title: string;
10
+ description: string;
11
+ subPoints?: string[];
12
+ examples: AssertionEnrichmentExample[];
13
+ }
14
+ export declare function renderRule(index: number, rule: AssertionEnrichmentRule): string;
15
+ export declare function getAssertionsPrompt(specificRules: AssertionEnrichmentRule[], scope: string, testFile: string, enhanceType: EnhanceType): string;
@@ -0,0 +1,2 @@
1
+ import { EnhanceType } from "./sharedAssertionRules.js";
2
+ export declare function getUIAssertionsPrompt(testFile: string, enhanceType: EnhanceType): string;
@@ -0,0 +1 @@
1
+ export declare function getFixErrorsPrompt(): string;
@@ -0,0 +1 @@
1
+ export declare const INIT_WORKSPACE_INSTRUCTIONS: string;
@@ -0,0 +1 @@
1
+ export declare function getModularizationPrompt(filePath: string): string;
@@ -0,0 +1 @@
1
+ export declare function getModularizationPrompt(filePath: string): string;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Skyramp personas injected into tool descriptions and prompts.
3
+ *
4
+ * In TestBot environments (SKYRAMP_FEATURE_TESTBOT=1), the persona is injected
5
+ * once via `claude --append-system-prompt` from the testbot GitHub Action
6
+ * (see testbot.git `src/agents/claude.ts` `loadQaPersona()`) rather than
7
+ * repeating it in every tool description. In that case getPersonaPrefix()
8
+ * returns empty string to avoid wasting context tokens. The testbot action
9
+ * pulls SKYRAMP_QA_PERSONA at runtime via the `@skyramp/mcp/personas` export.
10
+ *
11
+ * In IDE/MCP-direct environments, it is included in each tool description so the
12
+ * model has the role context available without a separate system prompt.
13
+ */
14
+ export declare const SKYRAMP_QA_PERSONA = "You are acting as a Skyramp QA Automation Engineer. Your responsibility is to translate user test intent into precise, deterministic test artifacts \u2014 whether generating API tests from specs, recording browser interactions for UI flows, or maintaining existing test suites. Derive all parameters strictly from the codebase, workspace config, API schemas, and page snapshots. Never guess or hallucinate values.";
15
+ /**
16
+ * Returns the persona prefix for use in tool descriptions.
17
+ * Returns an empty string when running inside TestBot — the testbot action
18
+ * appends the persona via `claude --append-system-prompt` instead, so we
19
+ * avoid duplicating it in every tool description.
20
+ */
21
+ export declare function getPersonaPrefix(): string;
@@ -0,0 +1 @@
1
+ export declare function getPomAwareCodeReusePrompt(testFile: string): string;
@@ -0,0 +1,2 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerStartTraceCollectionPrompt(mcpServer: McpServer): void;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Prompt language for skyramp_actions output — the LLM_INSTRUCTIONS block
3
+ * emitted to the agent that applies UPDATE and REGENERATE edits.
4
+ *
5
+ * Kept separate from actionsTool.ts so prompt text is co-located with other
6
+ * maintenance prompts and can be reviewed/edited without touching tool logic.
7
+ */
8
+ export interface RenameEntry {
9
+ oldPath: string;
10
+ newPath: string;
11
+ method: string;
12
+ }
13
+ /** Strategy string for URL-path find-and-replace updates. */
14
+ export declare function buildRenameStrategy(): string;
15
+ /** Strategy string for file renames after path substitution. */
16
+ export declare function buildFileRenameStrategy(): string;
17
+ /** Strategy string for in-place UPDATE edits. */
18
+ export declare function buildUpdateStrategy(): string;
19
+ /** Strategy string for REGENERATE — call generation tool to overwrite the file. */
20
+ export declare function buildRegenerateStrategy(): string;
21
+ /** Per-file instruction block for a single UPDATE recommendation. */
22
+ export declare function buildUpdateFileInstruction(params: {
23
+ testFile: string;
24
+ renames: RenameEntry[];
25
+ suggestedNewFile?: string;
26
+ updateInstructions?: string;
27
+ rationale?: string;
28
+ }): string;
29
+ /** Per-file instruction block for a single REGENERATE recommendation. */
30
+ export declare function buildRegenerateFileInstruction(params: {
31
+ testFile: string;
32
+ updateInstructions?: string;
33
+ outputDir: string;
34
+ outputFile: string;
35
+ }): string;
@@ -0,0 +1,4 @@
1
+ export declare function buildDriftAnalysisPrompt(stateFile?: string, existingTests?: Array<{
2
+ testFile: string;
3
+ source?: string;
4
+ }>): string;
@@ -0,0 +1,13 @@
1
+ export declare function buildActionDecisionTree(): string;
2
+ /** @deprecated use the individual check functions; this function is no longer part of the prompt */
3
+ export declare function buildBreakingChangePatterns(): string;
4
+ export declare function buildCheckEndpointExistence(): string;
5
+ export declare function buildCheckResponseShape(): string;
6
+ export declare function buildCheckAuthAndAuthorization(): string;
7
+ export declare function buildCheckBehavioralContract(): string;
8
+ export declare function buildCheckAssignAction(): string;
9
+ export declare function buildCheckAdditiveFields(): string;
10
+ export declare function buildDriftOutputChecklist(stateFile?: string, existingTests?: Array<{
11
+ testFile: string;
12
+ source?: string;
13
+ }>): string;
@@ -0,0 +1,84 @@
1
+ import { WorkspaceAuthType } from "../../utils/workspaceAuth.js";
2
+ import { ScannedEndpoint } from "../../utils/repoScanner.js";
3
+ /** Lightweight diff summary for the analysis output prompt. */
4
+ interface DiffSummary {
5
+ changedFiles: string[];
6
+ newEndpoints: Array<{
7
+ method: string;
8
+ path: string;
9
+ sourceFile: string;
10
+ }>;
11
+ modifiedEndpoints: Array<{
12
+ method: string;
13
+ path: string;
14
+ sourceFile: string;
15
+ }>;
16
+ removedEndpoints?: Array<{
17
+ method: string;
18
+ path: string;
19
+ sourceFile: string;
20
+ }>;
21
+ }
22
+ interface AnalysisOutputParams {
23
+ sessionId: string;
24
+ stateFile?: string;
25
+ repositoryPath: string;
26
+ analysisScope: string;
27
+ parsedDiff?: DiffSummary;
28
+ /** Path to temp file containing the full unified diff.
29
+ * Content is read once in buildAnalysisOutputText via readDiffFile — callers do not pass diffContent. */
30
+ diffFilePath?: string;
31
+ /** Resolved diff content — populated internally by buildAnalysisOutputText, not by callers. */
32
+ diffContent?: string;
33
+ /**
34
+ * Relative paths of all files whose names look like route/controller definitions.
35
+ * For full-repo scope: the LLM reads these to find endpoints from frameworks the
36
+ * static regex doesn't cover (Django, Axum, Ktor, FastAPI without prefix, etc.).
37
+ */
38
+ candidateRouteFiles?: string[];
39
+ scannedEndpoints: ScannedEndpoint[];
40
+ wsBaseUrl: string;
41
+ wsAuthHeader: string;
42
+ wsAuthType: WorkspaceAuthType | "";
43
+ wsSchemaPath: string;
44
+ /** True when wsSchemaPath was successfully fetched and parsed at analysis time */
45
+ specFetchSucceeded?: boolean;
46
+ routerMountContext: string[];
47
+ /** Content of key routing/mount files, read server-side (size-capped).
48
+ * Present when no spec is available — inlined so LLM doesn't need an extra read step. */
49
+ routerFileContents?: Array<{
50
+ file: string;
51
+ content: string;
52
+ }>;
53
+ nextTool?: string;
54
+ /**
55
+ * Changed files that contain no HTTP endpoint registrations (utilities, helpers,
56
+ * services, models). When non-empty the LLM is instructed to trace callers of
57
+ * the changed functions to find the correct HTTP surface (Fix 2 / Bug 5).
58
+ * Only meaningful in CurrentBranchDiff scope.
59
+ */
60
+ unmatchedFiles?: string[];
61
+ }
62
+ /** "1" — Read source files / changed files */
63
+ export declare const ANALYSIS_STEP_READ_FILES: string;
64
+ /** "1.1" — Verify/build/validate endpoint path resolution table */
65
+ export declare const ANALYSIS_STEP_RESOLVE_PATHS: string;
66
+ /** "2" — Extract or map endpoints */
67
+ export declare const ANALYSIS_STEP_EXTRACT: string;
68
+ /** "3" — Draft scenarios / present catalog / identify drift */
69
+ export declare const ANALYSIS_STEP_DRAFT: string;
70
+ /** "4" — Call the downstream tool (recommend_tests / analyze_test_health) */
71
+ export declare const ANALYSIS_STEP_CALL_TOOL: string;
72
+ /**
73
+ * Returns the step label for the trace-callers sub-step given runtime params.
74
+ * Returns "2.1" when the step is active (non-frontend unmatched backend files
75
+ * present in diff scope), or null when the step is absent.
76
+ *
77
+ * Use in tests instead of hardcoding "2.1":
78
+ * const label = getStepTraceCallers(params);
79
+ * if (label) expect(output).toContain(`### Step ${label}: Trace callers`);
80
+ * else expect(output).not.toContain("Trace callers");
81
+ */
82
+ export declare function getStepTraceCallers(p: AnalysisOutputParams): string | null;
83
+ export declare function buildAnalysisOutputText(p: AnalysisOutputParams): string;
84
+ export {};
@@ -1,3 +1,4 @@
1
+ import { jest } from "@jest/globals";
1
2
  jest.mock("@skyramp/skyramp", () => ({
2
3
  WorkspaceConfigManager: { create: jest.fn() },
3
4
  }));
@@ -0,0 +1,17 @@
1
+ import { DraftedScenario } from "../../types/RepositoryAnalysis.js";
2
+ import { PriorityTier } from "../../types/TestRecommendation.js";
3
+ /** "0" — Code Review: correctness analysis */
4
+ export declare const EXEC_STEP_CODE_REVIEW: string;
5
+ /** "1" — External test coverage verification */
6
+ export declare const EXEC_STEP_COVERAGE: string;
7
+ /** "2" — Parameter grounding & priority assignment */
8
+ export declare const EXEC_STEP_ENRICH: string;
9
+ /** "3" — Diversity check */
10
+ export declare const EXEC_STEP_DIVERSITY: string;
11
+ /** "4" — Execute merged plan */
12
+ export declare const EXEC_STEP_EXECUTE: string;
13
+ export declare function buildExecutionPlan(scored: Array<{
14
+ scenario: DraftedScenario;
15
+ priority: PriorityTier;
16
+ novelty: string;
17
+ }>, maxGen: number, topN: number, baseUrl: string, authHeaderValue: string, authSchemeSnippet: string, authTypeValue: string, seed: string, endpointCount: number, isUIOnlyPR: boolean, hasFrontendChanges?: boolean, hasTraces?: boolean, externalCoverage?: Set<string>, relevantExternalTestPaths?: string[]): string;
@@ -345,27 +345,18 @@ export function buildExecutionPlan(scored, maxGen, topN, baseUrl, authHeaderValu
345
345
  // frozen, but the `reasoning` CONTENT for UI entries should be blueprint-
346
346
  // grounded using concrete elements the agent captured via browser_blueprint.
347
347
  const uiGroundingGuidance = hasFrontendChanges ? `
348
- **UI recommendation grounding — applies to \`testType: "ui"\` entries.** The \`reasoning\` field for \`testType: "ui"\` entries MUST contain at least three of {\`role\`, \`accessibleName\`, \`testId\`, \`stableId\`, \`logicalName\`} cited in key=value form. Entries that omit the tuple are not valid output for UI test types. The agent should call \`browser_blueprint\` on affected pages (if it hasn't already) and use the captured data.
348
+ **UI recommendation grounding — applies to \`testType: "ui"\` entries in BOTH \`newTestsCreated\` and \`additionalRecommendations\`.** UI recommendations must populate three structured fields plus prose fields, all derived from captured \`browser_blueprint\` elements:
349
349
 
350
- **Field stability note for consumers:** \`testId\` and \`stableId\` are stable identifiers (from \`data-testid\` and unique \`id\` attributes respectively) code-generation consumers can key off them. \`role\` and \`accessibleName\` are derived from ARIA and survive DOM reshuffles. \`logicalName\` is a **display handle, not a stable identifier** — it's derived from role + accessibleName + section context and drifts when the accessibleName text changes. Cite \`logicalName\` for readability in the \`reasoning\` field, but downstream consumers (test generators, scoping tools) should NOT key off it. Prefer \`testId\` > \`stableId\` > \`role + accessibleName\` > \`fingerprint\` for identity.
351
-
352
- **Format for singular elements:**
353
- > role=<role>, accessibleName="<Accessible Name>", testId=<test-id-or-null>, stableId=<id-or-null>, logicalName=<logical_name>
354
-
355
- **Format for repeating elements (table rows, list items):** include \`contextText\` values from the row when the recommendation targets a specific row:
356
- > role=<role>, accessibleName="<template>", testId=<null>, stableId=<null>, logicalName=<name>, contextText=["customer@example.com", "$129.99", "Pending"]
357
-
358
- **Example (Edit Order form's Save button on /orders/{id}):**
359
- > role=button, accessibleName="Save changes", testId=null, stableId=null, logicalName=save_changes_btn — verifies boundary-value clamping on discount_percent (0..100)
360
-
361
- **Example (new-order-row recommendation on /orders):**
362
- > role=button, accessibleName="View details for order 13", testId=null, stableId=null, logicalName=view_details_for_order_btn, contextText=["customer@example.com", "$129.99", "Pending"] — verifies new order row renders with correct customer + total + status
350
+ - **\`targetElements\`**array of one or more elements (\`role\`, \`accessibleName\`, \`testId\`, \`stableId\`, \`contextText\`, \`mutability\`, \`widgetType\`). Single-element for tests with one dominant target; multi-element for render-state, multi-step, or form tests.
351
+ - **\`pageContext\`** — \`url\` and \`pageHash\` from the BlueprintCapture.
352
+ - **\`description\`** walkthrough of the test steps and assertions (what the test does, not why it is valuable).
353
+ - **\`reasoning\`** — free-form prose grounded in \`targetElements\` explaining why this test is valuable. Every element cited must appear in \`targetElements\` by its \`accessibleName\` (bolded, character-for-character). See the Blueprint Citation Invariant in the Testbot prompt (step 4) for citation rules, identifier priority (\`testId\` > \`stableId\` > \`role + accessibleName\`), repeating-element format (\`contextText\` parenthetical), and self-check guidance.
363
354
 
364
355
  **Validates line — applies to \`testType: "ui"\` entries.** The \`Validates:\` line for UI entries should describe an observable behavior the test verifies — what changes on the page after the action, or what state the user can see. Ground this description in the captured blueprint when possible. Reference structural facts (an element appears, a count changes, a status text updates, a URL transitions) rather than implementation language (component names, props, internal state). The line should be readable to someone who has not seen the source diff.
365
356
 
366
- **Scope clarification:** this grounding format applies **only** to \`testType: "ui"\` entries. Contract, integration, e2e, batch-scenario \`reasoning\` and \`Validates:\` fields use their existing conventions (endpoint paths, schemas, fixture chains) — do NOT reformat those. The "Fill in placeholders, then display verbatim" rule above refers to the CATALOG STRUCTURE (sections, ordering, test types); UI entries' \`reasoning\` and \`Validates:\` CONTENT follows this grounding format.
357
+ **Scope clarification:** this grounding rule applies **only** to \`testType: "ui"\` entries. Contract, integration, e2e, batch-scenario \`reasoning\` and \`Validates:\` fields use their existing conventions (endpoint paths, schemas, fixture chains) — do NOT reformat those. The "Fill in placeholders, then display verbatim" rule above refers to the CATALOG STRUCTURE (sections, ordering, test types); UI entries' \`reasoning\` and \`Validates:\` CONTENT follows this grounding rule.
367
358
 
368
- **If blueprint data isn't available** — agent skipped pre-scan, app unreachable, \`BlueprintInvariantError\`, or no candidate page covers the changed component — UI entries may fall back to source-grounded reasoning. Each such entry MUST be flagged with a leading \`[no-blueprint-data]\` marker in the \`reasoning\` field, and the failure mode must be logged in \`issuesFound\` with \`info\` severity naming the entry. Do NOT silently produce ungrounded reasoning without the marker.
359
+ **If blueprint data isn't available** — agent skipped pre-scan, app unreachable, \`BlueprintInvariantError\`, or no candidate page covers the changed component — UI entries must fall back as follows: set \`targetElements: null\`, omit \`pageContext\`, prefix BOTH \`description\` and \`reasoning\` with \`[no-blueprint-data]\`, and log the failure in \`issuesFound\` with \`info\` severity. Do NOT silently produce ungrounded reasoning without the marker in both fields.
369
360
  ` : "";
370
361
  // UI/E2E guidance — the LLM adds as many as its Budget Plan calls for.
371
362
  // Note: if a UI test already occupies a GENERATE slot (uiPlaceholderBlock), that slot
@@ -0,0 +1,7 @@
1
+ import { DraftedScenario } from "../../types/RepositoryAnalysis.js";
2
+ import { PriorityTier } from "../../types/TestRecommendation.js";
3
+ export declare function buildFullRepoRecommendations(scored: Array<{
4
+ scenario: DraftedScenario;
5
+ priority: PriorityTier;
6
+ novelty: string;
7
+ }>, topN: number, baseUrl: string, authHeaderValue: string, authSchemeSnippet: string, authTypeValue: string, isFrontendProject?: boolean, isFrontendOnlyProject?: boolean, externalCoverage?: Set<string>): string;
@@ -1,3 +1,4 @@
1
+ import { jest } from "@jest/globals";
1
2
  jest.mock("@skyramp/skyramp", () => ({ Skyramp: class {
2
3
  } }));
3
4
  import { mergeEnrichedScenarios } from "./registerRecommendTestsPrompt.js";