@skyramp/mcp 0.4.4-rc.1 → 0.5.0-rc.1

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 (159) hide show
  1. package/build/index.js +238 -212
  2. package/build/playwright/PlaywrightTraceService.d.ts +1 -1
  3. package/build/playwright/blueprintDigestStore.d.ts +1 -1
  4. package/build/playwright/registerPlaywrightTools.d.ts +1 -1
  5. package/build/playwright/traceRecordingPrompt.d.ts +1 -1
  6. package/build/playwright/traceRecordingPrompt.js +2 -2
  7. package/build/prompts/initialize-workspace/initializeWorkspacePrompt.d.ts +17 -0
  8. package/build/prompts/initialize-workspace/initializeWorkspacePrompt.js +50 -7
  9. package/build/prompts/local-dev/local-dev-prompts.d.ts +1 -1
  10. package/build/prompts/local-dev/local-dev-prompts.js +2 -2
  11. package/build/prompts/startTraceCollectionPrompts.d.ts +1 -1
  12. package/build/prompts/startTraceCollectionPrompts.js +2 -3
  13. package/build/prompts/test-maintenance/driftAnalysisShared.js +1 -1
  14. package/build/prompts/test-recommendation/registerRecommendTestsPrompt.d.ts +1 -1
  15. package/build/prompts/test-recommendation/registerRecommendTestsPrompt.js +2 -2
  16. package/build/prompts/testbot/testbot-prompts.d.ts +1 -1
  17. package/build/prompts/testbot/testbot-prompts.js +4 -7
  18. package/build/recommendation/answers.d.ts +17 -52
  19. package/build/recommendation/answers.js +29 -99
  20. package/build/recommendation/pullRequestText.d.ts +0 -2
  21. package/build/recommendation/pullRequestText.js +0 -16
  22. package/build/recommendation/registerPlan.d.ts +4 -7
  23. package/build/recommendation/registerPlan.js +11 -37
  24. package/build/recommendation/types.d.ts +4 -21
  25. package/build/recommendation/verifierContracts.d.ts +4 -4
  26. package/build/recommendation/verifierContracts.js +4 -4
  27. package/build/recommendation/verifiers/citedPath.d.ts +2 -2
  28. package/build/recommendation/verifiers/citedPath.js +2 -2
  29. package/build/recommendation/verifiers/issueTraceability.d.ts +5 -1
  30. package/build/recommendation/verifiers/issueTraceability.js +35 -4
  31. package/build/resources/analysisResources.d.ts +1 -1
  32. package/build/resources/analysisResources.js +1 -1
  33. package/build/resources/progressResource.d.ts +1 -1
  34. package/build/resources/testbotResource.d.ts +1 -1
  35. package/build/resources/testbotResource.js +1 -1
  36. package/build/services/AnalyticsService.d.ts +1 -1
  37. package/build/services/FleetExecutionService.d.ts +130 -0
  38. package/build/services/FleetExecutionService.js +391 -0
  39. package/build/services/ModularizationService.d.ts +1 -1
  40. package/build/services/TestExecutionService.d.ts +7 -0
  41. package/build/services/TestExecutionService.js +21 -0
  42. package/build/services/TestGenerationService.d.ts +1 -1
  43. package/build/tool-phases.js +2 -0
  44. package/build/tools/auth/loginTool.d.ts +1 -1
  45. package/build/tools/auth/loginTool.js +2 -2
  46. package/build/tools/auth/logoutTool.d.ts +1 -1
  47. package/build/tools/auth/logoutTool.js +2 -2
  48. package/build/tools/code-refactor/alignAssertionsTool.d.ts +1 -1
  49. package/build/tools/code-refactor/alignAssertionsTool.js +1 -1
  50. package/build/tools/code-refactor/assertionSkillTools.d.ts +1 -1
  51. package/build/tools/code-refactor/assertionSkillTools.js +2 -2
  52. package/build/tools/code-refactor/codeReuseTool.d.ts +1 -1
  53. package/build/tools/code-refactor/codeReuseTool.js +2 -2
  54. package/build/tools/code-refactor/enhanceAssertionsTool.d.ts +1 -1
  55. package/build/tools/code-refactor/enhanceAssertionsTool.js +1 -1
  56. package/build/tools/code-refactor/modularizationTool.d.ts +1 -1
  57. package/build/tools/code-refactor/modularizationTool.js +2 -2
  58. package/build/tools/enrichTestWithMocksTool.d.ts +1 -1
  59. package/build/tools/enrichTestWithMocksTool.js +2 -2
  60. package/build/tools/executeFleetTool.d.ts +28 -0
  61. package/build/tools/executeFleetTool.js +107 -0
  62. package/build/tools/executeSkyrampTestTool.d.ts +8 -5
  63. package/build/tools/executeSkyrampTestTool.js +5 -5
  64. package/build/tools/fixErrorTool.d.ts +1 -1
  65. package/build/tools/fixErrorTool.js +1 -1
  66. package/build/tools/generate-tests/batchMockGenerationTool.d.ts +6 -57
  67. package/build/tools/generate-tests/batchMockGenerationTool.js +3 -3
  68. package/build/tools/generate-tests/generateBatchScenarioRestTool.d.ts +9 -45
  69. package/build/tools/generate-tests/generateBatchScenarioRestTool.js +29 -11
  70. package/build/tools/generate-tests/generateContractRestTool.d.ts +1 -2
  71. package/build/tools/generate-tests/generateContractRestTool.js +1 -1
  72. package/build/tools/generate-tests/generateE2ERestTool.d.ts +1 -2
  73. package/build/tools/generate-tests/generateE2ERestTool.js +1 -1
  74. package/build/tools/generate-tests/generateFuzzRestTool.d.ts +1 -1
  75. package/build/tools/generate-tests/generateFuzzRestTool.js +1 -1
  76. package/build/tools/generate-tests/generateIntegrationRestTool.d.ts +1 -2
  77. package/build/tools/generate-tests/generateIntegrationRestTool.js +1 -1
  78. package/build/tools/generate-tests/generateLoadRestTool.d.ts +1 -2
  79. package/build/tools/generate-tests/generateLoadRestTool.js +2 -1
  80. package/build/tools/generate-tests/generateMockRestTool.d.ts +1 -2
  81. package/build/tools/generate-tests/generateMockRestTool.js +3 -3
  82. package/build/tools/generate-tests/generateSmokeRestTool.d.ts +1 -1
  83. package/build/tools/generate-tests/generateSmokeRestTool.js +1 -1
  84. package/build/tools/generate-tests/generateUILoadRestTool.d.ts +64 -0
  85. package/build/tools/generate-tests/generateUILoadRestTool.js +512 -0
  86. package/build/tools/generate-tests/generateUIRestTool.d.ts +6 -7
  87. package/build/tools/generate-tests/generateUIRestTool.js +1 -1
  88. package/build/tools/generate-tests/loadTestSchema.d.ts +15 -15
  89. package/build/tools/generate-tests/trace-reuse-guard.d.ts +1 -1
  90. package/build/tools/generateEnrichedIntegrationTestTool.d.ts +1 -2
  91. package/build/tools/generateEnrichedIntegrationTestTool.js +1 -1
  92. package/build/tools/localDevWorkerComposeTool.d.ts +1 -1
  93. package/build/tools/localDevWorkerComposeTool.js +2 -2
  94. package/build/tools/one-click/oneClickTool.d.ts +1 -1
  95. package/build/tools/one-click/oneClickTool.js +1 -1
  96. package/build/tools/preflightMockCheckTool.d.ts +1 -1
  97. package/build/tools/preflightMockCheckTool.js +3 -3
  98. package/build/tools/queryProxyMocksTool.d.ts +1 -1
  99. package/build/tools/queryProxyMocksTool.js +3 -3
  100. package/build/tools/submitReportTool.d.ts +111 -414
  101. package/build/tools/submitReportTool.js +32 -134
  102. package/build/tools/test-management/actionsTool.d.ts +1 -1
  103. package/build/tools/test-management/actionsTool.js +7 -7
  104. package/build/tools/test-management/analyzeChangesTool.d.ts +22 -118
  105. package/build/tools/test-management/analyzeChangesTool.js +4 -4
  106. package/build/tools/test-management/analyzeTestHealthTool.d.ts +1 -1
  107. package/build/tools/test-management/analyzeTestHealthTool.js +4 -4
  108. package/build/tools/test-management/registerTestPlanTool.d.ts +111 -743
  109. package/build/tools/test-management/registerTestPlanTool.js +20 -36
  110. package/build/tools/test-management/resolveScreenTool.d.ts +1 -1
  111. package/build/tools/test-management/resolveScreenTool.js +6 -2
  112. package/build/tools/trace/startTraceCollectionTool.d.ts +1 -1
  113. package/build/tools/trace/startTraceCollectionTool.js +4 -4
  114. package/build/tools/trace/stopTraceCollectionTool.d.ts +1 -1
  115. package/build/tools/trace/stopTraceCollectionTool.js +2 -2
  116. package/build/tools/verifyTestDependenciesTool.d.ts +1 -1
  117. package/build/tools/verifyTestDependenciesTool.js +1 -1
  118. package/build/tools/workspace/initScanWorkspaceTool.d.ts +12 -2
  119. package/build/tools/workspace/initScanWorkspaceTool.js +101 -10
  120. package/build/tools/workspace/initializeWorkspaceTool.d.ts +1 -1
  121. package/build/tools/workspace/initializeWorkspaceTool.js +41 -5
  122. package/build/types/RepositoryAnalysis.d.ts +164 -1170
  123. package/build/types/RepositoryAnalysis.js +12 -10
  124. package/build/types/StepMethod.d.ts +24 -1
  125. package/build/types/StepMethod.js +1 -1
  126. package/build/types/TestTypes.d.ts +34 -133
  127. package/build/types/TestTypes.js +3 -3
  128. package/build/utils/docker.d.ts +29 -7
  129. package/build/utils/docker.js +83 -27
  130. package/build/utils/initAgent.d.ts +3 -3
  131. package/build/utils/initAgent.js +58 -26
  132. package/build/utils/progress.d.ts +3 -4
  133. package/build/utils/progress.js +4 -4
  134. package/build/utils/utils.d.ts +1 -1
  135. package/build/utils/versions.d.ts +3 -3
  136. package/build/utils/versions.js +1 -1
  137. package/build/workspace/workspace.d.ts +126 -539
  138. package/build/workspace/workspace.js +26 -5
  139. package/build/workspace/workspaceVerifier.d.ts +28 -0
  140. package/build/workspace/workspaceVerifier.js +307 -0
  141. package/package.json +6 -5
  142. package/plugin/prompts/plan-tests.md +2 -2
  143. package/plugin/skills/repair-staged-files/SKILL.md +17 -0
  144. package/plugin/skills/setup-testbot-target-sut/SKILL.md +54 -0
  145. package/plugin/skills/setup-testbot-target-sut/reference/ci-workflow.md +26 -0
  146. package/plugin/skills/setup-testbot-target-sut/reference/existing-tests.md +14 -0
  147. package/plugin/skills/setup-testbot-target-sut/reference/troubleshooting.md +20 -0
  148. package/build/prompts/sut-setup/modes/adaptWorkflowPrompt.d.ts +0 -2
  149. package/build/prompts/sut-setup/modes/adaptWorkflowPrompt.js +0 -178
  150. package/build/prompts/sut-setup/modes/dockerComposePrompt.d.ts +0 -2
  151. package/build/prompts/sut-setup/modes/dockerComposePrompt.js +0 -311
  152. package/build/prompts/sut-setup/shared.d.ts +0 -62
  153. package/build/prompts/sut-setup/shared.js +0 -196
  154. package/build/recommendation/blockerProbes.d.ts +0 -13
  155. package/build/recommendation/blockerProbes.js +0 -91
  156. package/build/recommendation/blockers.d.ts +0 -65
  157. package/build/recommendation/blockers.js +0 -135
  158. package/build/resources/sutSetupResource.d.ts +0 -2
  159. package/build/resources/sutSetupResource.js +0 -63
package/build/index.js CHANGED
@@ -1,15 +1,17 @@
1
1
  #!/usr/bin/env node
2
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { serveStdio } from "@modelcontextprotocol/server/stdio";
3
+ import { McpServer } from "@modelcontextprotocol/server";
3
4
  import { runnableLanguagesText } from "./types/TestTypes.js";
4
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
5
  import { registerStartTraceCollectionPrompt } from "./prompts/startTraceCollectionPrompts.js";
6
6
  import { registerTraceTool } from "./tools/trace/startTraceCollectionTool.js";
7
7
  import { registerTraceStopTool } from "./tools/trace/stopTraceCollectionTool.js";
8
8
  import { registerExecuteSkyrampTestTool } from "./tools/executeSkyrampTestTool.js";
9
+ import { registerExecuteFleetTool } from "./tools/executeFleetTool.js";
9
10
  import { AUTH_PLACEHOLDER_TOKEN } from "./types/TestTypes.js";
10
11
  import { AUTH_CONFLICT_ERROR_MSG } from "./prompts/test-recommendation/recommendationSections.js";
11
12
  import { logger } from "./utils/logger.js";
12
13
  import { registerUITestTool } from "./tools/generate-tests/generateUIRestTool.js";
14
+ import { registerUILoadTestTool } from "./tools/generate-tests/generateUILoadRestTool.js";
13
15
  import { registerSmokeTestTool } from "./tools/generate-tests/generateSmokeRestTool.js";
14
16
  import { registerFuzzTestTool } from "./tools/generate-tests/generateFuzzRestTool.js";
15
17
  import { registerContractTestTool } from "./tools/generate-tests/generateContractRestTool.js";
@@ -31,7 +33,6 @@ import { registerMockTool } from "./tools/generate-tests/generateMockRestTool.js
31
33
  import { registerBatchMockTool } from "./tools/generate-tests/batchMockGenerationTool.js";
32
34
  import { registerAnalyzeChangesTool, registerAnalyzeTestHealthTool, registerActionsTool, registerRegisterTestPlanTool, registerResolveScreenTool, } from "./tools/test-management/index.js";
33
35
  import { registerTestbotPrompt } from "./prompts/testbot/testbot-prompts.js";
34
- import { registerSutSetupResource } from "./resources/sutSetupResource.js";
35
36
  import { registerTestbotResource } from "./resources/testbotResource.js";
36
37
  import { registerLocalDevPrompt } from "./prompts/local-dev/local-dev-prompts.js";
37
38
  import { registerSubmitReportTool } from "./tools/submitReportTool.js";
@@ -72,7 +73,7 @@ else if (localDevEnabled) {
72
73
  oneClickInstructions = localDevInstructions;
73
74
  }
74
75
  // Global workspace-init nudge for bare MCP usage. Suppressed in testbot mode,
75
- // which runs its own INIT_WORKSPACE step (buildWorkspaceInitSection()) instead.
76
+ // which initializes the workspace in its own steps instead.
76
77
  const workspaceInitInstructions = isTestbotEnabled() || oneClickEnabled || localDevEnabled
77
78
  ? ""
78
79
  : `
@@ -83,220 +84,247 @@ If the workspace root is a git repo AND \`.skyramp/workspace.yml\` does not exis
83
84
  3. Proceed with the originally requested tool, if it is not one of the two workspace-init tools above.
84
85
  Skip only if: not a git repo, \`.skyramp/workspace.yml\` already exists, or user explicitly declines.
85
86
  `;
86
- const server = new McpServer({
87
- name: "Skyramp MCP Server",
88
- version: "1.0.0",
89
- }, {
90
- capabilities: {
91
- tools: {
92
- listChanged: true,
87
+ /**
88
+ * Builds one fully-registered server. `serveStdio` calls this per connection,
89
+ * so every registration must happen here rather than at module load.
90
+ */
91
+ async function createServer({ era }) {
92
+ const server = new McpServer({
93
+ name: "Skyramp MCP Server",
94
+ version: "1.0.0",
95
+ }, {
96
+ capabilities: {
97
+ tools: {
98
+ listChanged: true,
99
+ },
100
+ prompts: {
101
+ listChanged: true,
102
+ },
103
+ resources: {
104
+ listChanged: true,
105
+ },
93
106
  },
94
- prompts: {
95
- listChanged: true,
96
- },
97
- resources: {
98
- listChanged: true,
99
- },
100
- },
101
- instructions: `Skyramp MCP Server — generates and executes API tests (fuzz, contract, integration, E2E, UI).
102
- ${workspaceInitInstructions}
103
- ## Rules
104
- - NEVER show CLI commands. NEVER attempt to install or configure the Skyramp CLI. ALWAYS use the MCP tools provided.
105
- - For UI and E2E tests, there are TWO recording modes:
106
- 1. **AI-driven recording** (default): Use the browser_* tools (browser_navigate, browser_click, etc.) to record interactions, then call skyramp_export_zip to export the trace, then call skyramp_ui_test_generation with the zip path.
107
- 2. **Manual recording**: ONLY when the user explicitly says "manual recording", "record myself", "I will interact", or "Docker trace" — use skyramp_start_trace_collection / skyramp_stop_trace_collection to let the user interact with the browser themselves.
108
- - To capture an authentication session for re-use (e.g. "save session", "store login", "record auth state"): call \`skyramp_start_trace_collection\` (\`playwrightSaveStoragePath\` defaults to saving the session in \`outputDir\` — no need to set it). Tell the user to log in once and then call \`skyramp_stop_trace_collection\` IMMEDIATELY after login completes. The saved file can be passed back as \`playwrightStoragePath\` on later trace runs, or referenced as \`storageState\` in generated tests.${oneClickInstructions}
107
+ instructions: `Skyramp MCP Server — generates and executes API tests (fuzz, contract, integration, E2E, UI).
108
+ ${workspaceInitInstructions}
109
+ ## Rules
110
+ - NEVER show CLI commands. NEVER attempt to install or configure the Skyramp CLI. ALWAYS use the MCP tools provided.
111
+ - For UI and E2E tests, there are TWO recording modes:
112
+ 1. **AI-driven recording** (default): Use the browser_* tools (browser_navigate, browser_click, etc.) to record interactions, then call skyramp_export_zip to export the trace, then call skyramp_ui_test_generation with the zip path.
113
+ 2. **Manual recording**: ONLY when the user explicitly says "manual recording", "record myself", "I will interact", or "Docker trace" — use skyramp_start_trace_collection / skyramp_stop_trace_collection to let the user interact with the browser themselves.
114
+ - To capture an authentication session for re-use (e.g. "save session", "store login", "record auth state"): call \`skyramp_start_trace_collection\` (\`playwrightSaveStoragePath\` defaults to saving the session in \`outputDir\` — no need to set it). Tell the user to log in once and then call \`skyramp_stop_trace_collection\` IMMEDIATELY after login completes. The saved file can be passed back as \`playwrightStoragePath\` on later trace runs, or referenced as \`storageState\` in generated tests.${oneClickInstructions}
109
115
 
110
- ## Test Management Flow
111
- Use \`skyramp_analyze_changes\` as the single entry point for both test recommendations and test health analysis.
116
+ ## Test Management Flow
117
+ Use \`skyramp_analyze_changes\` as the single entry point for both test recommendations and test health analysis.
112
118
 
113
- ### Recommendations (2-step)
114
- 1. Call \`skyramp_analyze_changes\` with \`repositoryPath\` and \`scope\` → scans endpoints, computes branch diff, discovers existing tests → returns a \`stateFile\` **and** inline ranked test recommendations.
115
- 2. (Optional) Use the \`skyramp_recommend_tests\` prompt with \`stateFile\` in Cursor/IDE chat for a focused recommendation view.
119
+ ### Recommendations (2-step)
120
+ 1. Call \`skyramp_analyze_changes\` with \`repositoryPath\` and \`scope\` → scans endpoints, computes branch diff, discovers existing tests → returns a \`stateFile\` **and** inline ranked test recommendations.
121
+ 2. (Optional) Use the \`skyramp_recommend_tests\` prompt with \`stateFile\` in Cursor/IDE chat for a focused recommendation view.
116
122
 
117
- ### Health Analysis (5-step)
118
- 1. Call \`skyramp_analyze_changes\` with \`repositoryPath\` and \`scope\` → returns a \`stateFile\`.
119
- 2. Run each external test in ${runnableLanguagesText()} with \`skyramp_execute_test\`, \`phase: "before"\`, and \`stateFile\` → the server runs your command and writes the verdict back to stateFile. The tool takes no other language, and the gate in step 3 does not ask for those.
120
- 3. Call \`skyramp_analyze_test_health\` with \`stateFile\` → runs drift analysis + health scoring + LLM semantic assessment. It refuses until step 2 has run.
121
- 4. (Optional) Run Skyramp-generated tests with \`skyramp_execute_test\` and \`stateFile\` → writes each verdict back for health scoring.
122
- 5. Call \`skyramp_actions\` with \`stateFile\` → executes UPDATE/REGENERATE/ADD recommendations (with execution-aware prioritization if step 4 ran).
123
+ ### Health Analysis (5-step)
124
+ 1. Call \`skyramp_analyze_changes\` with \`repositoryPath\` and \`scope\` → returns a \`stateFile\`.
125
+ 2. Run each external test in ${runnableLanguagesText()} with \`skyramp_execute_test\`, \`phase: "before"\`, and \`stateFile\` → the server runs your command and writes the verdict back to stateFile. The tool takes no other language, and the gate in step 3 does not ask for those.
126
+ 3. Call \`skyramp_analyze_test_health\` with \`stateFile\` → runs drift analysis + health scoring + LLM semantic assessment. It refuses until step 2 has run.
127
+ 4. (Optional) Run Skyramp-generated tests with \`skyramp_execute_test\` and \`stateFile\` → writes each verdict back for health scoring.
128
+ 5. Call \`skyramp_actions\` with \`stateFile\` → executes UPDATE/REGENERATE/ADD recommendations (with execution-aware prioritization if step 4 ran).
123
129
 
124
- After \`skyramp_analyze_changes\`, inspect enriched data via MCP Resources (use the \`sessionId\` returned in the output):
125
- - \`skyramp://analysis/{sessionId}/summary\` — high-level overview
126
- - \`skyramp://analysis/{sessionId}/endpoints\` — compact endpoint listing
127
- - \`skyramp://analysis/{sessionId}/endpoints/{path}\` — full path detail
128
- - \`skyramp://analysis/{sessionId}/endpoints/{path}/{method}\` — single method detail
129
- - \`skyramp://analysis/{sessionId}/scenarios\` — drafted scenarios
130
- - \`skyramp://analysis/{sessionId}/diff\` — branch diff context
130
+ After \`skyramp_analyze_changes\`, inspect enriched data via MCP Resources (use the \`sessionId\` returned in the output):
131
+ - \`skyramp://analysis/{sessionId}/summary\` — high-level overview
132
+ - \`skyramp://analysis/{sessionId}/endpoints\` — compact endpoint listing
133
+ - \`skyramp://analysis/{sessionId}/endpoints/{path}\` — full path detail
134
+ - \`skyramp://analysis/{sessionId}/endpoints/{path}/{method}\` — single method detail
135
+ - \`skyramp://analysis/{sessionId}/scenarios\` — drafted scenarios
136
+ - \`skyramp://analysis/{sessionId}/diff\` — branch diff context
131
137
 
132
- ## Workspace Defaults for Test Generation (MANDATORY)
133
- Before calling ANY test generation tool, you MUST follow this flow:
138
+ ## Workspace Defaults for Test Generation (MANDATORY)
139
+ Before calling ANY test generation tool, you MUST follow this flow:
134
140
 
135
- 1. **Read** the .skyramp/workspace.yml file to get the configured defaults.
136
- 2. **Extract** the \`language\`, \`framework\`, \`testDirectory\`, \`api.baseUrl\`, \`api.authHeader\`, and \`api.authType\` from the matching service in the services section.
137
- 3. **Use those values** as defaults for the test generation tool call. Pass the service \`testDirectory\` as the generation tool \`outputDir\`. Do NOT ask the user for these values if they are already configured in the workspace file.
138
- 4. **CRITICAL — endpointURL**: The \`endpointURL\` parameter MUST be the full URL to the specific endpoint being tested, NOT just the base URL. Construct it by combining \`api.baseUrl\` with the endpoint path. Example: if \`api.baseUrl\` is \`http://localhost:8000\` and the endpoint is \`/api/v1/products\`, pass \`endpointURL: "http://localhost:8000/api/v1/products"\`. NEVER pass just the base URL (e.g. \`http://localhost:8000\`) as \`endpointURL\`.
139
- 5. **CRITICAL — scenario generation**: When calling \`skyramp_batch_scenario_test_generation\`, ALWAYS pass:
140
- - \`baseURL\`: The full base URL from \`api.baseUrl\` (e.g., \`http://localhost:3000\`). This determines the scheme, host, and port in the generated trace. Without it, the trace defaults to https:443 which is almost always wrong for local development.
141
- - \`authHeader\`: Which HTTP header carries the auth credential. Get it from \`api.authHeader\` in workspace config. Examples: \`Authorization\` (Bearer/Token auth), \`X-Api-Key\` (API key auth), \`Cookie\` (session/cookie auth like NextAuth). Pass \`""\` to document the endpoint as unauthenticated in the generated test's assertions (unauthenticated endpoints or \`api.authType: "none"\`).
142
- - \`authScheme\`: Only when \`authHeader\` is \`Authorization\`. The prefix before the token (e.g., \`"Bearer"\` → \`Authorization: Bearer <token>\`). **Derive from**: (1) OpenAPI spec \`securitySchemes\`/\`securityDefinitions\`, (2) source code auth middleware, (3) workspace \`api.authType\`. **Do NOT guess.**
143
- - \`authToken\`: The full header value, used verbatim. When omitted, \`SKYRAMP_PLACEHOLDER_TOKEN\` is auto-generated. Only provide when the header needs a specific format (e.g., \`"session=${AUTH_PLACEHOLDER_TOKEN}"\` for Cookie). **Do NOT fabricate token values.**
144
- - \`apiSchema\` is OPTIONAL — omit it for code-first apps without OpenAPI specs.
145
- 6. **CRITICAL — integration test from scenario**: When calling \`skyramp_integration_test_generation\` with a \`scenarioFile\`:
146
- - If workspace has \`api.authType\` set: omit auth params entirely — passing auth here alongside workspace \`authType\` causes "${AUTH_CONFLICT_ERROR_MSG}".
147
- - If workspace has no \`api.authType\`: pass \`authHeader\` only (no \`authScheme\`).
148
- 7. **If the workspace file does not exist**, or the needed values (language, framework, testDirectory) are missing from the workspace config, ASK the user which language, framework, and outputDir they want before calling the tool.
149
- 8. The user can always override workspace defaults by explicitly specifying values in their request.
150
- `,
151
- });
152
- // Register prompts
153
- logger.info("Starting prompt registration process");
154
- const prompts = [
155
- registerStartTraceCollectionPrompt,
156
- registerRecommendTestsPrompt,
157
- registerTraceRecordingPrompt,
158
- ];
159
- if (isTestbotEnabled()) {
160
- prompts.push(registerTestbotPrompt);
161
- registerTestbotResource(server);
162
- logger.info("Testbot prompt enabled via SKYRAMP_FEATURE_TESTBOT");
163
- registerSutSetupResource(server);
164
- logger.info("Testbot SUT setup resource enabled via SKYRAMP_FEATURE_TESTBOT");
165
- }
166
- if (isLocalDevEnabled()) {
167
- prompts.push(registerLocalDevPrompt);
168
- logger.info("Local-dev prompt enabled via SKYRAMP_FEATURE_LOCAL_DEV");
169
- }
170
- prompts.forEach((registerPrompt) => registerPrompt(server));
171
- logger.info("All prompts registered successfully");
172
- // Register test generation tools
173
- const testGenerationTools = [
174
- registerSmokeTestTool,
175
- registerFuzzTestTool,
176
- registerContractTestTool,
177
- registerLoadTestTool,
178
- registerIntegrationTestTool,
179
- registerE2ETestTool,
180
- registerUITestTool,
181
- registerBatchScenarioTestTool,
182
- registerMockTool,
183
- registerBatchMockTool,
184
- ];
185
- testGenerationTools.forEach((registerTool) => registerTool(server));
186
- // Register modularization and code quality tools
187
- const codeQualityTools = [
188
- registerModularizationTool,
189
- registerCodeReuseTool,
190
- registerEnhanceAssertionsTool,
191
- registerAssertionVerifyTool,
192
- registerVerifyTestDependenciesTool,
193
- ];
194
- // With the Skyramp plugin loaded the agent already has the
195
- // fix-test-import-errors skill; the tool would be a second copy of
196
- // the same text (SKYR-4296).
197
- if (!isSkillsLoaded()) {
198
- // Same reasoning as fix-test-import-errors: with the plugin loaded the agent
199
- // has the validate-assertion-alignment-post-execution skill directly; this
200
- // tool exists so an agent without skill support still gets the same
201
- // procedure, rendered from the same markdown with real arguments filled in.
202
- codeQualityTools.push(registerFixErrorTool, registerAlignAssertionsTool);
203
- }
204
- else {
205
- // The enhance-assertions skill drives its own snapshot step itself (SKYR-4310).
206
- codeQualityTools.push(registerAssertionSnapshotTool);
207
- }
208
- codeQualityTools.forEach((registerTool) => registerTool(server));
209
- // Register analysis resources (MCP Resources for enriched data access)
210
- registerAnalysisResources(server);
211
- registerProgressResource(server);
212
- // Register unified test-management tools (replaces separate test-maintenance tools)
213
- registerAnalyzeChangesTool(server);
214
- registerAnalyzeTestHealthTool(server);
215
- registerActionsTool(server);
216
- registerRegisterTestPlanTool(server);
217
- registerResolveScreenTool(server);
218
- // Register workspace management tools
219
- registerInitScanWorkspaceTool(server);
220
- registerInitializeWorkspaceTool(server);
221
- // Register one-click orchestrated workflows
222
- if (oneClickEnabled || localDevEnabled) {
223
- registerOneClickTool(server);
224
- logger.info("One-click tools enabled", {
225
- enabledBy: {
226
- SKYRAMP_FEATURE_ONE_CLICK: oneClickEnabled,
227
- SKYRAMP_FEATURE_LOCAL_DEV: localDevEnabled,
228
- },
141
+ 1. **Read** the .skyramp/workspace.yml file to get the configured defaults.
142
+ 2. **Extract** the \`language\`, \`framework\`, \`testDirectory\`, \`api.baseUrl\`, \`api.authHeader\`, and \`api.authType\` from the matching service in the services section.
143
+ 3. **Use those values** as defaults for the test generation tool call. Pass the service \`testDirectory\` as the generation tool \`outputDir\`. Do NOT ask the user for these values if they are already configured in the workspace file.
144
+ 4. **CRITICAL — endpointURL**: The \`endpointURL\` parameter MUST be the full URL to the specific endpoint being tested, NOT just the base URL. Construct it by combining \`api.baseUrl\` with the endpoint path. Example: if \`api.baseUrl\` is \`http://localhost:8000\` and the endpoint is \`/api/v1/products\`, pass \`endpointURL: "http://localhost:8000/api/v1/products"\`. NEVER pass just the base URL (e.g. \`http://localhost:8000\`) as \`endpointURL\`.
145
+ 5. **CRITICAL — scenario generation**: When calling \`skyramp_batch_scenario_test_generation\`, ALWAYS pass:
146
+ - \`baseURL\`: The full base URL from \`api.baseUrl\` (e.g., \`http://localhost:3000\`). This determines the scheme, host, and port in the generated trace. Without it, the trace defaults to https:443 which is almost always wrong for local development.
147
+ - \`authHeader\`: Which HTTP header carries the auth credential. Get it from \`api.authHeader\` in workspace config. Examples: \`Authorization\` (Bearer/Token auth), \`X-Api-Key\` (API key auth), \`Cookie\` (session/cookie auth like NextAuth). Pass \`""\` to document the endpoint as unauthenticated in the generated test's assertions (unauthenticated endpoints or \`api.authType: "none"\`).
148
+ - \`authScheme\`: Only when \`authHeader\` is \`Authorization\`. The prefix before the token (e.g., \`"Bearer"\` → \`Authorization: Bearer <token>\`). **Derive from**: (1) OpenAPI spec \`securitySchemes\`/\`securityDefinitions\`, (2) source code auth middleware, (3) workspace \`api.authType\`. **Do NOT guess.**
149
+ - \`authToken\`: The full header value, used verbatim. When omitted, \`SKYRAMP_PLACEHOLDER_TOKEN\` is auto-generated. Only provide when the header needs a specific format (e.g., \`"session=${AUTH_PLACEHOLDER_TOKEN}"\` for Cookie). **Do NOT fabricate token values.**
150
+ - \`apiSchema\` is OPTIONAL — omit it for code-first apps without OpenAPI specs.
151
+ 6. **CRITICAL — integration test from scenario**: When calling \`skyramp_integration_test_generation\` with a \`scenarioFile\`:
152
+ - If workspace has \`api.authType\` set: omit auth params entirely — passing auth here alongside workspace \`authType\` causes "${AUTH_CONFLICT_ERROR_MSG}".
153
+ - If workspace has no \`api.authType\`: pass \`authHeader\` only (no \`authScheme\`).
154
+ 7. **If the workspace file does not exist**, or the needed values (language, framework, testDirectory) are missing from the workspace config, ASK the user which language, framework, and outputDir they want before calling the tool.
155
+ 8. The user can always override workspace defaults by explicitly specifying values in their request.
156
+ `,
229
157
  });
230
- }
231
- // Register other Skyramp tools
232
- const infrastructureTools = [
233
- registerLoginTool,
234
- registerLogoutTool,
235
- registerExecuteSkyrampTestTool,
236
- registerTraceTool,
237
- registerTraceStopTool,
238
- ];
239
- if (isLocalDevEnabled()) {
240
- infrastructureTools.push(registerEnrichTestWithMocksTool, registerPreflightMockCheckTool, registerGenerateEnrichedIntegrationTestTool, registerLocalDevWorkerComposeTool, registerQueryProxyMocksTool);
241
- logger.info("Local-dev tools enabled via SKYRAMP_FEATURE_LOCAL_DEV");
242
- }
243
- if (isTestbotEnabled()) {
244
- infrastructureTools.push(registerSubmitReportTool);
245
- logger.info("Testbot tools enabled via SKYRAMP_FEATURE_TESTBOT");
246
- }
247
- infrastructureTools.forEach((registerTool) => registerTool(server));
248
- // Register Playwright browser tools (trace recording via browser automation).
249
- //
250
- // Tell the capture which attribute this repository uses for test ids. Without
251
- // it the capture assumes Playwright's `data-testid`, and a repo using anything
252
- // else gets no test-id anchor and a positional xpath for every element — which
253
- // resolves at capture time and breaks later, so the miss never announces itself
254
- // (SKYR-4136). This server is the only component that knows which repository it
255
- // is running against.
256
- //
257
- // A declared `use.testIdAttribute` is authoritative. Failing that, the
258
- // repository's own tests name the attribute whenever they select on it, so read
259
- // it out of their selectors rather than guessing from a list of popular names.
260
- // Never fatal: no answer leaves the capture on Playwright's default.
261
- (async () => {
262
- let testIdAttribute;
263
- try {
264
- const root = await findRoot(process.cwd());
265
- testIdAttribute = await readTestIdAttribute(root);
266
- if (testIdAttribute) {
267
- logger.info(`testIdAttribute declared by the Playwright config: ${testIdAttribute}`);
268
- }
269
- else {
270
- const discovered = await discoverTestIdAttribute(root);
271
- testIdAttribute = discovered.attribute;
158
+ // Register prompts
159
+ logger.info("Starting prompt registration process");
160
+ const prompts = [
161
+ registerStartTraceCollectionPrompt,
162
+ registerRecommendTestsPrompt,
163
+ registerTraceRecordingPrompt,
164
+ ];
165
+ if (isTestbotEnabled()) {
166
+ prompts.push(registerTestbotPrompt);
167
+ registerTestbotResource(server);
168
+ logger.info("Testbot prompt enabled via SKYRAMP_FEATURE_TESTBOT");
169
+ }
170
+ if (isLocalDevEnabled()) {
171
+ prompts.push(registerLocalDevPrompt);
172
+ logger.info("Local-dev prompt enabled via SKYRAMP_FEATURE_LOCAL_DEV");
173
+ }
174
+ prompts.forEach((registerPrompt) => registerPrompt(server));
175
+ logger.info("All prompts registered successfully");
176
+ // Register test generation tools
177
+ const testGenerationTools = [
178
+ registerSmokeTestTool,
179
+ registerFuzzTestTool,
180
+ registerContractTestTool,
181
+ registerLoadTestTool,
182
+ registerIntegrationTestTool,
183
+ registerE2ETestTool,
184
+ registerUITestTool,
185
+ registerUILoadTestTool,
186
+ registerBatchScenarioTestTool,
187
+ registerMockTool,
188
+ registerBatchMockTool,
189
+ ];
190
+ testGenerationTools.forEach((registerTool) => registerTool(server));
191
+ // Register modularization and code quality tools
192
+ const codeQualityTools = [
193
+ registerModularizationTool,
194
+ registerCodeReuseTool,
195
+ registerEnhanceAssertionsTool,
196
+ registerAssertionVerifyTool,
197
+ registerVerifyTestDependenciesTool,
198
+ ];
199
+ // With the Skyramp plugin loaded the agent already has the
200
+ // fix-test-import-errors skill; the tool would be a second copy of
201
+ // the same text (SKYR-4296).
202
+ if (!isSkillsLoaded()) {
203
+ // Same reasoning as fix-test-import-errors: with the plugin loaded the agent
204
+ // has the validate-assertion-alignment-post-execution skill directly; this
205
+ // tool exists so an agent without skill support still gets the same
206
+ // procedure, rendered from the same markdown with real arguments filled in.
207
+ codeQualityTools.push(registerFixErrorTool, registerAlignAssertionsTool);
208
+ }
209
+ else {
210
+ // The enhance-assertions skill drives its own snapshot step itself (SKYR-4310).
211
+ codeQualityTools.push(registerAssertionSnapshotTool);
212
+ }
213
+ codeQualityTools.forEach((registerTool) => registerTool(server));
214
+ // Register analysis resources (MCP Resources for enriched data access)
215
+ registerAnalysisResources(server);
216
+ registerProgressResource(server);
217
+ // Register unified test-management tools (replaces separate test-maintenance tools)
218
+ registerAnalyzeChangesTool(server);
219
+ registerAnalyzeTestHealthTool(server);
220
+ registerActionsTool(server);
221
+ registerRegisterTestPlanTool(server);
222
+ registerResolveScreenTool(server);
223
+ // Register workspace management tools
224
+ registerInitScanWorkspaceTool(server);
225
+ registerInitializeWorkspaceTool(server);
226
+ // Register one-click orchestrated workflows
227
+ if (oneClickEnabled || localDevEnabled) {
228
+ registerOneClickTool(server);
229
+ logger.info("One-click tools enabled", {
230
+ enabledBy: {
231
+ SKYRAMP_FEATURE_ONE_CLICK: oneClickEnabled,
232
+ SKYRAMP_FEATURE_LOCAL_DEV: localDevEnabled,
233
+ },
234
+ });
235
+ }
236
+ // Register other Skyramp tools
237
+ const infrastructureTools = [
238
+ registerLoginTool,
239
+ registerLogoutTool,
240
+ registerExecuteSkyrampTestTool,
241
+ registerExecuteFleetTool,
242
+ registerTraceTool,
243
+ registerTraceStopTool,
244
+ ];
245
+ if (isLocalDevEnabled()) {
246
+ infrastructureTools.push(registerEnrichTestWithMocksTool, registerPreflightMockCheckTool, registerGenerateEnrichedIntegrationTestTool, registerLocalDevWorkerComposeTool, registerQueryProxyMocksTool);
247
+ logger.info("Local-dev tools enabled via SKYRAMP_FEATURE_LOCAL_DEV");
248
+ }
249
+ if (isTestbotEnabled()) {
250
+ infrastructureTools.push(registerSubmitReportTool);
251
+ logger.info("Testbot tools enabled via SKYRAMP_FEATURE_TESTBOT");
252
+ }
253
+ infrastructureTools.forEach((registerTool) => registerTool(server));
254
+ // Register Playwright browser tools (trace recording via browser automation).
255
+ //
256
+ // Tell the capture which attribute this repository uses for test ids. Without
257
+ // it the capture assumes Playwright's `data-testid`, and a repo using anything
258
+ // else gets no test-id anchor and a positional xpath for every element — which
259
+ // resolves at capture time and breaks later, so the miss never announces itself
260
+ // (SKYR-4136). This server is the only component that knows which repository it
261
+ // is running against.
262
+ //
263
+ // A declared `use.testIdAttribute` is authoritative. Failing that, the
264
+ // repository's own tests name the attribute whenever they select on it, so read
265
+ // it out of their selectors rather than guessing from a list of popular names.
266
+ // Never fatal: no answer leaves the capture on Playwright's default.
267
+ //
268
+ // Awaited, and worth the wait: `PlaywrightTraceService.initialize()` is 206ms
269
+ // of it and the browser tools come out of that service, so nothing can
270
+ // register them earlier. Running it in the background instead delays every
271
+ // connection's first response by nothing but leaves the client holding 27
272
+ // tools of 52 — Claude Code does not re-list on `tools/list_changed`, so all
273
+ // 23 `browser_*` tools stay invisible for the whole run.
274
+ await (async () => {
275
+ let testIdAttribute;
276
+ try {
277
+ const root = await findRoot(process.cwd());
278
+ testIdAttribute = await readTestIdAttribute(root);
272
279
  if (testIdAttribute) {
273
- // Log the runner-up counts: on a part-migrated repo the most-used
274
- // attribute wins, and a wrong pick should be visible here rather than
275
- // showing up later as brittle selectors.
276
- logger.info(`testIdAttribute discovered from test selectors: ${testIdAttribute}`, { counts: discovered.counts, filesScanned: discovered.filesScanned });
280
+ logger.info(`testIdAttribute declared by the Playwright config: ${testIdAttribute}`);
277
281
  }
278
282
  else {
279
- // No name rule can reach an arbitrary convention like `xyz-id`, so name
280
- // what the selectors did contain and the variable that overrides it.
281
- // Editing the repo's own Playwright config is the wrong instruction: a
282
- // suite may have several, and none of them at the root.
283
- logger.info("No testIdAttribute declared or discovered — capture stays on Playwright's data-testid. " +
284
- "Set PLAYWRIGHT_MCP_TEST_ID_ATTRIBUTE to override.", {
285
- attributesSeenInSelectors: discovered.observed,
286
- filesScanned: discovered.filesScanned,
287
- });
283
+ const discovered = await discoverTestIdAttribute(root);
284
+ testIdAttribute = discovered.attribute;
285
+ if (testIdAttribute) {
286
+ // Log the runner-up counts: on a part-migrated repo the most-used
287
+ // attribute wins, and a wrong pick should be visible here rather than
288
+ // showing up later as brittle selectors.
289
+ logger.info(`testIdAttribute discovered from test selectors: ${testIdAttribute}`, {
290
+ counts: discovered.counts,
291
+ filesScanned: discovered.filesScanned,
292
+ });
293
+ }
294
+ else {
295
+ // No name rule can reach an arbitrary convention like `xyz-id`, so name
296
+ // what the selectors did contain and the variable that overrides it.
297
+ // Editing the repo's own Playwright config is the wrong instruction: a
298
+ // suite may have several, and none of them at the root.
299
+ logger.info("No testIdAttribute declared or discovered — capture stays on Playwright's data-testid. " +
300
+ "Set PLAYWRIGHT_MCP_TEST_ID_ATTRIBUTE to override.", {
301
+ attributesSeenInSelectors: discovered.observed,
302
+ filesScanned: discovered.filesScanned,
303
+ });
304
+ }
288
305
  }
289
306
  }
290
- }
291
- catch (err) {
292
- logger.warning("Could not determine this repository's testIdAttribute", {
293
- error: err,
307
+ catch (err) {
308
+ logger.warning("Could not determine this repository's testIdAttribute", {
309
+ error: err,
310
+ });
311
+ }
312
+ await registerPlaywrightTools(server, { testIdAttribute });
313
+ })().catch((err) => {
314
+ logger.error("Failed to register Playwright tools", { error: err });
315
+ });
316
+ const runInitTrigger = () => {
317
+ registerInitTriggerOnMCPInitialized().catch((err) => {
318
+ logger.error("Failed to run MCP initialized trigger", { error: err });
294
319
  });
295
- }
296
- await registerPlaywrightTools(server, { testIdAttribute });
297
- })().catch((err) => {
298
- logger.error("Failed to register Playwright tools", { error: err });
299
- });
320
+ };
321
+ server.server.oninitialized = runInitTrigger;
322
+ // A 2026-07-28 connection has no `initialize` exchange, so `oninitialized`
323
+ // never fires on it.
324
+ if (era === "modern")
325
+ runInitTrigger();
326
+ return server;
327
+ }
300
328
  // Global error handlers for crash telemetry
301
329
  process.on("uncaughtException", async (error) => {
302
330
  // Don't send analytics for EPIPE errors
@@ -350,13 +378,11 @@ process.on("unhandledRejection", async (reason) => {
350
378
  });
351
379
  // Start MCP server
352
380
  async function main() {
353
- const transport = new StdioServerTransport();
354
- server.server.oninitialized = () => {
355
- registerInitTriggerOnMCPInitialized().catch((err) => {
356
- logger.error("Failed to run MCP initialized trigger", { error: err });
357
- });
358
- };
359
- await server.connect(transport);
381
+ // `serveStdio` owns the era decision: it reads the opening exchange and pins
382
+ // one instance from the factory for the connection. `StdioServerTransport`
383
+ // serves the 2025 handshake only, so the 2026-07-28 revision is unreachable
384
+ // through it however the client asks.
385
+ const handle = serveStdio(createServer);
360
386
  logger.info("MCP Server started successfully");
361
387
  // Listen for stdin closure (parent process disconnected)
362
388
  // Using multiple events for robustness across different disconnection scenarios
@@ -372,7 +398,7 @@ async function main() {
372
398
  ? playwrightService.shutdown().catch(() => { })
373
399
  : Promise.resolve();
374
400
  cleanupPlaywright.finally(() => {
375
- server.close().finally(() => {
401
+ handle.close().finally(() => {
376
402
  process.exit(0);
377
403
  });
378
404
  });
@@ -5,7 +5,7 @@
5
5
  * The Playwright fork is CJS; this project is ESM. We use createRequire
6
6
  * to bridge the module systems.
7
7
  */
8
- import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
8
+ import type { CallToolResult } from "@modelcontextprotocol/server";
9
9
  interface McpTool {
10
10
  name: string;
11
11
  description?: string;
@@ -1,4 +1,4 @@
1
- import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
1
+ import type { CallToolResult } from "@modelcontextprotocol/server";
2
2
  import type { BlueprintCaptureDigest } from "../types/BlueprintDigest.js";
3
3
  /** A run that takes more captures than this has a browsing problem of its own;
4
4
  * the cap is here so a runaway loop cannot grow the process without bound. */
@@ -3,6 +3,6 @@
3
3
  * tools in the Skyramp MCP server, delegating calls to PlaywrightTraceService.
4
4
  */
5
5
  import { PlaywrightTraceService, type PlaywrightTraceOptions } from "./PlaywrightTraceService.js";
6
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
+ import type { McpServer } from "@modelcontextprotocol/server";
7
7
  export declare function getPlaywrightTraceService(): PlaywrightTraceService | null;
8
8
  export declare function registerPlaywrightTools(server: McpServer, options?: PlaywrightTraceOptions): Promise<void>;
@@ -2,7 +2,7 @@
2
2
  * MCP prompt that guides the LLM through the Playwright-based trace recording
3
3
  * and Skyramp test generation flow.
4
4
  */
5
- import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
+ import type { McpServer } from "@modelcontextprotocol/server";
6
6
  export interface TraceRecordingPromptOpts {
7
7
  /** Directory where zip files should be written. Defaults to same dir as test file. */
8
8
  outputDir?: string;
@@ -82,7 +82,7 @@ export function registerTraceRecordingPrompt(server) {
82
82
  logger.info("Registering trace recording prompt");
83
83
  server.registerPrompt("skyramp_trace_recording_prompt", {
84
84
  description: "Guide for recording browser interactions as a Skyramp trace and generating UI tests",
85
- argsSchema: {
85
+ argsSchema: z.object({
86
86
  outputDir: z
87
87
  .string()
88
88
  .optional()
@@ -92,7 +92,7 @@ export function registerTraceRecordingPrompt(server) {
92
92
  .default(true)
93
93
  .optional()
94
94
  .describe("Whether to run skyramp_modularization after generation. Default: true. Set to false in CI."),
95
- },
95
+ }),
96
96
  }, (args) => ({
97
97
  messages: [
98
98
  {
@@ -1 +1,18 @@
1
1
  export declare const INIT_WORKSPACE_INSTRUCTIONS: string;
2
+ /** A repository of the Target other than the workspace's own, scanned into the same workspace.yml. */
3
+ export interface ScanRelatedRepository {
4
+ /** owner/repo, set verbatim as each of its services' `repository`. */
5
+ repository: string;
6
+ repositoryPath: string;
7
+ }
8
+ /**
9
+ * The scan instructions for one workspace. With related repositories, every
10
+ * repository is scanned into the one workspace.yml at `workspacePath`, each
11
+ * related repository's services carrying its `repository`. With a test
12
+ * repository, testDirectory is read from, and relative to, that checkout.
13
+ */
14
+ export declare function buildInitWorkspaceInstructions(target: {
15
+ workspacePath: string;
16
+ relatedRepositories?: ScanRelatedRepository[];
17
+ testRepositoryPath?: string;
18
+ }): string;