@skyramp/mcp 0.2.6 → 0.2.150-rc.mntnc

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 (233) 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 +6 -4
  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/enhance-assertions/uiAssertionsPrompt.js +24 -5
  18. package/build/prompts/fix-error-prompt.d.ts +1 -0
  19. package/build/prompts/initialize-workspace/initializeWorkspacePrompt.d.ts +1 -0
  20. package/build/prompts/modularization/integration-test-modularization.d.ts +1 -0
  21. package/build/prompts/modularization/ui-test-modularization.d.ts +1 -0
  22. package/build/prompts/personas.d.ts +21 -0
  23. package/build/prompts/pom-aware-code-reuse.d.ts +1 -0
  24. package/build/prompts/startTraceCollectionPrompts.d.ts +2 -0
  25. package/build/prompts/sut-setup/modes/adaptWorkflowPrompt.d.ts +2 -0
  26. package/build/prompts/sut-setup/modes/adaptWorkflowPrompt.js +114 -0
  27. package/build/prompts/sut-setup/modes/dockerComposePrompt.d.ts +2 -0
  28. package/build/prompts/sut-setup/modes/dockerComposePrompt.js +292 -0
  29. package/build/prompts/sut-setup/shared.d.ts +39 -0
  30. package/build/prompts/sut-setup/shared.js +132 -0
  31. package/build/prompts/test-maintenance/actionsInstructions.d.ts +35 -0
  32. package/build/prompts/test-maintenance/drift-analysis-prompt.d.ts +4 -0
  33. package/build/prompts/test-maintenance/driftAnalysisSections.d.ts +13 -0
  34. package/build/prompts/test-maintenance/driftAnalysisSections.js +9 -3
  35. package/build/prompts/test-recommendation/analysisOutputPrompt.d.ts +84 -0
  36. package/build/prompts/test-recommendation/analysisOutputPrompt.js +1 -1
  37. package/build/prompts/test-recommendation/analysisOutputPrompt.test.d.ts +1 -0
  38. package/build/prompts/test-recommendation/analysisOutputPrompt.test.js +1 -0
  39. package/build/prompts/test-recommendation/diffExecutionPlan.d.ts +17 -0
  40. package/build/prompts/test-recommendation/diffExecutionPlan.js +7 -16
  41. package/build/prompts/test-recommendation/fullRepoCatalog.d.ts +7 -0
  42. package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.d.ts +1 -0
  43. package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.js +1 -0
  44. package/build/prompts/test-recommendation/promptPlan.d.ts +203 -0
  45. package/build/prompts/test-recommendation/promptPlan.test.d.ts +1 -0
  46. package/build/prompts/test-recommendation/recommendationSections.d.ts +35 -0
  47. package/build/prompts/test-recommendation/recommendationShared.d.ts +31 -0
  48. package/build/prompts/test-recommendation/registerRecommendTestsPrompt.d.ts +7 -0
  49. package/build/prompts/test-recommendation/scopeAssessment.d.ts +55 -0
  50. package/build/prompts/test-recommendation/scopeAssessment.js +2 -2
  51. package/build/prompts/test-recommendation/scopeAssessment.test.d.ts +1 -0
  52. package/build/prompts/test-recommendation/scopeAssessment.test.js +1 -0
  53. package/build/prompts/test-recommendation/test-recommendation-prompt.d.ts +6 -0
  54. package/build/prompts/test-recommendation/test-recommendation-prompt.js +4 -4
  55. package/build/prompts/test-recommendation/test-recommendation-prompt.test.d.ts +1 -0
  56. package/build/prompts/test-recommendation/test-recommendation-prompt.test.js +6 -99
  57. package/build/prompts/testbot/testbot-prompts.d.ts +11 -0
  58. package/build/prompts/testbot/testbot-prompts.js +213 -42
  59. package/build/prompts/testbot/testbot-prompts.test.d.ts +1 -0
  60. package/build/prompts/testbot/testbot-prompts.test.js +15 -117
  61. package/build/resources/analysisResources.d.ts +17 -0
  62. package/build/resources/progressResource.d.ts +2 -0
  63. package/build/resources/sutSetupResource.d.ts +2 -0
  64. package/build/resources/sutSetupResource.js +45 -0
  65. package/build/resources/testbotResource.d.ts +2 -0
  66. package/build/resources/testbotResource.js +1 -1
  67. package/build/services/AnalyticsService.d.ts +13 -0
  68. package/build/services/AnalyticsService.test.d.ts +1 -0
  69. package/build/services/AnalyticsService.test.js +86 -0
  70. package/build/services/ModularizationService.d.ts +11 -0
  71. package/build/services/ScenarioGenerationService.d.ts +37 -0
  72. package/build/services/ScenarioGenerationService.integration.test.d.ts +1 -0
  73. package/build/services/ScenarioGenerationService.integration.test.js +4 -0
  74. package/build/services/ScenarioGenerationService.test.d.ts +1 -0
  75. package/build/services/TestDiscoveryService.d.ts +128 -0
  76. package/build/services/TestDiscoveryService.js +22 -12
  77. package/build/services/TestDiscoveryService.test.d.ts +1 -0
  78. package/build/services/TestDiscoveryService.test.js +4 -3
  79. package/build/services/TestExecutionService.d.ts +55 -0
  80. package/build/services/TestExecutionService.js +158 -26
  81. package/build/services/TestExecutionService.test.d.ts +1 -0
  82. package/build/services/TestExecutionService.test.js +339 -25
  83. package/build/services/TestGenerationService.d.ts +56 -0
  84. package/build/services/TestGenerationService.test.d.ts +1 -0
  85. package/build/services/TestGenerationService.test.js +10 -8
  86. package/build/services/containerEnv.d.ts +14 -0
  87. package/build/tool-phase-coverage.test.d.ts +1 -0
  88. package/build/tool-phase-coverage.test.js +2 -0
  89. package/build/tool-phases.d.ts +38 -0
  90. package/build/tools/auth/loginTool.d.ts +2 -0
  91. package/build/tools/auth/logoutTool.d.ts +2 -0
  92. package/build/tools/code-refactor/codeReuseTool.d.ts +2 -0
  93. package/build/tools/code-refactor/enhanceAssertionsTool.d.ts +2 -0
  94. package/build/tools/code-refactor/modularizationTool.d.ts +2 -0
  95. package/build/tools/executeSkyrampTestTool.d.ts +2 -0
  96. package/build/tools/executeSkyrampTestTool.js +17 -4
  97. package/build/tools/fixErrorTool.d.ts +2 -0
  98. package/build/tools/generate-tests/generateBatchScenarioRestTool.d.ts +45 -0
  99. package/build/tools/generate-tests/generateBatchScenarioRestTool.js +1 -1
  100. package/build/tools/generate-tests/generateBatchScenarioRestTool.test.d.ts +1 -0
  101. package/build/tools/generate-tests/generateBatchScenarioRestTool.test.js +11 -9
  102. package/build/tools/generate-tests/generateContractRestTool.d.ts +31 -0
  103. package/build/tools/generate-tests/generateE2ERestTool.d.ts +13 -0
  104. package/build/tools/generate-tests/generateFuzzRestTool.d.ts +10 -0
  105. package/build/tools/generate-tests/generateIntegrationRestTool.d.ts +16 -0
  106. package/build/tools/generate-tests/generateLoadRestTool.d.ts +18 -0
  107. package/build/tools/generate-tests/generateLoadRestTool.test.d.ts +1 -0
  108. package/build/tools/generate-tests/generateMockRestTool.d.ts +64 -0
  109. package/build/tools/generate-tests/generateSmokeRestTool.d.ts +8 -0
  110. package/build/tools/generate-tests/generateUIRestTool.d.ts +14 -0
  111. package/build/tools/generate-tests/generateUIRestTool.js +1 -1
  112. package/build/tools/generate-tests/loadTestSchema.d.ts +39 -0
  113. package/build/tools/one-click/oneClickTool.d.ts +11 -0
  114. package/build/tools/submitReportTool.d.ts +384 -0
  115. package/build/tools/submitReportTool.js +225 -37
  116. package/build/tools/submitReportTool.test.d.ts +1 -0
  117. package/build/tools/submitReportTool.test.js +479 -55
  118. package/build/tools/test-management/actionsTool.d.ts +10 -0
  119. package/build/tools/test-management/actionsTool.js +10 -0
  120. package/build/tools/test-management/analyzeChangesTool.d.ts +26 -0
  121. package/build/tools/test-management/analyzeChangesTool.js +128 -48
  122. package/build/tools/test-management/analyzeChangesTool.test.d.ts +1 -0
  123. package/build/tools/test-management/analyzeChangesTool.test.js +80 -73
  124. package/build/tools/test-management/analyzeTestHealthTool.d.ts +2 -0
  125. package/build/tools/test-management/analyzeTestHealthTool.js +6 -3
  126. package/build/tools/test-management/index.d.ts +3 -0
  127. package/build/tools/test-management/index.js +0 -1
  128. package/build/tools/trace/resolveSaveStoragePath.d.ts +7 -0
  129. package/build/tools/trace/resolveSaveStoragePath.test.d.ts +1 -0
  130. package/build/tools/trace/resolveSessionPaths.d.ts +40 -0
  131. package/build/tools/trace/resolveSessionPaths.test.d.ts +1 -0
  132. package/build/tools/trace/sessionState.d.ts +2 -0
  133. package/build/tools/trace/sessionState.test.d.ts +1 -0
  134. package/build/tools/trace/startTraceCollectionTool.d.ts +2 -0
  135. package/build/tools/trace/stopTraceCollectionTool.d.ts +2 -0
  136. package/build/tools/workspace/initScanWorkspaceTool.d.ts +4 -0
  137. package/build/tools/workspace/initializeWorkspaceTool.d.ts +2 -0
  138. package/build/tools/workspace/initializeWorkspaceTool.test.d.ts +1 -0
  139. package/build/tools/workspace/initializeWorkspaceTool.test.js +134 -0
  140. package/build/types/OneClickCommands.d.ts +68 -0
  141. package/build/types/RepositoryAnalysis.d.ts +3004 -0
  142. package/build/types/TestAnalysis.d.ts +97 -0
  143. package/build/types/TestExecution.d.ts +63 -0
  144. package/build/types/TestExecution.js +11 -1
  145. package/build/types/TestRecommendation.d.ts +12 -0
  146. package/build/types/TestTypes.d.ts +234 -0
  147. package/build/types/TestbotReport.d.ts +68 -0
  148. package/build/types/TestbotReport.js +1 -0
  149. package/build/types/index.d.ts +4 -0
  150. package/build/types/index.js +3 -0
  151. package/build/utils/AnalysisStateManager.d.ts +182 -0
  152. package/build/utils/AnalysisStateManager.js +10 -1
  153. package/build/utils/AnalysisStateManager.test.d.ts +1 -0
  154. package/build/utils/analyze-openapi.d.ts +1 -0
  155. package/build/utils/branchDiff.d.ts +18 -0
  156. package/build/utils/dartRouteExtractor.d.ts +45 -0
  157. package/build/utils/dartRouteExtractor.test.d.ts +1 -0
  158. package/build/utils/docker.d.ts +19 -0
  159. package/build/utils/docker.test.d.ts +1 -0
  160. package/build/utils/docker.test.js +10 -9
  161. package/build/utils/featureFlags.d.ts +37 -0
  162. package/build/utils/featureFlags.test.d.ts +1 -0
  163. package/build/utils/gitStaging.d.ts +24 -0
  164. package/build/utils/gitStaging.test.d.ts +1 -0
  165. package/build/utils/gitStaging.test.js +13 -7
  166. package/build/utils/httpDefaults.d.ts +10 -0
  167. package/build/utils/httpDefaults.test.d.ts +1 -0
  168. package/build/utils/initAgent.d.ts +36 -0
  169. package/build/utils/language-helper.d.ts +6 -0
  170. package/build/utils/logger.d.ts +11 -0
  171. package/build/utils/normalizeParams.d.ts +14 -0
  172. package/build/utils/normalizeSkyrampImports.d.ts +13 -0
  173. package/build/utils/pr-comment-parser.d.ts +31 -0
  174. package/build/utils/pr-comment-parser.test.d.ts +1 -0
  175. package/build/utils/pr-comment-parser.test.js +6 -5
  176. package/build/utils/projectMetadata.d.ts +15 -0
  177. package/build/utils/projectMetadata.test.d.ts +1 -0
  178. package/build/utils/proxy-terminal.d.ts +2 -0
  179. package/build/utils/repoScanner.d.ts +27 -0
  180. package/build/utils/repoScanner.test.d.ts +1 -0
  181. package/build/utils/routeParsers.d.ts +53 -0
  182. package/build/utils/routeParsers.js +31 -38
  183. package/build/utils/routeParsers.test.d.ts +1 -0
  184. package/build/utils/scenarioDrafting.d.ts +71 -0
  185. package/build/utils/scenarioDrafting.js +23 -1
  186. package/build/utils/scenarioDrafting.test.d.ts +1 -0
  187. package/build/utils/skyrampMdContent.d.ts +5 -0
  188. package/build/utils/sourceRouteExtractor.d.ts +48 -0
  189. package/build/utils/sourceRouteExtractor.test.d.ts +1 -0
  190. package/build/utils/telemetry.d.ts +32 -0
  191. package/build/utils/telemetry.test.d.ts +1 -0
  192. package/build/utils/trace-parser.d.ts +32 -0
  193. package/build/utils/trace-parser.test.d.ts +6 -0
  194. package/build/utils/uiPageEnumerator.d.ts +146 -0
  195. package/build/utils/uiPageEnumerator.js +58 -14
  196. package/build/utils/uiPageEnumerator.test.d.ts +1 -0
  197. package/build/utils/uiPageEnumerator.test.js +223 -43
  198. package/build/utils/utils.d.ts +45 -0
  199. package/build/utils/utils.js +10 -0
  200. package/build/utils/utils.test.d.ts +1 -0
  201. package/build/utils/versions.d.ts +3 -0
  202. package/build/utils/versions.js +1 -1
  203. package/build/utils/workspaceAuth.d.ts +127 -0
  204. package/build/utils/workspaceAuth.test.d.ts +1 -0
  205. package/build/utils/workspaceAuth.test.js +25 -25
  206. package/build/workspace/index.d.ts +1 -0
  207. package/build/workspace/workspace.d.ts +390 -0
  208. package/build/workspace/workspace.test.d.ts +1 -0
  209. package/node_modules/playwright/LICENSE +202 -0
  210. package/node_modules/playwright/NOTICE +5 -0
  211. package/node_modules/playwright/README.md +168 -0
  212. package/node_modules/playwright/lib/mcp/skyramp/traceRecordingBackend.js +13 -9
  213. package/node_modules/playwright/lib/mcp/test/skyRampExport.js +4 -3
  214. package/node_modules/playwright/node_modules/playwright-core/LICENSE +202 -0
  215. package/node_modules/playwright/node_modules/playwright-core/NOTICE +5 -0
  216. package/node_modules/playwright/node_modules/playwright-core/ThirdPartyNotices.txt +23 -126
  217. package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/assets/{codeMirrorModule-B0JOjboO.js → codeMirrorModule-B5kqh2EV.js} +1 -1
  218. package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/assets/{defaultSettingsView-1anWeyDf.js → defaultSettingsView-CZ9npQ3N.js} +79 -79
  219. package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/{index.Cc5029a3.js → index.BCnxj-_b.js} +1 -1
  220. package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/index.html +2 -2
  221. package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/{uiMode.Wo5yvvVh.js → uiMode.1Ym0Ivn8.js} +1 -1
  222. package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/uiMode.html +2 -2
  223. package/node_modules/playwright/node_modules/playwright-core/package.json +1 -1
  224. package/node_modules/playwright/package.json +1 -1
  225. package/package.json +16 -4
  226. package/build/tools/test-management/uiAnalyzeChangesTool.js +0 -155
  227. package/build/tools/test-management/uiAnalyzeChangesTool.test.js +0 -147
  228. package/node_modules/playwright/node_modules/playwright-core/.DS_Store +0 -0
  229. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/.bin/node-which +0 -52
  230. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/.bin/is-docker +0 -5
  231. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/.bin/mime +0 -46
  232. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/.bin/yaml +0 -11
  233. package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/index.CP3Y8Zsb.js +0 -2
@@ -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,8 +24,9 @@ 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
+ import { registerSutSetupResource } from "./resources/sutSetupResource.js";
29
30
  import { registerTestbotResource } from "./resources/testbotResource.js";
30
31
  import { registerSubmitReportTool } from "./tools/submitReportTool.js";
31
32
  import { registerInitializeWorkspaceTool } from "./tools/workspace/initializeWorkspaceTool.js";
@@ -123,7 +124,9 @@ const prompts = [
123
124
  if (isTestbotEnabled()) {
124
125
  prompts.push(registerTestbotPrompt);
125
126
  registerTestbotResource(server);
126
- logger.info("TestBot prompt enabled via SKYRAMP_FEATURE_TESTBOT");
127
+ logger.info("Testbot prompt enabled via SKYRAMP_FEATURE_TESTBOT");
128
+ registerSutSetupResource(server);
129
+ logger.info("Testbot SUT setup resource enabled via SKYRAMP_FEATURE_TESTBOT");
127
130
  }
128
131
  prompts.forEach((registerPrompt) => registerPrompt(server));
129
132
  logger.info("All prompts registered successfully");
@@ -152,7 +155,6 @@ codeQualityTools.forEach((registerTool) => registerTool(server));
152
155
  registerAnalysisResources(server);
153
156
  registerProgressResource(server);
154
157
  // Register unified test-management tools (replaces separate test-maintenance tools)
155
- registerUiAnalyzeChangesTool(server);
156
158
  registerAnalyzeChangesTool(server);
157
159
  registerAnalyzeTestHealthTool(server);
158
160
  registerActionsTool(server);
@@ -174,7 +176,7 @@ const infrastructureTools = [
174
176
  ];
175
177
  if (isTestbotEnabled()) {
176
178
  infrastructureTools.push(registerSubmitReportTool);
177
- logger.info("TestBot tools enabled via SKYRAMP_FEATURE_TESTBOT");
179
+ logger.info("Testbot tools enabled via SKYRAMP_FEATURE_TESTBOT");
178
180
  }
179
181
  infrastructureTools.forEach((registerTool) => registerTool(server));
180
182
  // Register Playwright browser tools (trace recording via browser automation)
@@ -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;
@@ -186,21 +186,40 @@ await page.context().addInitScript(() => {
186
186
  });
187
187
  \`\`\`
188
188
 
189
- And immediately after **every** \`page.goto()\` call in the test, add exactly these two statements — do NOT substitute a different activation approach or a different \`waitForFunction\` body:
189
+ And immediately after **every** \`page.goto()\` call in the test, add exactly these three statements — do NOT substitute a different activation approach or different \`waitForFunction\` bodies:
190
190
 
191
191
  \`\`\`typescript
192
+ // Wait for Flutter to bootstrap (confirms Flutter engine is ready before activating)
193
+ await page.waitForFunction(
194
+ () => !!document.querySelector('flt-semantics-placeholder, flt-glass-pane, flutter-view'),
195
+ undefined,
196
+ { timeout: 30000 }
197
+ );
192
198
  // Activate Flutter accessibility semantics by clicking the hidden placeholder
193
199
  await page.evaluate(() => { const el = document.querySelector('flt-semantics-placeholder'); if (el) el.dispatchEvent(new MouseEvent('click', { isTrusted: true, bubbles: true, cancelable: true })); });
194
- // Wait for Flutter semantics tree to be fully populated before interacting
200
+ // Wait for the semantics tree to be live: the activation placeholder is gone AND
201
+ // at least one flt-semantics node exists. Requiring a populated tree (not just the
202
+ // placeholder's absence) guards against a vacuous pass when the bootstrap wait
203
+ // above resolved on flt-glass-pane/flutter-view before the placeholder ever mounted.
195
204
  await page.waitForFunction(
196
- () => document.querySelector('flt-semantics-host')?.children?.length > 0,
205
+ () => document.querySelector('flt-semantics-placeholder') === null
206
+ && document.querySelector('flt-semantics') !== null,
207
+ undefined,
197
208
  { timeout: 20000 }
198
209
  );
199
210
  \`\`\`
200
211
 
201
- The \`waitForFunction\` check MUST be \`children?.length > 0\` (tree populated), NOT \`!!document.querySelector('flt-semantics-host')\` (tree merely exists it appears immediately but empty). If you see an existing body click or \`locator.click\` block after a goto, replace the entire block with the exact two statements above.
212
+ Use exactly the three statements above. Do NOT use the two-argument form \`waitForFunction(fn, { timeout })\` the timeout must be the third argument with \`undefined\` as the second. If you see an existing body click, \`locator.click\`, or old-style \`waitForFunction\` after a goto, replace the entire block with the exact three statements above.
213
+
214
+ This is required because Flutter web renders to a \`<canvas>\` element (no traditional DOM). The first \`waitForFunction\` ensures Flutter has bootstrapped before activation; the \`dispatchEvent\` activates semantics; the second \`waitForFunction\` confirms the semantics tree is live (placeholder removed **and** \`flt-semantics\` nodes present). The combined gate handles both modes — when accessibility is pre-enabled (semantics active from frame 1, no placeholder ever shown) and when activation depends on the click — without passing prematurely on a frame where neither has happened yet.
202
215
 
203
- This is required because Flutter web accessibility semantics are not activated by default in headless Chromium. The \`isTrusted\` patch makes synthetic click events trusted; the \`dispatchEvent\` call triggers Flutter to build the ARIA tree; the \`children?.length > 0\` wait ensures the tree is fully populated before any \`getByRole\` queries or \`click()\` calls run. Without all three (patch + dispatchEvent + populated wait), Flutter interactions will time out in CI/Docker execution.
216
+ **Then wait for the first element you interact with.** The gate above confirms the semantics tree *started* building, but Flutter populates it incrementally — individual widgets (a textbox, a button) can still be a beat behind when the gate passes, especially on a cold start where accessibility was not pre-enabled. The wrapped Skyramp page also enforces a short internal action timeout, so a lagging widget fails fast rather than waiting out the page default. Guard against this: immediately after the activation block (and after any later \`page.goto()\`'s block), add an explicit \`waitFor\` on the **first locator the test interacts with on that page**, before the interaction itself. Example:
217
+ \`\`\`typescript
218
+ // Wait for the specific target to be present before interacting (tree may still be filling in)
219
+ await page.getByRole('textbox', { name: 'Username' }).waitFor({ state: 'visible', timeout: 20000 });
220
+ await page.getByRole('textbox', { name: 'Username' }).fill('admin');
221
+ \`\`\`
222
+ Use the **same locator** that the next interaction uses — do not invent a new selector. This waits for exactly the widget the test needs, which is more reliable than any generic tree-node count (those are app-specific magic numbers); it is the per-target wait that Flutter-web automation guidance recommends over a one-size-fits-all readiness check.
204
223
 
205
224
  **Also check for brittle flt-semantic-node-* selectors:** If the test uses \`page.locator("#flt-semantic-node-N")\` for any interaction (clicks, navigations), replace it with a semantic selector (\`getByRole\`, \`getByText\`, or \`getByLabel\`) — \`flt-semantic-node-N\` IDs change between sessions and across devices, making the test brittle. Example: replace \`page.locator("#flt-semantic-node-78").click()\` with \`page.getByText("Settings").click()\` using the visible label from the same line's context.
206
225
 
@@ -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,2 @@
1
+ import { type SutPromptArgs } from "../shared.js";
2
+ export declare function getAdaptWorkflowPrompt(args: SutPromptArgs): string;
@@ -0,0 +1,114 @@
1
+ import { TESTBOT_WORKFLOW_PATH, buildContextBlock, buildCommonSutErrorsSection, buildLocalValidationSection, buildInputsBody, buildSutDefinitionBlock, } from "../shared.js";
2
+ import { getPersonaPrefix } from "../../personas.js";
3
+ import { PromptPlan } from "../../test-recommendation/promptPlan.js";
4
+ // ── Step body builders ────────────────────────────────────────────────────────
5
+ function buildReadSourcesBody(args) {
6
+ return args.sutSourceWorkflowFile
7
+ ? `Read the given source GitHub workflow file \`${args.sutSourceWorkflowFile}\` (the user's hint about which steps to lift), then ALSO read the rest of \`.github/workflows/\` and all infrastructure files (docker-compose, Kubernetes manifests, Helm charts) — the full SUT shape often lives across multiple files, so do NOT tunnel into the source workflow alone. Workflows show *how* the SUT is started; infrastructure files show *what* the SUT is. When a workflow step references an infra file (e.g., \`docker compose -f infra/compose.yml up\`, \`helm upgrade <chart>\`, \`kubectl apply -f k8s/\`), open that file too — services, ports, env vars, and dependencies live there.`
8
+ : `Read all GitHub workflow files in \`.github/workflows/\` AND all infrastructure files (docker-compose, Kubernetes manifests, Helm charts). Workflows show *how* the SUT is started; infrastructure files show *what* the SUT is. When a workflow step references an infra file (e.g., \`docker compose -f infra/compose.yml up\`, \`helm upgrade <chart>\`, \`kubectl apply -f k8s/\`), open that file too — services, ports, env vars, and dependencies live there. Pick the source workflow (the one whose SETUP/TEST/TEARDOWN steps will be lifted) once you have the full picture.`;
9
+ }
10
+ function buildClassifyStepsBody() {
11
+ return `From the source workflow, classify each step by its *purpose* — not by its name or surface mechanism (\`env:\`, \`with:\`, and \`\${{ secrets.* }}\` can appear on any category and do not determine it):
12
+ a. SETUP — prepares the SUT (install, build, start services, migrate, seed, configure env or inject secrets for the SUT). Common attributes: \`env:\` blocks (e.g. \`DATABASE_URL\`, build flags), \`with:\` parameters (e.g. \`actions/cache\`, \`actions/setup-node\`), \`\${{ secrets.* }}\` references (e.g. registry login, deploy keys), dependency installs (e.g. \`npm ci\` before build).
13
+ b. TEST — runs the test suite (will be replaced by \`skyramp/testbot\`). Common attributes: \`env:\` blocks (e.g. \`API_BASE_URL\`, \`AUTH_TOKEN\`), \`with:\` parameters (e.g. \`actions/cache\`, custom test-runner actions), \`\${{ secrets.* }}\` references (e.g. test credentials, live-integration keys), dependency installs (e.g. \`npm ci\` right before \`npm test\` in the same step).
14
+ c. TEARDOWN — stops or cleans up.
15
+ d. UNRELATED — does none of those (lint, format, notifications, badges).
16
+
17
+ Output as:
18
+ \`\`\`
19
+ Step: "<step name>" → SETUP | TEST | TEARDOWN | UNRELATED
20
+ \`\`\``;
21
+ }
22
+ function buildSummarizeBody() {
23
+ return `Summarize the SUT, pulling from all sources:
24
+ a. Setup commands needed to bring up all services (may come from multiple workflows / infra files).
25
+ b. Required secrets and env vars (with their \`\${{ secrets.* }}\` references and pass-through style — \`env:\` blocks vs. \`secrets: inherit\`).
26
+ c. Runner needed (\`runs-on\` value; a larger runner for heavy builds — runner names vary by org, do not hardcode).
27
+ d. How an auth token is obtained (script, step output, or secret).`;
28
+ }
29
+ function buildDecideIntroBody() {
30
+ return `The SUT must always be built from the PR's source code — Testbot reuses this workflow for every future PR, so it must validate the code in the PR being tested, not a stale snapshot. Use build: blocks in compose files (or docker build against the PR checkout) so images come from PR source. Pull-only image references and pinned upstream tags are fine for sidecars (databases, queues, caches), but the application services under test must be built locally.
31
+ Evaluate the four patterns in strict priority order — always start with Pattern A and only escalate when it genuinely cannot express the setup. Full semantics for each lifecycle input are in the reference section below.`;
32
+ }
33
+ function buildPatternABody() {
34
+ return `Use when the entire setup — build, start, seed — can be expressed as one or two shell commands (e.g., docker compose up -d --build, make start, ./scripts/start.sh). Do NOT add any GHA steps. Set targetSetupCommand, targetReadyCheckCommand, targetReadyCheckTimeout, and targetTeardownCommand on the Testbot action; leave skipTargetSetup unset.`;
35
+ }
36
+ function buildPatternBBody() {
37
+ return `Use when the source workflow requires GHA-specific steps purely for environment or tooling (e.g., docker/setup-buildx-action, actions/cache, private registry login) but the actual service start can still be expressed as a single command. Copy only those tool/env pre-steps BEFORE the Testbot action. Set targetSetupCommand, targetReadyCheckCommand, targetReadyCheckTimeout, and targetTeardownCommand on the Testbot action; leave skipTargetSetup unset. Preserve every env:, with:, and \${{ secrets.* }} reference from the pre-steps exactly as written.`;
38
+ }
39
+ function buildPatternCBody() {
40
+ return `Use when the service startup itself requires multiple GHA steps that cannot be collapsed into a single command. Copy the source workflow's SETUP steps verbatim BEFORE the Testbot action. Set skipTargetSetup: 'true' and do not set targetSetupCommand. Set targetReadyCheckCommand and targetReadyCheckTimeout on the Testbot action. Add TEARDOWN steps AFTER the Testbot action with if: always(), or set targetTeardownCommand if a single command suffices — pick one, not both. Preserve every env:, with:, and \${{ secrets.* }} reference exactly as written.`;
41
+ }
42
+ function buildPatternDBody() {
43
+ return `Use when teardown is also too complex for a single command. Copy the SETUP steps BEFORE and TEARDOWN steps AFTER the Testbot action (with if: always()). Set skipTargetSetup: 'true'. Do not set targetSetupCommand or targetTeardownCommand. Preserve every env:, with:, and \${{ secrets.* }} reference exactly as written.`;
44
+ }
45
+ function buildEditWorkflowBody() {
46
+ return `Edit \`${TESTBOT_WORKFLOW_PATH}\` (already created by the Testbot installer):
47
+ a. Apply the chosen pattern:
48
+ - Pattern A: set lifecycle inputs on the Testbot action, no GHA steps.
49
+ - Pattern B: add GHA tool/env pre-steps BEFORE the Testbot action, set lifecycle inputs (\`targetSetupCommand\`, \`targetReadyCheckCommand\`, \`targetTeardownCommand\`), leave \`skipTargetSetup\` unset.
50
+ - Pattern C: add GHA SETUP steps BEFORE the Testbot action, set \`skipTargetSetup: 'true'\`, set \`targetReadyCheckCommand\`, add TEARDOWN steps AFTER or set \`targetTeardownCommand\` — do NOT set \`targetSetupCommand\`.
51
+ - Pattern D: add GHA SETUP steps BEFORE and TEARDOWN steps AFTER the Testbot action, set \`skipTargetSetup: 'true'\`, do NOT set \`targetSetupCommand\` or \`targetTeardownCommand\`.
52
+ b. Update \`runs-on\` to match the runner needed by the source workflow's setup — runner names vary by org, do not hardcode (see runner-label guidance in Step 3 above).
53
+ c. Pass all required secrets through — reuse the same \`\${{ secrets.* }}\` references or \`secrets: inherit\`. For GHA steps (Patterns B, C, D), set secrets via \`env:\` on the individual steps that need them; for lifecycle inputs (Patterns A, B), set them on the Testbot action or at the job level.
54
+ d. The basic file already contains the \`skyramp/testbot\` action — REPLACE the original workflow's test-run step with it, do NOT add a duplicate test runner step.`;
55
+ }
56
+ function buildConfigureAuthBody() {
57
+ return `Configure auth — use the lifecycle input reference above for full semantics of \`authTokenCommand\` and \`uiCredentials\`:
58
+ a. If the source workflow exports or seeds an auth token, set \`authTokenCommand\` on the Testbot action (or create \`.skyramp/sut/get-auth-token.sh\`).
59
+ b. If any service requires browser login, set \`uiCredentials\` on the Testbot action.
60
+ c. Omit both when the SUT is unauthenticated.`;
61
+ }
62
+ function buildHandleShapeBody() {
63
+ return `Handle source-workflow shape:
64
+ a. If the original workflow uses \`matrix\` builds, pick ONE configuration for the Testbot workflow (matrix runs would multiply Testbot invocations).
65
+ b. If the original workflow uses \`needs:\` (job dependencies), inline the dependent job's steps into the Testbot job — Testbot runs as a single job.`;
66
+ }
67
+ function buildAdaptRestrictionsBody() {
68
+ return `Do not modify any other GitHub workflow files referenced. The only github workflow file you may edit is \`${TESTBOT_WORKFLOW_PATH}\`; every other workflow under \`.github/workflows/\` (including the source workflow) is read-only reference material.`;
69
+ }
70
+ // ── PromptPlan declaration ────────────────────────────────────────────────────
71
+ const _adaptPlan = new PromptPlan()
72
+ .addPhase("adapt", "", { headerLevel: "hidden", stepFormat: "hash" })
73
+ .step("SCAN", "Understand the System Under Test in this repository", () => "")
74
+ .subStep("READ_SOURCES", "Read workflows and infra files", buildReadSourcesBody)
75
+ .subStep("CLASSIFY_STEPS", "Classify source workflow steps", buildClassifyStepsBody)
76
+ .subStep("SUMMARIZE", "Summarize the SUT", buildSummarizeBody)
77
+ .step("DECIDE", "Decide SUT setup strategy", buildDecideIntroBody)
78
+ .subStep("PATTERN_A", "Pattern A — Testbot lifecycle commands only (try this first, always)", buildPatternABody)
79
+ .subStep("PATTERN_B", "Pattern B — Hybrid: GHA pre-steps for tool/env setup + Testbot lifecycle commands for service start", buildPatternBBody)
80
+ .subStep("PATTERN_C", "Pattern C — GHA steps replace service startup + Testbot lifecycle validation", buildPatternCBody)
81
+ .subStep("PATTERN_D", "Pattern D — Fully wrapped by GHA steps", buildPatternDBody)
82
+ .step("INPUTS", "Plan the Testbot action inputs", () => buildInputsBody())
83
+ .step("ADAPT", "Edit the Testbot workflow and generate SUT files", () => "")
84
+ .subStep("EDIT_WORKFLOW", "Edit the workflow file", buildEditWorkflowBody)
85
+ .subStep("CONFIGURE_AUTH", "Configure auth", buildConfigureAuthBody)
86
+ .subStep("HANDLE_SHAPE", "Handle source-workflow shape", buildHandleShapeBody)
87
+ .subStep("RESTRICTIONS", "What not to do", buildAdaptRestrictionsBody)
88
+ .step("VERIFY", "Verify", () => "")
89
+ .subStep("COMMON_ERRORS", "Common SUT errors", () => buildCommonSutErrorsSection())
90
+ .subStep("LOCAL_VALIDATION", "Local validation", () => buildLocalValidationSection())
91
+ .done();
92
+ // ── Goal section (static prose above the plan) ────────────────────────────────
93
+ function buildGoalSection(args) {
94
+ const sourceLine = args.sutSourceWorkflowFile
95
+ ? `The user pointed at \`${args.sutSourceWorkflowFile}\` as the source workflow whose setup/teardown steps should be copied into the Testbot workflow. Use it as your primary source of setup steps — but still read the rest of the repo (other workflows, docker-compose, Kubernetes, Helm) to understand the full SUT shape.`
96
+ : `No specific source workflow was provided. Read ALL available GitHub workflows in this repository to learn how services are built, started, and authenticated, and pick the source workflow whose setup steps best match a SUT for testing (typically an e2e/integration workflow, not lint/release/security workflows).`;
97
+ const thinkingSourceClause = args.sutSourceWorkflowFile
98
+ ? `confirms you are using \`${args.sutSourceWorkflowFile}\` as the source of setup steps (or explains why a different workflow is a better fit)`
99
+ : `names the workflow you selected as the source of setup steps and explains why`;
100
+ return `### Goal
101
+ 1. Generate working System Under Test (SUT) files that enable the Skyramp Testbot workflow (\`${TESTBOT_WORKFLOW_PATH}\`) to test any PR-specific code in this repository end-to-end for the services supported (REST or gRPC service APIs, queues, frontend UIs).
102
+ 2. Source workflow: ${sourceLine}
103
+ 3. Required output:
104
+ a. Output a <thinking> block that: (i) ${thinkingSourceClause}, (ii) summarizes what you learned about the SUT — services, secrets, auth, runner size — pulling from ALL workflows and infrastructure files, and (iii) decides how the SUT will be brought up — prefer Testbot lifecycle commands alone (targetSetupCommand, targetReadyCheckCommand, targetTeardownCommand) when the setup can be expressed as a single shell command; add GHA pre-steps only for tooling that cannot run in a shell (Buildx, cache, registry login) while still using lifecycle commands for service start; escalate to full GHA steps replacing service startup only when a single command cannot express it; use fully wrapped GHA steps for both setup and teardown only as a last resort. State clearly which approach was chosen and why.
105
+ b. Adapt the Testbot workflow file (\`${TESTBOT_WORKFLOW_PATH}\`) for bringing up the system under test.`;
106
+ }
107
+ export function getAdaptWorkflowPrompt(args) {
108
+ return `${getPersonaPrefix()}${buildGoalSection(args)}
109
+
110
+ ${buildSutDefinitionBlock()}${buildContextBlock(args)}
111
+
112
+ ${_adaptPlan.render(args)}
113
+ `;
114
+ }
@@ -0,0 +1,2 @@
1
+ import { type SutPromptArgs } from "../shared.js";
2
+ export declare function getDockerComposePrompt(args: SutPromptArgs): string;