@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
@@ -1,13 +1,14 @@
1
- jest.mock("../../workspace/workspace.js", () => ({
1
+ import { jest } from "@jest/globals";
2
+ jest.unstable_mockModule("../../workspace/workspace.js", () => ({
2
3
  WorkspaceConfigManager: jest.fn(),
3
4
  }));
4
- jest.mock("../../services/AnalyticsService.js", () => ({
5
+ jest.unstable_mockModule("../../services/AnalyticsService.js", () => ({
5
6
  AnalyticsService: { pushMCPToolEvent: jest.fn() },
6
7
  }));
7
- jest.mock("../../playwright/traceRecordingPrompt.js", () => ({
8
+ jest.unstable_mockModule("../../playwright/traceRecordingPrompt.js", () => ({
8
9
  getTraceRecordingPromptText: () => "",
9
10
  }));
10
- import { getTestbotPrompt } from "./testbot-prompts.js";
11
+ const { getTestbotPrompt, buildWorkspaceRecoveryPrefix } = await import("./testbot-prompts.js");
11
12
  // Minimal args to invoke getTestbotPrompt — only services matter for these tests
12
13
  const baseArgs = {
13
14
  prTitle: "Test PR",
@@ -24,26 +25,6 @@ function callWithServices(services) {
24
25
  undefined, // userPrompt
25
26
  services);
26
27
  }
27
- function callWithStateOutputFile(stateOutputFile) {
28
- return getTestbotPrompt(baseArgs.prTitle, baseArgs.prDescription, baseArgs.summaryOutputFile, baseArgs.repositoryPath, undefined, // baseBranch
29
- undefined, // maxRecommendations
30
- undefined, // maxGenerate
31
- undefined, // maxCritical
32
- undefined, // prNumber
33
- undefined, // userPrompt
34
- undefined, // services
35
- stateOutputFile);
36
- }
37
- function callFollowUpWithStateOutputFile(stateOutputFile) {
38
- return getTestbotPrompt(baseArgs.prTitle, baseArgs.prDescription, baseArgs.summaryOutputFile, baseArgs.repositoryPath, undefined, // baseBranch
39
- undefined, // maxRecommendations
40
- undefined, // maxGenerate
41
- undefined, // maxCritical
42
- undefined, // prNumber
43
- "add more tests", // userPrompt — triggers follow-up path
44
- undefined, // services
45
- stateOutputFile);
46
- }
47
28
  describe("buildServiceContext (via getTestbotPrompt)", () => {
48
29
  it("renders full service with all fields", () => {
49
30
  const prompt = callWithServices([
@@ -121,27 +102,6 @@ describe("buildServiceContext (via getTestbotPrompt)", () => {
121
102
  expect(prompt).toContain("</REPOSITORY PATH>\nUse the Skyramp MCP server tools");
122
103
  });
123
104
  });
124
- describe("stateOutputFile in getTestbotPrompt", () => {
125
- it("includes stateOutputFile in skyramp_analyze_changes call for first-run prompt", () => {
126
- const stateFile = "/tmp/skyramp/analyze-changes-state.json";
127
- const prompt = callWithStateOutputFile(stateFile);
128
- // The prompt must pass stateOutputFile to skyramp_analyze_changes
129
- expect(prompt).toContain(`\`stateOutputFile\`: "${stateFile}"`);
130
- });
131
- it("includes stateOutputFile in skyramp_analyze_changes call for follow-up prompt", () => {
132
- const stateFile = "/tmp/skyramp/analyze-changes-state.json";
133
- const prompt = callFollowUpWithStateOutputFile(stateFile);
134
- expect(prompt).toContain(`\`stateOutputFile\`: "${stateFile}"`);
135
- });
136
- it("omits stateOutputFile from skyramp_analyze_changes call when not provided", () => {
137
- const prompt = callWithStateOutputFile(undefined);
138
- expect(prompt).not.toContain("stateOutputFile");
139
- });
140
- it("omits stateOutputFile from follow-up prompt when not provided", () => {
141
- const prompt = callFollowUpWithStateOutputFile(undefined);
142
- expect(prompt).not.toContain("stateOutputFile");
143
- });
144
- });
145
105
  describe("uiCredentials in getTestbotPrompt", () => {
146
106
  function callWithUiCredentials(uiCredentials) {
147
107
  return getTestbotPrompt(baseArgs.prTitle, baseArgs.prDescription, baseArgs.summaryOutputFile, baseArgs.repositoryPath, undefined, // baseBranch
@@ -151,7 +111,6 @@ describe("uiCredentials in getTestbotPrompt", () => {
151
111
  undefined, // prNumber
152
112
  undefined, // userPrompt
153
113
  undefined, // services
154
- undefined, // stateOutputFile
155
114
  uiCredentials);
156
115
  }
157
116
  // The instructions text references `<ui-credentials>` in prose (backticked);
@@ -216,13 +175,11 @@ describe("drift analysis — runtime tool call (step 3)", () => {
216
175
  const prompt = basePrompt();
217
176
  expect(prompt).toContain("skyramp_actions");
218
177
  });
219
- it("step 3 appears inside Task 1, before Task 2", () => {
178
+ it("skyramp_analyze_test_health is referenced in the prompt", () => {
179
+ // After the unified maintenance refactor, analyze_test_health is referenced
180
+ // in the testMaintenance submission guidance rather than as an explicit step.
220
181
  const prompt = basePrompt();
221
- const task1Pos = prompt.indexOf("## Task 1");
222
- const healthPos = prompt.indexOf("skyramp_analyze_test_health");
223
- const task2Pos = prompt.indexOf("## Task 2");
224
- expect(healthPos).toBeGreaterThan(task1Pos);
225
- expect(healthPos).toBeLessThan(task2Pos);
182
+ expect(prompt).toContain("skyramp_analyze_test_health");
226
183
  });
227
184
  it("does not contain the build-time embedded drift_analysis_rules content (Action Decision Tree)", () => {
228
185
  // The rules are now fetched at runtime via skyramp_analyze_test_health —
@@ -237,57 +194,7 @@ describe("drift analysis — runtime tool call (step 3)", () => {
237
194
  expect(prompt).not.toContain("You are acting as a Skyramp Integration Architect");
238
195
  });
239
196
  });
240
- describe("UI grounding via Task 2 capture-act-capture", () => {
241
- it("surfaces uiContext as guidance, not a contract", () => {
242
- const prompt = getTestbotPrompt(baseArgs.prTitle, baseArgs.prDescription, baseArgs.summaryOutputFile, baseArgs.repositoryPath);
243
- // uiContext fields are explained inline so the agent knows what to do with
244
- // them. Step 1 provides candidate URLs but gives fallback instructions
245
- // ("navigate from the workspace baseUrl and explore") for 404s/redirects,
246
- // treating candidates as guidance not a rigid contract.
247
- expect(prompt).toContain("uiContext");
248
- expect(prompt).toContain("candidateUiPages");
249
- expect(prompt).toContain("changedFrontendFiles");
250
- expect(prompt).toMatch(/navigate from the workspace baseUrl and explore/i);
251
- });
252
- it("step 5 enforces Blueprint Citation Invariant in natural prose", () => {
253
- const prompt = getTestbotPrompt(baseArgs.prTitle, baseArgs.prDescription, baseArgs.summaryOutputFile, baseArgs.repositoryPath);
254
- // Step 5 is the citation-invariant guardrail, not a "fill in tuples"
255
- // post-processing step (slice 4 cleanup: recs are grounded upstream).
256
- expect(prompt).toContain("Blueprint Citation Invariant");
257
- // Reasoning must be natural prose, NOT internal-identifier syntax.
258
- expect(prompt).toMatch(/natural prose/i);
259
- expect(prompt).toMatch(/internal-identifier syntax/i);
260
- });
261
- it("Task 2 no longer instructs the agent to fill in tuples post-hoc", () => {
262
- const prompt = getTestbotPrompt(baseArgs.prTitle, baseArgs.prDescription, baseArgs.summaryOutputFile, baseArgs.repositoryPath);
263
- // After slice 4 cleanup: Task 2 captures are for trace recording's own
264
- // assertions, not for retroactively rewriting recommendation reasoning.
265
- // The phrase "fill in tuples" must NOT appear anywhere in the prompt.
266
- expect(prompt).not.toMatch(/fill in tuples/i);
267
- expect(prompt).not.toMatch(/return to step 5 and fill/i);
268
- });
269
- it("Task 2 step 5 mentions possibleAssertions as available, NOT as required (slice 5.5 softening)", () => {
270
- const prompt = getTestbotPrompt(baseArgs.prTitle, baseArgs.prDescription, baseArgs.summaryOutputFile, baseArgs.repositoryPath);
271
- // Slice 5: AFTER-action browser_blueprint response includes
272
- // possibleAssertions[] — mechanically translated candidates.
273
- expect(prompt).toContain("possibleAssertions");
274
- // Slice 5.5: prompt explicitly tells the agent NOT to feel obligated.
275
- // Two P09 runs with the prior "emit at least one" directive showed the
276
- // agent over-using shallow visibility assertions at the expense of
277
- // integration-test depth. The softened version says: read them, use
278
- // when they happen to match what you'd write anyway, ignore otherwise.
279
- expect(prompt).toMatch(/do not feel obligated/i);
280
- expect(prompt).toMatch(/biased toward visibility/i);
281
- // The candidate format is still documented.
282
- expect(prompt).toMatch(/\bcode\b.*\brationale\b.*\btier\b/i);
283
- // The pre-existing "at least one browser_assert per page navigated"
284
- // rule should be preserved (it's about meaningful business-outcome
285
- // assertions, not about possibleAssertions).
286
- expect(prompt).toMatch(/at least one .browser_assert. per page navigated/i);
287
- });
288
- });
289
197
  describe("buildWorkspaceRecoveryPrefix", () => {
290
- const { buildWorkspaceRecoveryPrefix } = require("./testbot-prompts.js");
291
198
  it("includes repositoryPath in both init_scan and init_workspace instructions", () => {
292
199
  const prefix = buildWorkspaceRecoveryPrefix("/home/user/repo");
293
200
  expect(prefix).toContain('skyramp_init_scan with workspacePath "/home/user/repo"');
@@ -312,7 +219,6 @@ describe("testsRepoDir in getTestbotPrompt", () => {
312
219
  undefined, // prNumber
313
220
  undefined, // userPrompt
314
221
  undefined, // services
315
- undefined, // stateOutputFile
316
222
  undefined, // uiCredentials
317
223
  testsRepoDir);
318
224
  }
@@ -324,7 +230,6 @@ describe("testsRepoDir in getTestbotPrompt", () => {
324
230
  undefined, // prNumber
325
231
  "add more tests", // userPrompt — triggers follow-up path
326
232
  undefined, // services
327
- undefined, // stateOutputFile
328
233
  undefined, // uiCredentials
329
234
  testsRepoDir);
330
235
  }
@@ -348,20 +253,13 @@ describe("testsRepoDir in getTestbotPrompt", () => {
348
253
  });
349
254
  });
350
255
  describe("testbot prompt blueprint-grounded recommendations (slice 4)", () => {
351
- it("instructs the agent to call skyramp_ui_analyze_changes before skyramp_analyze_changes", () => {
352
- const prompt = getTestbotPrompt(baseArgs.prTitle, baseArgs.prDescription, baseArgs.summaryOutputFile, baseArgs.repositoryPath);
353
- const uiacIdx = prompt.indexOf("skyramp_ui_analyze_changes");
354
- const acIdx = prompt.indexOf("skyramp_analyze_changes");
355
- expect(uiacIdx).toBeGreaterThan(-1);
356
- expect(acIdx).toBeGreaterThan(uiacIdx);
357
- });
358
- it("Task 1 step 1 instructs the agent to capture blueprints (without threading them through a param)", () => {
256
+ it("uses a single skyramp_analyze_changes call (no separate pre-flight tool, no blueprint threading)", () => {
359
257
  const prompt = getTestbotPrompt(baseArgs.prTitle, baseArgs.prDescription, baseArgs.summaryOutputFile, baseArgs.repositoryPath);
360
- // Captures stay in tool-result history; analyze_changes returns the
361
- // authoring rules and the agent supplies the captured vocabulary.
362
- expect(prompt).toMatch(/browser_blueprint`?\s*to capture/i);
363
- expect(prompt).toMatch(/tool-result history/i);
364
- // Make sure we removed the old capturedBlueprints threading directive.
258
+ // The standalone pre-flight tool is gone its work folded into analyze_changes.
259
+ expect(prompt).not.toContain("skyramp_ui_analyze_changes");
260
+ expect(prompt).toContain("skyramp_analyze_changes");
261
+ // Captures stay in tool-result history — the old capturedBlueprints
262
+ // threading directive must be gone.
365
263
  expect(prompt).not.toMatch(/capturedBlueprints/);
366
264
  });
367
265
  // Flutter support — both the generalised UI trigger wording and the
@@ -0,0 +1,17 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare const ANALYSIS_URI_PREFIX = "skyramp://analysis";
3
+ /**
4
+ * Register MCP Resources for analysis data access.
5
+ *
6
+ * Resources provide read-only, token-efficient access to analysis data
7
+ * via sessionId. The state file is an internal backing store.
8
+ *
9
+ * URI scheme:
10
+ * skyramp://analysis/{sessionId}/summary
11
+ * skyramp://analysis/{sessionId}/endpoints
12
+ * skyramp://analysis/{sessionId}/endpoints/{+path}
13
+ * skyramp://analysis/{sessionId}/endpoints/{+path}/{method}
14
+ * skyramp://analysis/{sessionId}/scenarios
15
+ * skyramp://analysis/{sessionId}/diff
16
+ */
17
+ export declare function registerAnalysisResources(server: McpServer): void;
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerProgressResource(server: McpServer): void;
@@ -0,0 +1,2 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerSutSetupResource(server: McpServer): void;
@@ -0,0 +1,45 @@
1
+ import { ResourceTemplate, } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { logger } from "../utils/logger.js";
3
+ import { resourceText } from "../utils/utils.js";
4
+ import { AnalyticsService } from "../services/AnalyticsService.js";
5
+ import { getAdaptWorkflowPrompt } from "../prompts/sut-setup/modes/adaptWorkflowPrompt.js";
6
+ import { getDockerComposePrompt } from "../prompts/sut-setup/modes/dockerComposePrompt.js";
7
+ import { SutSetupMode } from "../prompts/sut-setup/shared.js";
8
+ export function registerSutSetupResource(server) {
9
+ logger.info("Registering SUT setup resource");
10
+ // RFC 6570 {+rest} (reserved expansion) captures the entire query string
11
+ // including the leading "?". This avoids the SDK's per-param regex which
12
+ // fails on empty query-param values.
13
+ const template = new ResourceTemplate("skyramp://prompts/skyramp_testbot_sut{+rest}", { list: undefined });
14
+ server.registerResource("skyramp_testbot_sut", template, {
15
+ title: "Skyramp Testbot SUT Setup",
16
+ description: "Returns mode-specific instructions for SUT (System Under Test) setup. " +
17
+ "Modes: none, adapt_workflow, docker_compose.",
18
+ mimeType: "text/plain",
19
+ }, async (uri) => {
20
+ const param = (name, fallback) => uri.searchParams.get(name) ?? fallback;
21
+ const mode = param("sutSetupMode", SutSetupMode.None);
22
+ const args = {
23
+ repositoryPath: param("repositoryPath", "."),
24
+ sutSetupMode: mode,
25
+ sutSourceWorkflowFile: param("sutSourceWorkflowFile", ""),
26
+ sutSourceDockerComposeFile: param("sutSourceDockerComposeFile", ""),
27
+ };
28
+ let prompt;
29
+ switch (mode) {
30
+ case SutSetupMode.AdaptWorkflow:
31
+ prompt = getAdaptWorkflowPrompt(args);
32
+ break;
33
+ case SutSetupMode.DockerCompose:
34
+ prompt = getDockerComposePrompt(args);
35
+ break;
36
+ case SutSetupMode.None:
37
+ prompt = "sutSetupMode is 'none'. No SUT setup required.";
38
+ break;
39
+ default:
40
+ prompt = `Unknown SUT setup mode: '${mode}'. Valid modes: none, adapt_workflow, docker_compose.`;
41
+ }
42
+ AnalyticsService.pushMCPToolEvent("skyramp_testbot_sut_resource", undefined, { mode }).catch(() => { });
43
+ return resourceText(uri.toString(), prompt);
44
+ });
45
+ }
@@ -0,0 +1,2 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerTestbotResource(server: McpServer): void;
@@ -25,7 +25,7 @@ export function registerTestbotResource(server) {
25
25
  const maxCrit = parseInt(uri.searchParams.get("maxCritical") || "", 10);
26
26
  const repositoryPath = param("repositoryPath", ".");
27
27
  const services = await readWorkspaceServices(repositoryPath);
28
- const prompt = getTestbotPrompt(param("prTitle", ""), param("prDescription", ""), param("summaryOutputFile", ""), repositoryPath, uri.searchParams.get("baseBranch") || undefined, isNaN(maxRec) ? MAX_RECOMMENDATIONS : maxRec, isNaN(maxGen) ? MAX_TESTS_TO_GENERATE : maxGen, isNaN(maxCrit) ? MAX_CRITICAL_TESTS : maxCrit, isNaN(prNum) ? undefined : prNum, uri.searchParams.get("userPrompt") || undefined, services.length ? services : undefined, uri.searchParams.get("stateOutputFile") || undefined, uri.searchParams.get("uiCredentials") || undefined, uri.searchParams.get("testsRepoDir") || undefined);
28
+ const prompt = getTestbotPrompt(param("prTitle", ""), param("prDescription", ""), param("summaryOutputFile", ""), repositoryPath, uri.searchParams.get("baseBranch") || undefined, isNaN(maxRec) ? MAX_RECOMMENDATIONS : maxRec, isNaN(maxGen) ? MAX_TESTS_TO_GENERATE : maxGen, isNaN(maxCrit) ? MAX_CRITICAL_TESTS : maxCrit, isNaN(prNum) ? undefined : prNum, uri.searchParams.get("userPrompt") || undefined, services.length ? services : undefined, uri.searchParams.get("uiCredentials") || undefined, uri.searchParams.get("testsRepoDir") || undefined);
29
29
  AnalyticsService.pushMCPToolEvent("skyramp_testbot_prompt", undefined, {}).catch(() => { });
30
30
  // Return the original URI — clients may use it to re-fetch the resource,
31
31
  // and the caller already has these params. Credentials never appear in
@@ -0,0 +1,13 @@
1
+ import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
2
+ export declare class AnalyticsService {
3
+ static pushTestGenerationToolEvent(toolName: string, result: CallToolResult, params: Record<string, any>): Promise<void>;
4
+ static pushMCPToolEvent(toolName: string, result: CallToolResult | undefined, params: Record<string, string>): Promise<void>;
5
+ /**
6
+ * Track server crash events
7
+ */
8
+ static pushServerCrashEvent(crashType: string, errorMessage: string, errorStack?: string): Promise<void>;
9
+ /**
10
+ * Track tool timeout events
11
+ */
12
+ static pushToolTimeoutEvent(toolName: string, timeoutMs: number, params: Record<string, string>): Promise<void>;
13
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,86 @@
1
+ // @ts-nocheck - Jest ESM type inference issues
2
+ import { jest } from "@jest/globals";
3
+ import * as fs from "fs";
4
+ import * as path from "path";
5
+ import { fileURLToPath } from "url";
6
+ // AnalyticsService resolves the MCP version with
7
+ // `fileURLToPath(import.meta.url)` at module scope. Under ts-jest's old
8
+ // CommonJS transform that top-level import.meta failed to compile with TS1343,
9
+ // so this module — and therefore this test — could not exist. The native-ESM
10
+ // Jest config (SKYR-3799) is what makes it loadable.
11
+ // pushToolEvent lives in @skyramp/skyramp, which pulls the native dylib. Mock
12
+ // it so we can assert on the event payload without loading the binary. Under
13
+ // native ESM jest.mock is not hoisted — use unstable_mockModule + dynamic
14
+ // import of the subject below.
15
+ const pushToolEvent = jest.fn();
16
+ jest.unstable_mockModule("@skyramp/skyramp", () => ({ pushToolEvent }));
17
+ jest.unstable_mockModule("../utils/telemetry.js", () => ({
18
+ getEntryPoint: jest.fn(() => "mcp"),
19
+ getCIPlatform: jest.fn(() => undefined),
20
+ getRepositoryInfo: jest.fn(async () => ({})),
21
+ }));
22
+ jest.unstable_mockModule("../utils/logger.js", () => ({
23
+ logger: { info: jest.fn(), error: jest.fn(), debug: jest.fn(), warn: jest.fn() },
24
+ }));
25
+ const { AnalyticsService } = await import("./AnalyticsService.js");
26
+ const telemetry = await import("../utils/telemetry.js");
27
+ // The version the production code should resolve: package.json two levels up
28
+ // from this module's own location — the same lookup getMCPPackageVersion does
29
+ // via import.meta.url. Computing it the same way here proves the test harness
30
+ // itself supports import.meta now.
31
+ const expectedVersion = JSON.parse(fs.readFileSync(path.join(path.dirname(fileURLToPath(import.meta.url)), "../../package.json"), "utf8")).version;
32
+ describe("AnalyticsService — import.meta-based version resolution", () => {
33
+ beforeEach(() => {
34
+ jest.clearAllMocks();
35
+ telemetry.getEntryPoint.mockReturnValue("mcp");
36
+ telemetry.getCIPlatform.mockReturnValue(undefined);
37
+ telemetry.getRepositoryInfo.mockResolvedValue({});
38
+ });
39
+ it("stamps the package.json version (resolved via import.meta.url) into the event params", async () => {
40
+ const params = {};
41
+ await AnalyticsService.pushMCPToolEvent("skyramp_smoke_test_generation", undefined, params);
42
+ expect(pushToolEvent).toHaveBeenCalledTimes(1);
43
+ const [, toolName, , sentParams] = pushToolEvent.mock.calls[0];
44
+ expect(toolName).toBe("skyramp_smoke_test_generation");
45
+ expect(sentParams.mcpServerVersion).toBe(expectedVersion);
46
+ // Sanity: a real semver-ish string, not an empty/undefined fallback.
47
+ expect(sentParams.mcpServerVersion).toMatch(/^\d+\.\d+\.\d+/);
48
+ });
49
+ it("concatenates error text from an isError result into the event error message", async () => {
50
+ const result = {
51
+ isError: true,
52
+ content: [
53
+ { type: "text", text: "first failure" },
54
+ { type: "text", text: "second failure" },
55
+ ],
56
+ };
57
+ await AnalyticsService.pushMCPToolEvent("skyramp_execute_test", result, {});
58
+ const [, , errorMessage] = pushToolEvent.mock.calls[0];
59
+ expect(errorMessage).toBe("first failure, second failure");
60
+ });
61
+ it("sends an empty error message for a successful result", async () => {
62
+ const result = { isError: false, content: [{ type: "text", text: "ok" }] };
63
+ await AnalyticsService.pushMCPToolEvent("skyramp_execute_test", result, {});
64
+ const [, , errorMessage] = pushToolEvent.mock.calls[0];
65
+ expect(errorMessage).toBe("");
66
+ });
67
+ it("includes ciPlatform in the params when running in CI", async () => {
68
+ telemetry.getCIPlatform.mockReturnValue("github_actions");
69
+ const params = {};
70
+ await AnalyticsService.pushMCPToolEvent("skyramp_init_workspace", undefined, params);
71
+ const [, , , sentParams] = pushToolEvent.mock.calls[0];
72
+ expect(sentParams.ciPlatform).toBe("github_actions");
73
+ });
74
+ it("merges repository info into the params", async () => {
75
+ telemetry.getRepositoryInfo.mockResolvedValue({ repoName: "letsramp/mcp", repoOwner: "letsramp" });
76
+ const params = { repositoryPath: "/repo" };
77
+ await AnalyticsService.pushMCPToolEvent("skyramp_analyze_changes", undefined, params);
78
+ expect(telemetry.getRepositoryInfo).toHaveBeenCalledWith("/repo");
79
+ const [, , , sentParams] = pushToolEvent.mock.calls[0];
80
+ expect(sentParams.repoName).toBe("letsramp/mcp");
81
+ });
82
+ it("swallows errors from pushToolEvent (telemetry must never break a tool call)", async () => {
83
+ pushToolEvent.mockRejectedValueOnce(new Error("network down"));
84
+ await expect(AnalyticsService.pushMCPToolEvent("skyramp_smoke_test_generation", undefined, {})).resolves.toBeUndefined();
85
+ });
86
+ });
@@ -0,0 +1,11 @@
1
+ import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
2
+ export interface ModularizationParams {
3
+ testFile: string;
4
+ testType?: string;
5
+ language?: string;
6
+ isTraceBased?: boolean;
7
+ prompt?: string;
8
+ }
9
+ export declare class ModularizationService {
10
+ processModularizationRequest(params: ModularizationParams): Promise<CallToolResult>;
11
+ }
@@ -0,0 +1,37 @@
1
+ import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
2
+ export interface TraceRequest {
3
+ Source: string;
4
+ Destination: string;
5
+ RequestBody: string;
6
+ ResponseBody: string;
7
+ RequestHeaders: Record<string, string[]>;
8
+ ResponseHeaders: Record<string, string[]>;
9
+ Method: string;
10
+ Path: string;
11
+ QueryParams: Record<string, string[]>;
12
+ StatusCode: number;
13
+ Port: number;
14
+ Timestamp: string;
15
+ Scheme: string;
16
+ }
17
+ export interface ScenarioParams {
18
+ scenarioName: string;
19
+ destination: string;
20
+ apiSchema?: string;
21
+ baseURL?: string;
22
+ method: string;
23
+ path: string;
24
+ requestBody?: string;
25
+ queryParams?: string;
26
+ responseBody?: string;
27
+ statusCode?: number;
28
+ outputDir: string;
29
+ authHeader?: string;
30
+ authScheme?: string;
31
+ authToken?: string;
32
+ responseHeaders?: Record<string, string[]>;
33
+ }
34
+ export declare class ScenarioGenerationService {
35
+ parseScenario(params: ScenarioParams): Promise<CallToolResult>;
36
+ generateTraceRequestFromInput(params: ScenarioParams): TraceRequest | null;
37
+ }
@@ -4,10 +4,14 @@
4
4
  *
5
5
  * Requires: @skyramp/skyramp native dylib (skips if not available)
6
6
  */
7
+ import { jest } from "@jest/globals";
7
8
  import fs from "fs";
8
9
  import path from "path";
9
10
  import os from "os";
11
+ import { createRequire } from "module";
10
12
  import { ScenarioGenerationService } from "./ScenarioGenerationService.js";
13
+ // Native dylib is a CommonJS addon — load it via createRequire under ESM.
14
+ const require = createRequire(import.meta.url);
11
15
  let SkyrampClient;
12
16
  try {
13
17
  SkyrampClient = require("@skyramp/skyramp").SkyrampClient;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,128 @@
1
+ import { TestAnalysisResult } from "../types/TestAnalysis.js";
2
+ interface TestDiscoveryResult {
3
+ tests: TestAnalysisResult[];
4
+ /** Paths of external files that were deemed relevant to the PR (score > 0). */
5
+ relevantExternalTestPaths: string[];
6
+ }
7
+ export interface TestDiscoveryOptions {
8
+ /**
9
+ * Resource names derived from endpoints in changed files (e.g. ["orders", "products"]).
10
+ * - Non-empty array: external files partitioned by relevance; only relevant files
11
+ * get full endpoint extraction. May be the sentinel `["unknown"]` when endpoints
12
+ * exist but resource names are unresolvable — treated as "endpoints present" to
13
+ * avoid skipping external coverage. Also used for "add field" PRs where the changed
14
+ * files have no endpoint definitions but the scanner found related endpoints nearby.
15
+ * - Empty array `[]`: PR mode with no endpoints from diff or scanner — external
16
+ * tests are skipped entirely to avoid flooding context.
17
+ * - `undefined`: full-repo mode — external tests capped at MAX_EXTERNAL_FULL_REPO.
18
+ */
19
+ changedResources?: string[];
20
+ }
21
+ export declare class TestDiscoveryService {
22
+ private readonly EXCLUDED_DIRS;
23
+ private readonly SKYRAMP_MARKER;
24
+ private readonly SUPPORTED_EXTENSIONS;
25
+ private readonly MAX_CONCURRENT_OPERATIONS;
26
+ private readonly MAX_EXTERNAL_FULL_REPO;
27
+ private readonly TEST_FILE_PATTERNS;
28
+ private readonly TEST_DIR_PATTERNS;
29
+ /**
30
+ * Discover all tests under testDir — both Skyramp-generated and external (user-written).
31
+ * Uses fast-glob for cross-platform file scanning, then classifies discovered files
32
+ * as Skyramp-generated tests, external tests, or not-a-test during processing.
33
+ *
34
+ * External test handling depends on `options.changedResources`:
35
+ * - `string[]` with entries (PR mode, endpoints detected): partition by relevance.
36
+ * - `[]` empty array (PR mode, scanner found no endpoints): skip external tests entirely
37
+ * rather than flooding context with irrelevant files.
38
+ * - `undefined` (full-repo mode, no diff): cap at MAX_EXTERNAL_FULL_REPO.
39
+ */
40
+ discoverTests(testDir: string, options?: TestDiscoveryOptions): Promise<TestDiscoveryResult>;
41
+ /**
42
+ * Score an external test file's relevance to a set of changed resource names.
43
+ * Tokenises the last two segments of the file path (split by /, \, -, _, .)
44
+ * and counts overlapping tokens with the changed resources.
45
+ * Example: "test_orders_api.py" vs ["orders"] → score 1.
46
+ */
47
+ private scoreRelevance;
48
+ /**
49
+ * Partition external test files into relevant (score > 0) and low-relevance (score = 0).
50
+ * Signal: path/name token overlap with changedResources.
51
+ */
52
+ private partitionByRelevance;
53
+ /**
54
+ * Process test files in parallel batches with concurrency control
55
+ * @param isExternal When true, uses external test metadata extraction
56
+ * @param contentCache Optional pre-read file contents from classification pass
57
+ */
58
+ private processFilesInBatches;
59
+ /**
60
+ * Classify candidate files as skyramp (has marker), external (test file without
61
+ * marker), or not-a-test. Caches file contents so downstream metadata extraction
62
+ * doesn't need to re-read from disk.
63
+ */
64
+ private classifyTestFiles;
65
+ /**
66
+ * Check if a file is an external (non-Skyramp) test file based on naming convention
67
+ * or directory placement.
68
+ */
69
+ private isExternalTestFile;
70
+ /**
71
+ * Extract metadata from a test file
72
+ * File is already confirmed to contain Skyramp marker by file search
73
+ * @param cachedContent Optional pre-read content from classification pass
74
+ */
75
+ private extractTestMetadata;
76
+ /**
77
+ * Extract the HTTP methods and paths covered by this test file.
78
+ * Returns a comma-separated string like "GET /orders/{id}, DELETE /orders/{id}".
79
+ * Handles Python (send_request / check_schema) and TypeScript/JS (sendRequest).
80
+ */
81
+ private extractCoveredEndpoints;
82
+ /**
83
+ * Extract metadata from an external (non-Skyramp) test file.
84
+ * Uses heuristic patterns for endpoint extraction, test type, and framework detection.
85
+ * @param cachedContent Optional pre-read content from classification pass
86
+ */
87
+ private extractExternalTestMetadata;
88
+ /**
89
+ * Extract HTTP endpoints from external (non-Skyramp) test files.
90
+ * Matches common patterns: requests.get, axios.post, fetch, supertest, RestAssured.
91
+ */
92
+ private extractExternalEndpoints;
93
+ /**
94
+ * Normalize an endpoint path extracted from test code.
95
+ * Strips base URL prefixes and returns only the path portion.
96
+ * Returns null if the path doesn't look like an API endpoint.
97
+ */
98
+ private normalizeEndpointPath;
99
+ /**
100
+ * Detect test type from external test file path and content.
101
+ * Falls back to directory/filename heuristics since external tests lack Skyramp command lines.
102
+ */
103
+ private detectExternalTestType;
104
+ /**
105
+ * Detect test framework from external test file content by checking imports.
106
+ */
107
+ private detectExternalFramework;
108
+ /**
109
+ * Detect programming language from file extension
110
+ */
111
+ private detectLanguage;
112
+ /**
113
+ * Detect test type from file content and name
114
+ * Checks Skyramp command line, filename, and content patterns
115
+ */
116
+ private detectTestType;
117
+ /**
118
+ * Extract API schema path from test content
119
+ * Looks for Skyramp command line first, then fallback to other patterns
120
+ */
121
+ private extractApiSchema;
122
+ /**
123
+ * Extract Framework from test content
124
+ * Looks for Skyramp command line first, then fallback to other patterns
125
+ */
126
+ private extractFramework;
127
+ }
128
+ export {};