@skyramp/mcp 0.3.2-rc.pom-3 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/commands/commandLibrary.d.ts +1 -0
- package/build/commands/commandLibrary.js +19 -13
- package/build/commands/localDevTestChangesCommand.d.ts +15 -0
- package/build/commands/localDevTestChangesCommand.js +201 -0
- package/build/index.js +80 -6
- package/build/prompts/code-reuse.js +3 -0
- package/build/prompts/enhance-assertions/sharedAssertionRules.d.ts +1 -0
- package/build/prompts/enhance-assertions/sharedAssertionRules.js +17 -0
- package/build/prompts/initialize-workspace/initializeWorkspacePrompt.js +11 -9
- package/build/prompts/local-dev/local-dev-plan.d.ts +35 -0
- package/build/prompts/local-dev/local-dev-plan.js +429 -0
- package/build/prompts/local-dev/local-dev-prompts.d.ts +4 -0
- package/build/prompts/local-dev/local-dev-prompts.js +190 -0
- package/build/prompts/pom-aware-code-reuse.js +12 -0
- package/build/prompts/prompt-utils.d.ts +8 -0
- package/build/prompts/prompt-utils.js +33 -0
- package/build/prompts/sut-setup/modes/adaptWorkflowPrompt.js +37 -14
- package/build/prompts/sut-setup/shared.js +16 -12
- package/build/prompts/test-recommendation/analysisOutputPrompt.js +21 -29
- package/build/prompts/test-recommendation/scopeAssessment.d.ts +24 -7
- package/build/prompts/test-recommendation/scopeAssessment.js +111 -12
- package/build/prompts/test-recommendation/test-recommendation-prompt.js +41 -4
- package/build/prompts/testbot/testbot-prompts.d.ts +0 -5
- package/build/prompts/testbot/testbot-prompts.js +32 -52
- package/build/recommendation/planRanker.d.ts +15 -2
- package/build/recommendation/planRanker.js +76 -5
- package/build/resources/testbotResource.js +2 -1
- package/build/services/AnalyticsService.d.ts +1 -1
- package/build/services/TestExecutionService.d.ts +2 -1
- package/build/services/TestExecutionService.js +8 -3
- package/build/services/TestGenerationService.d.ts +2 -2
- package/build/services/TestGenerationService.js +39 -21
- package/build/services/containerEnv.js +3 -1
- package/build/tool-phases.js +6 -0
- package/build/tools/code-refactor/codeReuseTool.js +43 -4
- package/build/tools/code-refactor/enhanceAssertionsTool.js +68 -18
- package/build/tools/code-refactor/reuse-outcome.d.ts +109 -0
- package/build/tools/code-refactor/reuse-outcome.js +158 -0
- package/build/tools/code-refactor/reuse-state.d.ts +45 -0
- package/build/tools/code-refactor/reuse-state.js +140 -0
- package/build/tools/enrichTestWithMocksTool.d.ts +28 -0
- package/build/tools/enrichTestWithMocksTool.js +726 -0
- package/build/tools/executeSkyrampTestTool.d.ts +11 -0
- package/build/tools/executeSkyrampTestTool.js +62 -21
- package/build/tools/generate-tests/batchMockGenerationTool.d.ts +106 -0
- package/build/tools/generate-tests/batchMockGenerationTool.js +545 -0
- package/build/tools/generate-tests/generateBatchScenarioRestTool.js +25 -23
- package/build/tools/generate-tests/generateContractRestTool.js +2 -2
- package/build/tools/generate-tests/generateE2ERestTool.d.ts +1 -1
- package/build/tools/generate-tests/generateE2ERestTool.js +1 -1
- package/build/tools/generate-tests/generateLoadRestTool.d.ts +1 -1
- package/build/tools/generate-tests/generateLoadRestTool.js +1 -1
- package/build/tools/generate-tests/generateMockRestTool.d.ts +179 -6
- package/build/tools/generate-tests/generateMockRestTool.js +391 -22
- package/build/tools/generate-tests/loadTestSchema.d.ts +1 -1
- package/build/tools/generate-tests/planGuard.js +2 -22
- package/build/tools/generateEnrichedIntegrationTestTool.d.ts +25 -0
- package/build/tools/generateEnrichedIntegrationTestTool.js +235 -0
- package/build/tools/localDevWorkerComposeTool.d.ts +24 -0
- package/build/tools/localDevWorkerComposeTool.js +264 -0
- package/build/tools/one-click/oneClickTool.d.ts +13 -0
- package/build/tools/one-click/oneClickTool.js +195 -24
- package/build/tools/preflightMockCheckTool.d.ts +2 -0
- package/build/tools/preflightMockCheckTool.js +96 -0
- package/build/tools/queryProxyMocksTool.d.ts +70 -0
- package/build/tools/queryProxyMocksTool.js +522 -0
- package/build/tools/runExistingTestsTool.d.ts +31 -0
- package/build/tools/runExistingTestsTool.js +214 -13
- package/build/tools/submitReportTool.js +38 -3
- package/build/tools/test-management/analyzeChangesTool.d.ts +2 -1
- package/build/tools/test-management/analyzeChangesTool.js +63 -40
- package/build/tools/test-management/registerTestPlanTool.js +55 -7
- package/build/tools/trace/startTraceCollectionTool.js +3 -3
- package/build/types/FrontendIntegration.d.ts +3 -0
- package/build/types/FrontendIntegration.js +3 -0
- package/build/types/OneClickCommands.d.ts +1 -1
- package/build/types/Recommendation.d.ts +20 -0
- package/build/types/Recommendation.js +32 -6
- package/build/types/RepositoryAnalysis.d.ts +131 -14
- package/build/types/RepositoryAnalysis.js +16 -2
- package/build/types/ReuseOutcome.d.ts +63 -0
- package/build/types/ReuseOutcome.js +33 -0
- package/build/types/TestExecution.d.ts +1 -0
- package/build/types/TestTypes.d.ts +25 -7
- package/build/types/TestTypes.js +22 -6
- package/build/types/TestbotReport.d.ts +7 -0
- package/build/types/index.d.ts +2 -0
- package/build/types/index.js +1 -0
- package/build/utils/AnalysisStateManager.d.ts +26 -0
- package/build/utils/AnalysisStateManager.js +31 -1
- package/build/utils/analyze-openapi.js +18 -1
- package/build/utils/branchDiff.d.ts +17 -1
- package/build/utils/branchDiff.js +99 -14
- package/build/utils/featureFlags.d.ts +31 -0
- package/build/utils/featureFlags.js +37 -0
- package/build/utils/frontendIntegration.js +8 -1
- package/build/utils/grpcMockValidation.d.ts +1 -0
- package/build/utils/grpcMockValidation.js +49 -0
- package/build/utils/httpMethodValidation.d.ts +4 -0
- package/build/utils/httpMethodValidation.js +15 -0
- package/build/utils/logger.js +1 -1
- package/build/utils/mockCompatibility.d.ts +49 -0
- package/build/utils/mockCompatibility.js +82 -0
- package/build/utils/pom-scope/pom-files.js +7 -0
- package/build/utils/pom-verify/bindings.js +11 -1
- package/build/utils/pom-verify/re-exports.d.ts +10 -0
- package/build/utils/pom-verify/re-exports.js +61 -0
- package/build/utils/pom-verify/resolve.d.ts +4 -1
- package/build/utils/pom-verify/resolve.js +7 -4
- package/build/utils/pom-verify/verify.d.ts +5 -0
- package/build/utils/pom-verify/verify.js +25 -3
- package/build/utils/progress.js +10 -5
- package/build/utils/proxy-terminal.js +3 -3
- package/build/utils/routeParsers.d.ts +3 -9
- package/build/utils/routeParsers.js +79 -4
- package/build/utils/utils.js +2 -2
- package/build/utils/versions.d.ts +4 -3
- package/build/utils/versions.js +3 -1
- package/build/utils/workspaceAuth.d.ts +46 -0
- package/build/utils/workspaceAuth.js +156 -1
- package/build/workspace/testSuites.d.ts +2 -1
- package/build/workspace/testSuites.js +1 -1
- package/build/workspace/workspace.d.ts +108 -32
- package/build/workspace/workspace.js +32 -4
- package/package.json +5 -2
- package/build/adapters/jestAdapter.test.d.ts +0 -1
- package/build/adapters/jestAdapter.test.js +0 -93
- package/build/adapters/mochaAdapter.test.d.ts +0 -1
- package/build/adapters/mochaAdapter.test.js +0 -63
- package/build/adapters/playwrightAdapter.test.d.ts +0 -1
- package/build/adapters/playwrightAdapter.test.js +0 -169
- package/build/adapters/pytestAdapter.test.d.ts +0 -1
- package/build/adapters/pytestAdapter.test.js +0 -90
- package/build/prompts/code-reuse.test.d.ts +0 -1
- package/build/prompts/code-reuse.test.js +0 -62
- package/build/prompts/pom-aware-code-reuse.test.d.ts +0 -1
- package/build/prompts/pom-aware-code-reuse.test.js +0 -11
- package/build/prompts/test-maintenance/drift-analysis-prompt.test.d.ts +0 -1
- package/build/prompts/test-maintenance/drift-analysis-prompt.test.js +0 -51
- package/build/prompts/test-recommendation/analysisOutputPrompt.test.d.ts +0 -1
- package/build/prompts/test-recommendation/analysisOutputPrompt.test.js +0 -264
- package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.d.ts +0 -1
- package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.js +0 -126
- package/build/prompts/test-recommendation/promptPlan.test.d.ts +0 -1
- package/build/prompts/test-recommendation/promptPlan.test.js +0 -336
- package/build/prompts/test-recommendation/scopeAssessment.test.d.ts +0 -1
- package/build/prompts/test-recommendation/scopeAssessment.test.js +0 -371
- package/build/prompts/test-recommendation/test-recommendation-prompt.test.d.ts +0 -1
- package/build/prompts/test-recommendation/test-recommendation-prompt.test.js +0 -1925
- package/build/prompts/testbot/testbot-prompts.test.d.ts +0 -1
- package/build/prompts/testbot/testbot-prompts.test.js +0 -451
- package/build/recommendation/budgeters/diversityBalancedBudgeter.test.d.ts +0 -1
- package/build/recommendation/budgeters/diversityBalancedBudgeter.test.js +0 -138
- package/build/recommendation/budgeters/fixedNBudgeter.test.d.ts +0 -1
- package/build/recommendation/budgeters/fixedNBudgeter.test.js +0 -66
- package/build/recommendation/discriminators.test.d.ts +0 -1
- package/build/recommendation/discriminators.test.js +0 -324
- package/build/recommendation/diversity.test.d.ts +0 -1
- package/build/recommendation/diversity.test.js +0 -77
- package/build/recommendation/planRanker.test.d.ts +0 -1
- package/build/recommendation/planRanker.test.js +0 -110
- package/build/resources/testbotResource.test.d.ts +0 -1
- package/build/resources/testbotResource.test.js +0 -44
- package/build/services/AnalyticsService.test.d.ts +0 -1
- package/build/services/AnalyticsService.test.js +0 -86
- package/build/services/ScenarioGenerationService.integration.test.d.ts +0 -1
- package/build/services/ScenarioGenerationService.integration.test.js +0 -162
- package/build/services/ScenarioGenerationService.test.d.ts +0 -1
- package/build/services/ScenarioGenerationService.test.js +0 -414
- package/build/services/TestDiscoveryService.test.d.ts +0 -1
- package/build/services/TestDiscoveryService.test.js +0 -983
- package/build/services/TestExecutionService.test.d.ts +0 -1
- package/build/services/TestExecutionService.test.js +0 -1032
- package/build/services/TestGenerationService.test.d.ts +0 -1
- package/build/services/TestGenerationService.test.js +0 -578
- package/build/tool-phase-coverage.test.d.ts +0 -1
- package/build/tool-phase-coverage.test.js +0 -49
- package/build/tools/code-refactor/codeReuseTool.test.d.ts +0 -1
- package/build/tools/code-refactor/codeReuseTool.test.js +0 -572
- package/build/tools/generate-tests/generateBatchScenarioRestTool.test.d.ts +0 -1
- package/build/tools/generate-tests/generateBatchScenarioRestTool.test.js +0 -433
- package/build/tools/generate-tests/generateContractRestTool.test.d.ts +0 -1
- package/build/tools/generate-tests/generateContractRestTool.test.js +0 -142
- package/build/tools/generate-tests/generateIntegrationRestTool.test.d.ts +0 -1
- package/build/tools/generate-tests/generateIntegrationRestTool.test.js +0 -159
- package/build/tools/generate-tests/generateLoadRestTool.test.d.ts +0 -1
- package/build/tools/generate-tests/generateLoadRestTool.test.js +0 -169
- package/build/tools/generate-tests/generateUIRestTool.test.d.ts +0 -1
- package/build/tools/generate-tests/generateUIRestTool.test.js +0 -32
- package/build/tools/generate-tests/planGuard.test.d.ts +0 -1
- package/build/tools/generate-tests/planGuard.test.js +0 -185
- package/build/tools/generate-tests/scenarioLint.test.d.ts +0 -1
- package/build/tools/generate-tests/scenarioLint.test.js +0 -100
- package/build/tools/runExistingTestsTool.test.d.ts +0 -1
- package/build/tools/runExistingTestsTool.test.js +0 -379
- package/build/tools/submitReportTool.test.d.ts +0 -1
- package/build/tools/submitReportTool.test.js +0 -1428
- package/build/tools/test-management/actionsTool.test.d.ts +0 -1
- package/build/tools/test-management/actionsTool.test.js +0 -436
- package/build/tools/test-management/analyzeChangesTool.test.d.ts +0 -1
- package/build/tools/test-management/analyzeChangesTool.test.js +0 -522
- package/build/tools/test-management/analyzeTestHealthTool.test.d.ts +0 -1
- package/build/tools/test-management/analyzeTestHealthTool.test.js +0 -385
- package/build/tools/test-management/registerTestPlanTool.test.d.ts +0 -1
- package/build/tools/test-management/registerTestPlanTool.test.js +0 -296
- package/build/tools/trace/resolveSaveStoragePath.test.d.ts +0 -1
- package/build/tools/trace/resolveSaveStoragePath.test.js +0 -17
- package/build/tools/trace/resolveSessionPaths.test.d.ts +0 -1
- package/build/tools/trace/resolveSessionPaths.test.js +0 -104
- package/build/tools/trace/sessionState.test.d.ts +0 -1
- package/build/tools/trace/sessionState.test.js +0 -17
- package/build/tools/workspace/initializeWorkspaceTool.test.d.ts +0 -1
- package/build/tools/workspace/initializeWorkspaceTool.test.js +0 -139
- package/build/tools/workspace/serviceUpsert.test.d.ts +0 -1
- package/build/tools/workspace/serviceUpsert.test.js +0 -50
- package/build/utils/AnalysisStateManager.test.d.ts +0 -1
- package/build/utils/AnalysisStateManager.test.js +0 -134
- package/build/utils/dartRouteExtractor.test.d.ts +0 -1
- package/build/utils/dartRouteExtractor.test.js +0 -307
- package/build/utils/docker.test.d.ts +0 -1
- package/build/utils/docker.test.js +0 -114
- package/build/utils/featureFlags.test.d.ts +0 -1
- package/build/utils/featureFlags.test.js +0 -81
- package/build/utils/fileWalk.test.d.ts +0 -1
- package/build/utils/fileWalk.test.js +0 -252
- package/build/utils/frontendIntegration.test.d.ts +0 -1
- package/build/utils/frontendIntegration.test.js +0 -229
- package/build/utils/frontendSelectors.test.d.ts +0 -1
- package/build/utils/frontendSelectors.test.js +0 -118
- package/build/utils/gitStaging.test.d.ts +0 -1
- package/build/utils/gitStaging.test.js +0 -111
- package/build/utils/httpDefaults.test.d.ts +0 -1
- package/build/utils/httpDefaults.test.js +0 -21
- package/build/utils/importerHop.test.d.ts +0 -1
- package/build/utils/importerHop.test.js +0 -469
- package/build/utils/pathAffinityClassification.test.d.ts +0 -1
- package/build/utils/pathAffinityClassification.test.js +0 -208
- package/build/utils/planMatchKeys.test.d.ts +0 -1
- package/build/utils/planMatchKeys.test.js +0 -123
- package/build/utils/pom-scope/index.test.d.ts +0 -1
- package/build/utils/pom-scope/index.test.js +0 -278
- package/build/utils/pom-scope/pom-files.test.d.ts +0 -1
- package/build/utils/pom-scope/pom-files.test.js +0 -29
- package/build/utils/pom-scope/scoring.test.d.ts +0 -1
- package/build/utils/pom-scope/scoring.test.js +0 -39
- package/build/utils/pom-scope/selector-extractor.test.d.ts +0 -1
- package/build/utils/pom-scope/selector-extractor.test.js +0 -67
- package/build/utils/pom-verify/bindings.test.d.ts +0 -1
- package/build/utils/pom-verify/bindings.test.js +0 -164
- package/build/utils/pom-verify/calls.test.d.ts +0 -1
- package/build/utils/pom-verify/calls.test.js +0 -61
- package/build/utils/pom-verify/resolve.test.d.ts +0 -1
- package/build/utils/pom-verify/resolve.test.js +0 -114
- package/build/utils/pom-verify/verify.test.d.ts +0 -1
- package/build/utils/pom-verify/verify.test.js +0 -374
- package/build/utils/pr-comment-parser.test.d.ts +0 -1
- package/build/utils/pr-comment-parser.test.js +0 -428
- package/build/utils/progress.test.d.ts +0 -1
- package/build/utils/progress.test.js +0 -37
- package/build/utils/projectMetadata.test.d.ts +0 -1
- package/build/utils/projectMetadata.test.js +0 -172
- package/build/utils/pythonMountPrefixes.test.d.ts +0 -1
- package/build/utils/pythonMountPrefixes.test.js +0 -113
- package/build/utils/repoScanner.test.d.ts +0 -1
- package/build/utils/repoScanner.test.js +0 -190
- package/build/utils/reportVerification.test.d.ts +0 -1
- package/build/utils/reportVerification.test.js +0 -185
- package/build/utils/routeParsers.test.d.ts +0 -1
- package/build/utils/routeParsers.test.js +0 -1011
- package/build/utils/scenarioDrafting.test.d.ts +0 -1
- package/build/utils/scenarioDrafting.test.js +0 -876
- package/build/utils/sourceRouteExtractor.test.d.ts +0 -1
- package/build/utils/sourceRouteExtractor.test.js +0 -738
- package/build/utils/telemetry.test.d.ts +0 -1
- package/build/utils/telemetry.test.js +0 -70
- package/build/utils/trace-parser.test.d.ts +0 -6
- package/build/utils/trace-parser.test.js +0 -140
- package/build/utils/uiPageEnumerator.test.d.ts +0 -1
- package/build/utils/uiPageEnumerator.test.js +0 -824
- package/build/utils/utils.test.d.ts +0 -1
- package/build/utils/utils.test.js +0 -103
- package/build/utils/walkerCharacterization.test.d.ts +0 -1
- package/build/utils/walkerCharacterization.test.js +0 -233
- package/build/utils/workspaceAuth.test.d.ts +0 -1
- package/build/utils/workspaceAuth.test.js +0 -260
- package/build/workspace/testSuites.test.d.ts +0 -1
- package/build/workspace/testSuites.test.js +0 -23
- package/build/workspace/workspace.test.d.ts +0 -1
- package/build/workspace/workspace.test.js +0 -264
|
@@ -9,3 +9,4 @@ export declare function getCommandIds(): OneClickCommandId[];
|
|
|
9
9
|
export declare function lookupCommand(id: string): OneClickCommandDef;
|
|
10
10
|
export { TEST_GIVEN_ENDPOINT_COMPREHENSIVELY_COMMAND } from "./testThisEndpointCommand.js";
|
|
11
11
|
export { FULLREPO_RECOMMEND_GENERATE_EXECUTE_TOPN_TESTS_COMMAND } from "./recommendTestsAndExecuteCommand.js";
|
|
12
|
+
export { LOCAL_DEV_TEST_CHANGES_COMMAND } from "./localDevTestChangesCommand.js";
|
|
@@ -1,23 +1,28 @@
|
|
|
1
|
+
import { isLocalDevEnabled, isOneClickEnabled } from "../utils/featureFlags.js";
|
|
1
2
|
import { TEST_GIVEN_ENDPOINT_COMPREHENSIVELY_COMMAND } from "./testThisEndpointCommand.js";
|
|
2
3
|
import { FULLREPO_RECOMMEND_GENERATE_EXECUTE_TOPN_TESTS_COMMAND } from "./recommendTestsAndExecuteCommand.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* 2. Create a new file in commands/ (e.g. myWorkflowCommand.ts) with steps and export the command
|
|
7
|
-
* 3. Import the command here and add it to COMMAND_LIBRARY
|
|
8
|
-
* 4. The generic buildWorkflowFromCommand() will render detailed instructions from your steps
|
|
9
|
-
* (no schema changes needed in oneClickTool.ts — the workflow param description is generated dynamically)
|
|
10
|
-
*/
|
|
11
|
-
/** All predefined one-click commands */
|
|
12
|
-
const COMMAND_LIBRARY = {
|
|
4
|
+
import { LOCAL_DEV_TEST_CHANGES_COMMAND } from "./localDevTestChangesCommand.js";
|
|
5
|
+
/** Base predefined one-click commands */
|
|
6
|
+
const BASE_COMMAND_LIBRARY = {
|
|
13
7
|
test_given_endpoint_comprehensively: TEST_GIVEN_ENDPOINT_COMPREHENSIVELY_COMMAND,
|
|
14
8
|
full_repo_scan_recommend_generate_and_execute_top_n_tests: FULLREPO_RECOMMEND_GENERATE_EXECUTE_TOPN_TESTS_COMMAND,
|
|
15
9
|
};
|
|
10
|
+
/** All enabled predefined one-click commands */
|
|
11
|
+
function getCommandLibrary() {
|
|
12
|
+
const commands = {};
|
|
13
|
+
if (isOneClickEnabled()) {
|
|
14
|
+
Object.assign(commands, BASE_COMMAND_LIBRARY);
|
|
15
|
+
}
|
|
16
|
+
if (isLocalDevEnabled()) {
|
|
17
|
+
commands.local_dev_test_changes = LOCAL_DEV_TEST_CHANGES_COMMAND;
|
|
18
|
+
}
|
|
19
|
+
return commands;
|
|
20
|
+
}
|
|
16
21
|
export function getAllCommands() {
|
|
17
|
-
return Object.values(
|
|
22
|
+
return Object.values(getCommandLibrary()).filter((cmd) => Boolean(cmd));
|
|
18
23
|
}
|
|
19
24
|
export function getCommandIds() {
|
|
20
|
-
return
|
|
25
|
+
return getAllCommands().map((cmd) => cmd.id);
|
|
21
26
|
}
|
|
22
27
|
/**
|
|
23
28
|
* Look up a command by its string ID. Accepts any string so the tool handler
|
|
@@ -25,7 +30,7 @@ export function getCommandIds() {
|
|
|
25
30
|
* the ID is not found.
|
|
26
31
|
*/
|
|
27
32
|
export function lookupCommand(id) {
|
|
28
|
-
const cmd =
|
|
33
|
+
const cmd = getCommandLibrary()[id];
|
|
29
34
|
if (!cmd) {
|
|
30
35
|
const available = getCommandIds().join(", ");
|
|
31
36
|
throw new Error(`Unknown workflow: "${id}". Valid workflow IDs: ${available}.`);
|
|
@@ -35,3 +40,4 @@ export function lookupCommand(id) {
|
|
|
35
40
|
// Re-export commands for consumers that import from commandLibrary
|
|
36
41
|
export { TEST_GIVEN_ENDPOINT_COMPREHENSIVELY_COMMAND } from "./testThisEndpointCommand.js";
|
|
37
42
|
export { FULLREPO_RECOMMEND_GENERATE_EXECUTE_TOPN_TESTS_COMMAND } from "./recommendTestsAndExecuteCommand.js";
|
|
43
|
+
export { LOCAL_DEV_TEST_CHANGES_COMMAND } from "./localDevTestChangesCommand.js";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { OneClickCommandDef } from "../types/OneClickCommands.js";
|
|
2
|
+
/**
|
|
3
|
+
* Predefined One-Click Command: Local Dev — Test Changes
|
|
4
|
+
*
|
|
5
|
+
* This is the BOOTSTRAPPER / ENTRY POINT for local-dev testing.
|
|
6
|
+
* It handles first-time setup (skills + workspace), then delegates
|
|
7
|
+
* the actual test workflow to the `skyramp_local_dev` MCP prompt.
|
|
8
|
+
*
|
|
9
|
+
* Flow:
|
|
10
|
+
* Step 0: Install IDE skill into repo for the calling agent
|
|
11
|
+
* Step 1: Ensure .skyramp/workspace.yml exists
|
|
12
|
+
* Step 2: Invoke skyramp_local_dev prompt (which runs the full workflow)
|
|
13
|
+
*/
|
|
14
|
+
export declare const LOCAL_DEV_SKILL_CONTENT = "---\nname: local-dev\ndescription: Run the Skyramp MCP local-dev workflow to test local code changes against a base branch. Use when the user asks to test changes, mock downstream services, validate a feature branch, run local-dev, or verify a PR before merge.\nuser_invocable: true\n---\n\n# local-dev\n\nUse the Skyramp MCP local-dev workflow as the source of truth. Do not recreate the workflow steps from this skill.\n\n## Usage\n\n`/local-dev` \u2014 diff against main (default)\n`/local-dev main --mock stripe,billing --real postgres,redis`\n\n## Invocation\n\nCall the `skyramp_local_dev` MCP prompt with the user's intent preserved:\n- `baseCommit`: branch/SHA to diff against (default: main)\n- `repositoryPath`: absolute path to repo\n- `servicesToMock`: comma-separated services the user explicitly wants mocked\n- `realServices`: comma-separated services that should receive real traffic\n- `mockProtocols`: comma-separated protocols the user explicitly wants mocked (for example, `rest`)\n\nBy default, mock only true third-party downstream services. Keep the service under test, infrastructure, and local first-party services real unless the user explicitly asks to mock them.\n";
|
|
15
|
+
export declare const LOCAL_DEV_TEST_CHANGES_COMMAND: OneClickCommandDef;
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { localDevPlan, } from "../prompts/local-dev/local-dev-plan.js";
|
|
2
|
+
/**
|
|
3
|
+
* Predefined One-Click Command: Local Dev — Test Changes
|
|
4
|
+
*
|
|
5
|
+
* This is the BOOTSTRAPPER / ENTRY POINT for local-dev testing.
|
|
6
|
+
* It handles first-time setup (skills + workspace), then delegates
|
|
7
|
+
* the actual test workflow to the `skyramp_local_dev` MCP prompt.
|
|
8
|
+
*
|
|
9
|
+
* Flow:
|
|
10
|
+
* Step 0: Install IDE skill into repo for the calling agent
|
|
11
|
+
* Step 1: Ensure .skyramp/workspace.yml exists
|
|
12
|
+
* Step 2: Invoke skyramp_local_dev prompt (which runs the full workflow)
|
|
13
|
+
*/
|
|
14
|
+
// ── Skill content (single source of truth) ──────────────────────────────────
|
|
15
|
+
// These get written to user repos by Step 0. Edit here, not in separate files.
|
|
16
|
+
export const LOCAL_DEV_SKILL_CONTENT = `---
|
|
17
|
+
name: local-dev
|
|
18
|
+
description: Run the Skyramp MCP local-dev workflow to test local code changes against a base branch. Use when the user asks to test changes, mock downstream services, validate a feature branch, run local-dev, or verify a PR before merge.
|
|
19
|
+
user_invocable: true
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# local-dev
|
|
23
|
+
|
|
24
|
+
Use the Skyramp MCP local-dev workflow as the source of truth. Do not recreate the workflow steps from this skill.
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
\`/local-dev\` — diff against main (default)
|
|
29
|
+
\`/local-dev main --mock stripe,billing --real postgres,redis\`
|
|
30
|
+
|
|
31
|
+
## Invocation
|
|
32
|
+
|
|
33
|
+
Call the \`skyramp_local_dev\` MCP prompt with the user's intent preserved:
|
|
34
|
+
- \`baseCommit\`: branch/SHA to diff against (default: main)
|
|
35
|
+
- \`repositoryPath\`: absolute path to repo
|
|
36
|
+
- \`servicesToMock\`: comma-separated services the user explicitly wants mocked
|
|
37
|
+
- \`realServices\`: comma-separated services that should receive real traffic
|
|
38
|
+
- \`mockProtocols\`: comma-separated protocols the user explicitly wants mocked (for example, \`rest\`)
|
|
39
|
+
|
|
40
|
+
By default, mock only true third-party downstream services. Keep the service under test, infrastructure, and local first-party services real unless the user explicitly asks to mock them.
|
|
41
|
+
`;
|
|
42
|
+
const localDevTestChangesSteps = [
|
|
43
|
+
{
|
|
44
|
+
stepIndex: 0,
|
|
45
|
+
title: "Install local-dev skill into the repository",
|
|
46
|
+
description: `The \`skyramp_one_click_tool\` installs the local-dev skill file for the calling agent automatically when this workflow is invoked. Verify the matching file exists before continuing.
|
|
47
|
+
|
|
48
|
+
File to check/create only if the tool did not already install it:
|
|
49
|
+
- Cursor: \`.cursor/skills/local-dev/SKILL.md\`
|
|
50
|
+
- Claude Code: \`.claude/skills/local-dev/SKILL.md\`
|
|
51
|
+
Agents without repo-local skill support skip skill creation. Also ensure the MCP config has the required env vars set (SKYRAMP_FEATURE_LOCAL_DEV=1).`,
|
|
52
|
+
conditionalGuidance: `Create the skill file for the calling agent ONLY if it doesn't already exist — never overwrite.
|
|
53
|
+
|
|
54
|
+
**Skill path for the calling agent only:**
|
|
55
|
+
- Cursor: \`.cursor/skills/local-dev/SKILL.md\`
|
|
56
|
+
- Claude Code: \`.claude/skills/local-dev/SKILL.md\`
|
|
57
|
+
Agents without repo-local skill support should skip skill creation. Write this exact content to the matching Cursor or Claude Code file:
|
|
58
|
+
${LOCAL_DEV_SKILL_CONTENT}
|
|
59
|
+
|
|
60
|
+
**MCP config env vars** — also ensure the following env vars are set in the Skyramp MCP server config:
|
|
61
|
+
- For Cursor: \`~/.cursor/mcp.json\` → add to the skyramp server's \`env\` block:
|
|
62
|
+
\`"SKYRAMP_FEATURE_LOCAL_DEV": "1"\`
|
|
63
|
+
- For Claude Code: \`~/.claude/settings.json\` → add to the skyramp server's \`env\` block:
|
|
64
|
+
\`"SKYRAMP_FEATURE_LOCAL_DEV": "1"\`
|
|
65
|
+
- For VS Code: add to the Skyramp MCP server's VS Code MCP config env block:
|
|
66
|
+
\`"SKYRAMP_FEATURE_LOCAL_DEV": "1"\`
|
|
67
|
+
|
|
68
|
+
After updating the config, the user must restart the IDE or reload MCP servers for the change to take effect.
|
|
69
|
+
|
|
70
|
+
After verifying or creating files, inform the user what was installed.`,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
stepIndex: 1,
|
|
74
|
+
title: "Ensure Skyramp workspace is initialized",
|
|
75
|
+
description: "Check whether .skyramp/workspace.yml exists at repositoryPath. If it exists, read it to confirm it has services and dependencies configured. If it does not exist and .git exists, call skyramp_init_scan with workspacePath to discover services, then call skyramp_init_workspace with the scan results to create the workspace file.",
|
|
76
|
+
toolCall: {
|
|
77
|
+
toolName: "skyramp_init_scan",
|
|
78
|
+
description: "Scan repository for services if workspace not initialized",
|
|
79
|
+
inputs: {
|
|
80
|
+
workspacePath: { source: "user", paramKey: "repositoryPath" },
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
conditionalGuidance: `Only call skyramp_init_scan + skyramp_init_workspace if .skyramp/workspace.yml does NOT exist. If it already exists, skip this step entirely. The workspace.yml is required by the skyramp_local_dev prompt — it reads service URLs, dependencies, runtime config, and network settings from it.
|
|
84
|
+
|
|
85
|
+
Turn efficiency — after skyramp_init_scan returns its instructions, follow them to build the services array and call skyramp_init_workspace. Do NOT manually explore the codebase, run git diff, or spawn sub-agents to read source files before calling skyramp_init_workspace — the analyze_changes tool in the next step handles diff analysis automatically.`,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
stepIndex: 2,
|
|
89
|
+
title: "Invoke the skyramp_local_dev prompt",
|
|
90
|
+
description: "Call the `skyramp_local_dev` MCP prompt to run the full local-dev testing workflow.\n\nPass these parameters:\n- `baseCommit`: the one-click `baseBranch` value (default `main`)\n- `repositoryPath`: absolute path to the repo\n- `servicesToMock`: comma-separated list only when the user explicitly named services to mock\n- `realServices`: comma-separated list only when the user explicitly named services that should receive real traffic\n- `mockProtocols`: comma-separated list only when the user explicitly constrained mocked protocols (for example, `rest`)\n- `sandboxWorkerUrl`: the one-click `proxyUrl` value, only when provided — a Skyramp worker proxy URL (host:port or ingress route) to query for real recorded traffic\n- `proxyKubeconfig` / `proxyNamespace`: only when provided — reach the worker proxy in-cluster via kubectl port-forward instead of a URL\n\nWhen any proxy access is provided, the workflow calls `skyramp_query_proxy_mocks` during dependency discovery to derive mock request/response shapes from real recorded traffic instead of inferring them.\n\nThe one-click tool exposes `baseBranch` because that matches other workflow inputs; the `skyramp_local_dev` prompt argument is named `baseCommit`. Always map `baseBranch` → `baseCommit` when invoking the prompt.\n\nThe workflow generates the highest-value tests regardless of type. For integration scenarios with selected downstream mocks: skyramp_mock_generation → skyramp_integration_test_generation → skyramp_enrich_test_with_mocks. For provider contract scenarios: skyramp_contract_test_generation only; no mocks needed; do not enrich contract tests. Integration enrich is MANDATORY when the selected scenario has downstream mocks — it embeds MOCK_SERVICES into the test file.\n\nFollow the returned prompt instructions EXACTLY — do not skip steps or freelance.",
|
|
91
|
+
conditionalGuidance: renderFallbackGuidance(),
|
|
92
|
+
},
|
|
93
|
+
];
|
|
94
|
+
/**
|
|
95
|
+
* Render the fallback guidance from the canonical localDevPlan.
|
|
96
|
+
* This ensures the one-click command fallback stays in sync with the plan
|
|
97
|
+
* without maintaining a separate handwritten copy.
|
|
98
|
+
*/
|
|
99
|
+
function renderFallbackGuidance() {
|
|
100
|
+
const preamble = `The skyramp_local_dev prompt returns a detailed multi-step workflow. Follow it completely.
|
|
101
|
+
|
|
102
|
+
If the prompt is NOT available as a callable prompt in this IDE, fall back to calling the individual tools in sequence. Replace <REPOSITORY_PATH> with the actual repository path and <BASE_BRANCH> with the user's one-click \`baseBranch\` value (default "main"). When the plan says \`baseCommit\`, use that same baseBranch value.
|
|
103
|
+
|
|
104
|
+
Fallback service routing inputs from the one-click invocation:
|
|
105
|
+
<SERVICE_ROUTING>
|
|
106
|
+
<MOCK_SERVICES><servicesToMock from one-click params, if provided; use all when the user requested mock all></MOCK_SERVICES>
|
|
107
|
+
<REAL_SERVICES><realServices from one-click params, if provided></REAL_SERVICES>
|
|
108
|
+
<MOCK_PROTOCOLS><mockProtocols from one-click params, if provided></MOCK_PROTOCOLS>
|
|
109
|
+
</SERVICE_ROUTING>
|
|
110
|
+
|
|
111
|
+
Three rules apply in fallback mode at all times:
|
|
112
|
+
1. **No hand-written tests or mocks**: do NOT use Write, Edit, or any file-writing tool to create test or mock files manually. ALL test and mock files MUST be produced by Skyramp MCP generation tools (\`skyramp_batch_scenario_test_generation\`, \`skyramp_integration_test_generation\`, \`skyramp_generate_enriched_integration_test\`, \`skyramp_contract_test_generation\`, \`skyramp_mock_generation\`, \`skyramp_batch_mock_generation\`). If a generation tool fails, fix the inputs and retry — do not fall back to writing tests by hand.
|
|
113
|
+
2. **Mock scope**: if the user said "mock all downstream services", "mock all", "mock everything", or "mock all except X", treat all discovered downstream dependencies as selected for mocking (same as passing \`servicesToMock: "all"\`). Do not silently default to the third-party-only policy when the user expressed broad mock intent.
|
|
114
|
+
3. **No pytest fallback**: if \`skyramp_execute_test\` becomes unavailable at any point (tool not found, MCP disconnected, context compaction), stop immediately and ask the user to reconnect the Skyramp MCP server. Do not fall back to \`pytest\`, \`python3\`, or any direct runtime — doing so bypasses mock deployment and produces results that cannot be trusted as Skyramp-validated.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
`;
|
|
119
|
+
const ctx = {
|
|
120
|
+
repositoryPath: "<REPOSITORY_PATH>",
|
|
121
|
+
baseCommit: "<BASE_BRANCH from one-click baseBranch, default main>",
|
|
122
|
+
maxRecommendations: 8,
|
|
123
|
+
maxGenerate: 5,
|
|
124
|
+
schemaSourceGuidance: "Use any OpenAPI spec found in the repository as the authoritative schema source. If no spec is available, infer request/response shapes from the implementation code.",
|
|
125
|
+
serviceRoutingBlock: `<SERVICE_ROUTING>
|
|
126
|
+
<MOCK_SERVICES><servicesToMock from one-click params, if provided; use all when the user requested mock all></MOCK_SERVICES>
|
|
127
|
+
<REAL_SERVICES><realServices from one-click params, if provided></REAL_SERVICES>
|
|
128
|
+
<MOCK_PROTOCOLS><mockProtocols from one-click params, if provided></MOCK_PROTOCOLS>
|
|
129
|
+
</SERVICE_ROUTING>`,
|
|
130
|
+
serviceContext: `<SERVICE_CONTEXT>
|
|
131
|
+
Read <REPOSITORY_PATH>/.skyramp/workspace.yml before classifying dependencies. Use its services, dependencies, runtime, ports, and docker network values as the local service inventory.
|
|
132
|
+
</SERVICE_CONTEXT>`,
|
|
133
|
+
};
|
|
134
|
+
const planBody = localDevPlan.render(ctx);
|
|
135
|
+
const principles = `
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Key Principles
|
|
139
|
+
- ALL output paths absolute inside repo. NEVER /tmp.
|
|
140
|
+
- For **integration tests**: call \`skyramp_enrich_test_with_mocks\` after generating each test that uses selected downstream mocks. Each integration test with mocked dependencies MUST have MOCK_SERVICES embedded for third-party mocks or user-requested mocks.
|
|
141
|
+
- For **provider contract tests**: no mocks needed — test hits the real endpoint directly. Do NOT call \`skyramp_enrich_test_with_mocks\` for contract tests.
|
|
142
|
+
- Prioritize tests that catch real bugs and edge cases; test type is secondary to coverage value.
|
|
143
|
+
- Present results directly to the user (no skyramp_submit_report).
|
|
144
|
+
- **Prefer batch operations**: Use \`skyramp_batch_mock_generation\` over individual mock calls.
|
|
145
|
+
- **Prefer combined tools**: Use \`skyramp_generate_enriched_integration_test\` over separate generate+enrich.
|
|
146
|
+
- **Pre-flight first**: Call \`skyramp_preflight_mock_check\` before mock generation to catch protocol conflicts.
|
|
147
|
+
- **Compact assertions**: Use \`skyramp_enhance_assertions\` with \`autoApply: true\` for shorter instructions.`;
|
|
148
|
+
return preamble + planBody + principles;
|
|
149
|
+
}
|
|
150
|
+
export const LOCAL_DEV_TEST_CHANGES_COMMAND = {
|
|
151
|
+
id: "local_dev_test_changes",
|
|
152
|
+
name: "Local Dev — Test Changes",
|
|
153
|
+
description: "Bootstrap and run the local-dev testing workflow: install the active agent's IDE skill into the repo, initialize workspace, then invoke skyramp_local_dev to diff local changes, generate mocks and exhaustive tests, execute, and report. First run sets up the repo for future `/local-dev` usage.",
|
|
154
|
+
intent: {
|
|
155
|
+
contextIndicators: [
|
|
156
|
+
"Use when the user wants to test their LOCAL code changes (committed or uncommitted) against a base branch",
|
|
157
|
+
"Use when the user asks to set up, initialize, or bootstrap Skyramp local-dev testing in their repo",
|
|
158
|
+
"Use when the user mentions mocking downstream services for local testing",
|
|
159
|
+
"Use when the user asks to validate a feature branch, generate tests for their diff, or run a local-dev workflow",
|
|
160
|
+
"First invocation installs the active agent's skill so future runs can use /local-dev directly",
|
|
161
|
+
"Do NOT use for testing a deployed/remote service — this is for LOCAL changes only",
|
|
162
|
+
"Do NOT use for a single test type request like 'generate a smoke test' — use the specific generation tool",
|
|
163
|
+
],
|
|
164
|
+
purpose: "Bootstrap local-dev testing: install the active agent's IDE skill into repo, initialize workspace, then delegate to skyramp_local_dev prompt for the full test workflow (diff → mock → generate → execute → report).",
|
|
165
|
+
workflowSummary: "Install active agent skill → Init workspace → Invoke skyramp_local_dev prompt (which runs: analyze diff → recommend scenarios → generate mocks + tests → verify → deploy SUT + mocks → execute → report)",
|
|
166
|
+
examples: {
|
|
167
|
+
use: [
|
|
168
|
+
"test my local changes against main",
|
|
169
|
+
"setup skyramp local dev",
|
|
170
|
+
"initialize local dev testing",
|
|
171
|
+
"install skyramp skills",
|
|
172
|
+
"generate tests for my feature branch",
|
|
173
|
+
"run local-dev workflow",
|
|
174
|
+
"mock downstream services and test my diff",
|
|
175
|
+
"validate my changes before pushing",
|
|
176
|
+
"bootstrap skyramp testing in this repo",
|
|
177
|
+
],
|
|
178
|
+
doNotUse: [
|
|
179
|
+
"test the products endpoint comprehensively → use test_given_endpoint_comprehensively instead",
|
|
180
|
+
"generate a smoke test for /api/users → use skyramp_smoke_test_generation directly",
|
|
181
|
+
"scan the full repo and run tests → use full_repo_scan_recommend_generate_and_execute_top_n_tests",
|
|
182
|
+
"run my existing tests → use skyramp_execute_test directly",
|
|
183
|
+
],
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
steps: localDevTestChangesSteps,
|
|
187
|
+
inputParams: {
|
|
188
|
+
required: ["repositoryPath"],
|
|
189
|
+
optional: [
|
|
190
|
+
"baseBranch",
|
|
191
|
+
"servicesToMock",
|
|
192
|
+
"realServices",
|
|
193
|
+
"mockProtocols",
|
|
194
|
+
"endpointURL",
|
|
195
|
+
"token",
|
|
196
|
+
"proxyUrl",
|
|
197
|
+
"proxyKubeconfig",
|
|
198
|
+
"proxyNamespace",
|
|
199
|
+
],
|
|
200
|
+
},
|
|
201
|
+
};
|
package/build/index.js
CHANGED
|
@@ -25,24 +25,47 @@ import { registerCodeReuseTool } from "./tools/code-refactor/codeReuseTool.js";
|
|
|
25
25
|
import { registerEnhanceAssertionsTool } from "./tools/code-refactor/enhanceAssertionsTool.js";
|
|
26
26
|
import { registerBatchScenarioTestTool } from "./tools/generate-tests/generateBatchScenarioRestTool.js";
|
|
27
27
|
import { registerMockTool } from "./tools/generate-tests/generateMockRestTool.js";
|
|
28
|
+
import { registerBatchMockTool } from "./tools/generate-tests/batchMockGenerationTool.js";
|
|
28
29
|
import { registerAnalyzeChangesTool, registerAnalyzeTestHealthTool, registerActionsTool, registerRegisterTestPlanTool, } from "./tools/test-management/index.js";
|
|
29
30
|
import { registerTestbotPrompt } from "./prompts/testbot/testbot-prompts.js";
|
|
30
31
|
import { registerSutSetupResource } from "./resources/sutSetupResource.js";
|
|
31
32
|
import { registerTestbotResource } from "./resources/testbotResource.js";
|
|
33
|
+
import { registerLocalDevPrompt } from "./prompts/local-dev/local-dev-prompts.js";
|
|
32
34
|
import { registerSubmitReportTool } from "./tools/submitReportTool.js";
|
|
33
35
|
import { registerInitializeWorkspaceTool } from "./tools/workspace/initializeWorkspaceTool.js";
|
|
34
36
|
import { registerInitScanWorkspaceTool } from "./tools/workspace/initScanWorkspaceTool.js";
|
|
35
37
|
import { registerOneClickTool } from "./tools/one-click/oneClickTool.js";
|
|
38
|
+
import { registerEnrichTestWithMocksTool } from "./tools/enrichTestWithMocksTool.js";
|
|
39
|
+
import { registerPreflightMockCheckTool } from "./tools/preflightMockCheckTool.js";
|
|
40
|
+
import { registerGenerateEnrichedIntegrationTestTool } from "./tools/generateEnrichedIntegrationTestTool.js";
|
|
41
|
+
import { registerLocalDevWorkerComposeTool } from "./tools/localDevWorkerComposeTool.js";
|
|
42
|
+
import { registerQueryProxyMocksTool } from "./tools/queryProxyMocksTool.js";
|
|
36
43
|
import { registerAnalysisResources } from "./resources/analysisResources.js";
|
|
37
44
|
import { registerProgressResource } from "./resources/progressResource.js";
|
|
38
45
|
import { AnalyticsService } from "./services/AnalyticsService.js";
|
|
39
46
|
import { registerInitTriggerOnMCPInitialized } from "./utils/initAgent.js";
|
|
40
|
-
import { isTestbotEnabled } from "./utils/featureFlags.js";
|
|
47
|
+
import { isTestbotEnabled, isLocalDevEnabled } from "./utils/featureFlags.js";
|
|
41
48
|
import { registerPlaywrightTools, registerTraceRecordingPrompt, getPlaywrightTraceService, } from "./playwright/index.js";
|
|
49
|
+
// One-click routing instructions — injected into MCP server instructions so agents
|
|
50
|
+
// know to delegate to the one-click tool rather than self-orchestrating.
|
|
51
|
+
// Suppressed in testbot mode where the testbot prompt drives orchestration.
|
|
42
52
|
const oneClickEnabled = process.env.SKYRAMP_FEATURE_ONE_CLICK === "1";
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
53
|
+
const localDevEnabled = isLocalDevEnabled();
|
|
54
|
+
const localDevInstructions = `\n- When the user asks to test local changes, validate a feature branch, mock services and test, or run local-dev: MUST call \`skyramp_one_click_tool\` with workflow \`local_dev_test_changes\`, \`callingAgent\` set to the current MCP client (\`cursor\` or \`claude\` for skill installation; VS Code does not support repo-local Agent Skills), \`repositoryPath\`, and \`baseBranch\` (default "main"). Do NOT self-orchestrate — the one-click tool handles skill installation, workspace init, and prompt invocation.
|
|
55
|
+
- **Proxy / K8s worker**: When the user mentions a Skyramp proxy, K8s worker, kubeconfig, namespace, or provides proxy setup instructions (helm deploy worker, kubectl port-forward, proxy intercepts, seed traffic), do NOT execute those steps manually with bash commands. Instead, pass \`proxyKubeconfig\` and \`proxyNamespace\` (or \`proxyUrl\`) to \`skyramp_one_click_tool\`. The MCP tools handle proxy access internally — \`skyramp_query_proxy_mocks\` runs kubectl port-forward and queries captured traffic automatically. Manual kubectl, helm, or curl commands for proxy setup are unnecessary and waste agent turns.`;
|
|
56
|
+
const fullOneClickInstructions = `\n- When the user asks to comprehensively, thoroughly, or deeply test a specific endpoint: MUST call \`skyramp_one_click_tool\` with workflow \`test_given_endpoint_comprehensively\` first. Do NOT self-orchestrate the steps manually.\n- When the user asks to scan the full repo, recommend, generate, and execute top N tests: MUST call \`skyramp_one_click_tool\` with workflow \`full_repo_scan_recommend_generate_and_execute_top_n_tests\`.${localDevEnabled ? localDevInstructions : ""}`;
|
|
57
|
+
// Testbot suppresses one-click workflows (it has its own orchestration via testbot prompt),
|
|
58
|
+
// but local-dev routing is always active when the flag is set — they serve different use cases.
|
|
59
|
+
let oneClickInstructions = "";
|
|
60
|
+
if (isTestbotEnabled()) {
|
|
61
|
+
oneClickInstructions = localDevEnabled ? localDevInstructions : "";
|
|
62
|
+
}
|
|
63
|
+
else if (oneClickEnabled) {
|
|
64
|
+
oneClickInstructions = fullOneClickInstructions;
|
|
65
|
+
}
|
|
66
|
+
else if (localDevEnabled) {
|
|
67
|
+
oneClickInstructions = localDevInstructions;
|
|
68
|
+
}
|
|
46
69
|
const server = new McpServer({
|
|
47
70
|
name: "Skyramp MCP Server",
|
|
48
71
|
version: "1.0.0",
|
|
@@ -122,6 +145,10 @@ if (isTestbotEnabled()) {
|
|
|
122
145
|
registerSutSetupResource(server);
|
|
123
146
|
logger.info("Testbot SUT setup resource enabled via SKYRAMP_FEATURE_TESTBOT");
|
|
124
147
|
}
|
|
148
|
+
if (isLocalDevEnabled()) {
|
|
149
|
+
prompts.push(registerLocalDevPrompt);
|
|
150
|
+
logger.info("Local-dev prompt enabled via SKYRAMP_FEATURE_LOCAL_DEV");
|
|
151
|
+
}
|
|
125
152
|
prompts.forEach((registerPrompt) => registerPrompt(server));
|
|
126
153
|
logger.info("All prompts registered successfully");
|
|
127
154
|
// Register test generation tools
|
|
@@ -135,6 +162,7 @@ const testGenerationTools = [
|
|
|
135
162
|
registerUITestTool,
|
|
136
163
|
registerBatchScenarioTestTool,
|
|
137
164
|
registerMockTool,
|
|
165
|
+
registerBatchMockTool,
|
|
138
166
|
];
|
|
139
167
|
testGenerationTools.forEach((registerTool) => registerTool(server));
|
|
140
168
|
// Register modularization and code quality tools
|
|
@@ -157,9 +185,14 @@ registerRegisterTestPlanTool(server);
|
|
|
157
185
|
registerInitScanWorkspaceTool(server);
|
|
158
186
|
registerInitializeWorkspaceTool(server);
|
|
159
187
|
// Register one-click orchestrated workflows
|
|
160
|
-
if (oneClickEnabled) {
|
|
188
|
+
if (oneClickEnabled || localDevEnabled) {
|
|
161
189
|
registerOneClickTool(server);
|
|
162
|
-
logger.info("One-click tools enabled
|
|
190
|
+
logger.info("One-click tools enabled", {
|
|
191
|
+
enabledBy: {
|
|
192
|
+
SKYRAMP_FEATURE_ONE_CLICK: oneClickEnabled,
|
|
193
|
+
SKYRAMP_FEATURE_LOCAL_DEV: localDevEnabled,
|
|
194
|
+
},
|
|
195
|
+
});
|
|
163
196
|
}
|
|
164
197
|
// Register other Skyramp tools
|
|
165
198
|
const infrastructureTools = [
|
|
@@ -169,6 +202,10 @@ const infrastructureTools = [
|
|
|
169
202
|
registerTraceTool,
|
|
170
203
|
registerTraceStopTool,
|
|
171
204
|
];
|
|
205
|
+
if (isLocalDevEnabled()) {
|
|
206
|
+
infrastructureTools.push(registerEnrichTestWithMocksTool, registerPreflightMockCheckTool, registerGenerateEnrichedIntegrationTestTool, registerLocalDevWorkerComposeTool, registerQueryProxyMocksTool);
|
|
207
|
+
logger.info("Local-dev tools enabled via SKYRAMP_FEATURE_LOCAL_DEV");
|
|
208
|
+
}
|
|
172
209
|
if (isTestbotEnabled()) {
|
|
173
210
|
infrastructureTools.push(registerSubmitReportTool);
|
|
174
211
|
infrastructureTools.push(registerRunExistingTestsTool);
|
|
@@ -198,6 +235,38 @@ process.on("uncaughtException", async (error) => {
|
|
|
198
235
|
}
|
|
199
236
|
process.exit(1);
|
|
200
237
|
});
|
|
238
|
+
// Handle unhandled promise rejections — without this handler Node.js 15+
|
|
239
|
+
// terminates the process on any unhandled rejection, which drops the MCP
|
|
240
|
+
// connection if e.g. a progress notification write fails on a broken transport.
|
|
241
|
+
process.on("unhandledRejection", async (reason) => {
|
|
242
|
+
const error = reason instanceof Error ? reason : new Error(String(reason));
|
|
243
|
+
// EPIPE means the client already disconnected — exit cleanly
|
|
244
|
+
if ("code" in error && error.code === "EPIPE") {
|
|
245
|
+
process.exit(0);
|
|
246
|
+
}
|
|
247
|
+
// gRPC/Docker connectivity errors — log and survive.
|
|
248
|
+
// These occur when Docker containers/networks are destroyed while the MCP
|
|
249
|
+
// server has pending gRPC calls to the Skyramp worker. The server should
|
|
250
|
+
// stay alive so non-Docker tools remain available.
|
|
251
|
+
const msg = error.message || "";
|
|
252
|
+
const isDockerDisconnect = /UNAVAILABLE|DEADLINE_EXCEEDED|ECONNREFUSED|ECONNRESET|connection reset|socket hang up|stream removed/i.test(msg);
|
|
253
|
+
if (isDockerDisconnect) {
|
|
254
|
+
logger.info("gRPC/Docker connection lost (container or network likely destroyed)", {
|
|
255
|
+
error: msg,
|
|
256
|
+
});
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
logger.error("Unhandled promise rejection", {
|
|
260
|
+
error: error.message,
|
|
261
|
+
stack: error.stack,
|
|
262
|
+
});
|
|
263
|
+
try {
|
|
264
|
+
await AnalyticsService.pushServerCrashEvent("unhandledRejection", error.message, error.stack);
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
// Best effort — don't let telemetry failure cascade
|
|
268
|
+
}
|
|
269
|
+
});
|
|
201
270
|
// Start MCP server
|
|
202
271
|
async function main() {
|
|
203
272
|
const transport = new StdioServerTransport();
|
|
@@ -233,6 +302,11 @@ async function main() {
|
|
|
233
302
|
logger.error("STDIN error, parent likely disconnected", { error: err });
|
|
234
303
|
handleParentDisconnect("stdin error");
|
|
235
304
|
});
|
|
305
|
+
// Handle stdout errors (EPIPE = client stopped reading, broken pipe)
|
|
306
|
+
process.stdout.on("error", (err) => {
|
|
307
|
+
logger.error("STDOUT error, client likely disconnected", { error: err });
|
|
308
|
+
handleParentDisconnect("stdout error");
|
|
309
|
+
});
|
|
236
310
|
// Handle process termination signals
|
|
237
311
|
process.on("SIGTERM", () => handleParentDisconnect("SIGTERM"));
|
|
238
312
|
process.on("SIGINT", () => handleParentDisconnect("SIGINT"));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { generateSkyrampHeader, SKYRAMP_UTILS_HEADER } from "../utils/utils.js";
|
|
2
|
+
import { isPomReuseEnabled } from "../utils/featureFlags.js";
|
|
2
3
|
import { getPomAwareCodeReusePrompt } from "./pom-aware-code-reuse.js";
|
|
3
4
|
const LANGUAGE_MAP = {
|
|
4
5
|
python: {
|
|
@@ -19,6 +20,8 @@ const LANGUAGE_MAP = {
|
|
|
19
20
|
},
|
|
20
21
|
};
|
|
21
22
|
export function isPomAwareTarget(language, framework) {
|
|
23
|
+
if (!isPomReuseEnabled())
|
|
24
|
+
return false;
|
|
22
25
|
const lang = language.toLowerCase();
|
|
23
26
|
return (lang === "typescript" || lang === "javascript") && framework?.toLowerCase() === "playwright";
|
|
24
27
|
}
|
|
@@ -12,4 +12,5 @@ export interface AssertionEnrichmentRule {
|
|
|
12
12
|
examples: AssertionEnrichmentExample[];
|
|
13
13
|
}
|
|
14
14
|
export declare function renderRule(index: number, rule: AssertionEnrichmentRule): string;
|
|
15
|
+
export declare function renderSharedAssertionRules(): string;
|
|
15
16
|
export declare function getAssertionsPrompt(specificRules: AssertionEnrichmentRule[], scope: string, testFile: string, enhanceType: EnhanceType): string;
|
|
@@ -122,6 +122,20 @@ expect(getResponseValue(productsPostResponse, "created_at")).toMatch(/^\\d{4}-\\
|
|
|
122
122
|
},
|
|
123
123
|
],
|
|
124
124
|
},
|
|
125
|
+
{
|
|
126
|
+
title: "Use exact recorded JSON paths",
|
|
127
|
+
description: "Do not add object-wrapper prefixes or nested paths that are not present in the actual response body. Use the exact JSON path from the recorded response body.",
|
|
128
|
+
subPoints: [
|
|
129
|
+
`If the body is flat (\`{"id": "acc_...", "tax_exempt": true}\`), use \`"tax_exempt"\`, not \`"account.tax_exempt"\`.`,
|
|
130
|
+
"Only use dot notation when the recorded response genuinely nests the field under that key.",
|
|
131
|
+
],
|
|
132
|
+
examples: [
|
|
133
|
+
{
|
|
134
|
+
language: "javascript",
|
|
135
|
+
code: `expect(getResponseValue(accountResponse, "tax_exempt")).toBe(true);`,
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
},
|
|
125
139
|
{
|
|
126
140
|
title: "Computed response fields, derived using dynamic formulas",
|
|
127
141
|
description: "When the response contains a field whose value is derived from a calculation, assert the result using a formula built from prior response values and request inputs, not a hardcoded literal.",
|
|
@@ -158,6 +172,9 @@ ${ex.code}
|
|
|
158
172
|
function renderRules(rules) {
|
|
159
173
|
return rules.map((rule, i) => renderRule(i + 1, rule)).join("\n\n");
|
|
160
174
|
}
|
|
175
|
+
export function renderSharedAssertionRules() {
|
|
176
|
+
return renderRules(SHARED_RULES);
|
|
177
|
+
}
|
|
161
178
|
export function getAssertionsPrompt(specificRules, scope, testFile, enhanceType) {
|
|
162
179
|
const allRules = [...SHARED_RULES, ...specificRules];
|
|
163
180
|
const ruleChecklistKeys = allRules
|
|
@@ -13,7 +13,7 @@ After scanning the workspace, before calling the skyramp_init_workspace tool, yo
|
|
|
13
13
|
"framework": "<framework>",
|
|
14
14
|
"testDirectory": "<path>",
|
|
15
15
|
"api": { "schemaPath": "<path-or-url>", "baseUrl": "<url>", "authType": "<type>", "authHeader": "<header>" },
|
|
16
|
-
"runtimeDetails": { "runtime": "<runtime>", "serverStartCommand": "<command>", "dockerNetwork": "<network>" }
|
|
16
|
+
"runtimeDetails": { "runtime": "<runtime>", "serverStartCommand": "<command>", "serverStopCommand": "<docker stop command>", "dockerNetwork": "<network>" }
|
|
17
17
|
}
|
|
18
18
|
]
|
|
19
19
|
\`\`\`
|
|
@@ -68,7 +68,7 @@ API schemas (look inside the service directory and check known framework default
|
|
|
68
68
|
<runtime_config>
|
|
69
69
|
Inspect the repo root (and subdirectories like .devcontainer/) for shared runtime configuration:
|
|
70
70
|
1. CLAUDE.md or AGENTS.md: if either file exists at the repo root, check it for dev/test/CI setup instructions including how to start services, required environment variables, and runtime configuration.
|
|
71
|
-
2. Docker Compose files: scan for ALL compose files including docker-compose.yml, docker-compose.yaml, docker-compose.*.yml (such as docker-compose.testbot.yml or docker-compose.dev.yml), compose.yml, and compose.*.yaml in the repo root and subdirectories. Distinguish between application compose files and infrastructure-only compose files. Infrastructure compose files contain only supporting services like databases, Redis, Minio, mail servers, or message queues and do NOT run the application itself. Application compose files contain the actual application services that build from the repo source code (look for "build:" directives pointing to the repo, or services that map to discovered application directories). Only use application compose files for determining runtime and
|
|
71
|
+
2. Docker Compose files: scan for ALL compose files including docker-compose.yml, docker-compose.yaml, docker-compose.*.yml (such as docker-compose.testbot.yml or docker-compose.dev.yml), compose.yml, and compose.*.yaml in the repo root and subdirectories. Distinguish between application compose files and infrastructure-only compose files. Infrastructure compose files contain only supporting services like databases, Redis, Minio, mail servers, or message queues and do NOT run the application itself. Application compose files contain the actual application services that build from the repo source code (look for "build:" directives pointing to the repo, or services that map to discovered application directories). Only use application compose files for determining runtime, serverStartCommand, and serverStopCommand. When a non-default compose file is found, the serverStartCommand and serverStopCommand must reference it explicitly (such as "docker compose -f docker-compose.testbot.yml up -d --build <service-name>" and "docker compose -f docker-compose.testbot.yml stop <service-name>"). Docker Compose ALWAYS prefixes the network name with the project name. If compose has "networks: { my-net: ... }", the actual network name is "<project-name>_my-net". If there is no explicit networks section, the default network is "<project-name>_default". The project name is the basename of the working directory where docker compose runs.
|
|
72
72
|
3. Makefile: extract start and dev targets.
|
|
73
73
|
4. Root package.json scripts: extract workspace-level commands.
|
|
74
74
|
</runtime_config>
|
|
@@ -135,18 +135,20 @@ Create one service entry per deployable unit. You MUST include every backend/API
|
|
|
135
135
|
<runtime_fields>
|
|
136
136
|
1. runtimeDetails.runtime (required): One of local, docker, or k8s. Detect per service:
|
|
137
137
|
- If the service is listed in an application docker compose file (one that builds or runs the application, not infrastructure-only files containing only databases, caches, or queues) or has a Dockerfile as its intended run method, use "docker".
|
|
138
|
-
- If k8s manifests exist (charts/, k8s/, deploy/), use "k8s".
|
|
138
|
+
- If k8s manifests exist (charts/, k8s/, deploy/) AND the service is intended to run in K8s for local development, use "k8s".
|
|
139
139
|
- If the service has no Docker or k8s configuration and is run directly via a language runtime (npm, python, java, etc.), use "local".
|
|
140
140
|
A repo may have MIXED runtimes. A backend in docker-compose.yml uses "docker" while a frontend run with pnpm or npm locally uses "local". Include ALL services regardless of runtime.
|
|
141
141
|
If the frontend is bundled inside the API Docker container (no separate frontend service in the compose file), both frontend and backend services should use runtime "docker", share the same baseUrl (the container's exposed URL), and use the same serverStartCommand since they run in the same container.
|
|
142
|
+
IMPORTANT — proxy parameters are NOT runtime indicators: If proxyKubeconfig, proxyNamespace, or proxyUrl appear in the conversation context, they are for a Skyramp proxy worker that collects traffic samples for mock generation. They do NOT indicate the repo's runtime. Do not use proxy K8s params to set runtime, k8sNamespace, or k8sContext. Determine the runtime solely from the repo's own files (docker-compose.yml, Dockerfile, k8s manifests that are part of the repo's own local dev workflow). Note that many repos have K8s deployment manifests for staging/production but use Docker Compose for local development — check which setup the repo actually uses for local dev.
|
|
142
143
|
2. runtimeDetails.serverStartCommand: The command to start or deploy the service. It MUST match the runtime:
|
|
143
|
-
- For "docker" runtime: Use a Docker command such as "docker compose up -d <service-name>" for the default docker-compose.yml, or "docker compose -f <compose-file> up -d <service-name>" when using a non-default compose file. This is always derivable from the application docker compose file and service name.
|
|
144
|
+
- For "docker" runtime: Use a Docker command that rebuilds application services from the working tree before starting them, such as "docker compose up -d --build <service-name>" for the default docker-compose.yml, or "docker compose -f <compose-file> up -d --build <service-name>" when using a non-default compose file. This is always derivable from the application docker compose file and service name. If the compose service has no build context and only references an image, note that the command cannot rebuild local code.
|
|
144
145
|
- For "k8s" runtime: Use a deploy command such as "kubectl apply -f deploy/", "helm install myrelease .", or "skaffold run". This is always derivable from the manifests or charts present in the repo.
|
|
145
146
|
- For "local" runtime: Use an application command such as "uvicorn main:app", "npm run dev", or "java -jar app.jar". Derive from Makefile, package.json scripts, or README. If no start command is discoverable, omit this field entirely.
|
|
146
147
|
NEVER mix runtime types with incompatible commands (for example, using "uvicorn" with runtime "docker" will cause errors). For "local" runtime, NEVER fabricate a command. Only use commands found in Makefile, package.json scripts, or README.
|
|
147
|
-
3. runtimeDetails.
|
|
148
|
-
4. runtimeDetails.
|
|
149
|
-
5. runtimeDetails.
|
|
148
|
+
3. runtimeDetails.serverStopCommand: Optional command to stop the service after test execution. ONLY set when runtime is "docker" and serverStartCommand starts persistent Docker infrastructure. For docker compose starts, prefer matching stop/down commands from the same compose file. Omit this field for "local" and "k8s" runtimes, or when teardown is unsafe or not discoverable.
|
|
149
|
+
4. runtimeDetails.dockerNetwork: Docker network name. ONLY set when runtime is "docker". NEVER set for "local" or "k8s".
|
|
150
|
+
5. runtimeDetails.k8sNamespace: Kubernetes namespace. ONLY set when runtime is "k8s". NEVER set for "local" or "docker".
|
|
151
|
+
6. runtimeDetails.k8sContext: Kubernetes context. ONLY set when runtime is "k8s". NEVER set for "local" or "docker".
|
|
150
152
|
</runtime_fields>
|
|
151
153
|
|
|
152
154
|
### Verification
|
|
@@ -159,8 +161,8 @@ Before calling skyramp_init_workspace, confirm all of the following:
|
|
|
159
161
|
5. Every service with authType apiKey has authHeader explicitly set to the actual custom header name (such as "X-API-Key" or "X-Admin-Key"). If you cannot find the header name in the source code, env vars, or README, do NOT use authType apiKey. Use authType none instead and add a YAML comment explaining auth is unresolved.
|
|
160
162
|
6. framework matches language (python uses pytest or robot, typescript or javascript uses playwright, java uses junit).
|
|
161
163
|
7. testDirectory follows the stable resolution rules above: framework config file when present (Playwright testDir in playwright.config.ts, pytest testpaths in pytest.ini or pyproject.toml, JUnit test source dir in pom.xml or build.gradle); otherwise the deterministic default (tests/skyramp for a single service, tests/skyramp/<serviceDirName> for multiple services).
|
|
162
|
-
8. If serverStartCommand is provided, it matches the runtime.
|
|
163
|
-
9. For services in docker-compose.yml: runtime MUST be "docker" and the command MUST be a docker command such as "docker compose up -d <service-name>". Always include it since it is derivable from the service name.
|
|
164
|
+
8. If serverStartCommand is provided, it matches the runtime. If serverStopCommand is provided, runtime is "docker" and the command is a Docker command.
|
|
165
|
+
9. For services in docker-compose.yml: runtime MUST be "docker" and the command MUST be a docker command such as "docker compose up -d --build <service-name>" when the service has a build context. Always include it since it is derivable from the service name.
|
|
164
166
|
10. NEVER use application-level commands (uvicorn, npm, node, python, java, etc.) with runtime "docker".
|
|
165
167
|
11. For "local" runtime: if no start command is discoverable from Makefile, package.json scripts, or README, omit serverStartCommand rather than guessing.
|
|
166
168
|
12. dockerNetwork is set only when runtime is "docker".
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PromptPlan-based local-dev workflow — 6 phases.
|
|
3
|
+
*
|
|
4
|
+
* Phases: ANALYZE → RECOMMEND → GENERATE → VERIFY → DEPLOY → EXECUTE
|
|
5
|
+
*
|
|
6
|
+
* Key design decisions:
|
|
7
|
+
* - Mock files are generated in the same language as tests (from workspace config) with get_all_mocks()/getAllMocks()
|
|
8
|
+
* - Tests import get_all_mocks()/getAllMocks() from each mock file, collect into MOCK_SERVICES, deploy collectively
|
|
9
|
+
* - NO YAML mock files, NO CLI commands — ONLY MCP tools
|
|
10
|
+
* - Execution uses skyramp_execute_test MCP tool exclusively
|
|
11
|
+
* - Enriched tests apply mocks at runtime through their language-specific Skyramp client helper
|
|
12
|
+
*/
|
|
13
|
+
import { PromptPlan } from "../test-recommendation/promptPlan.js";
|
|
14
|
+
/** gRPC service name guidance — use bare name from proto, not package-qualified. */
|
|
15
|
+
export declare const GRPC_SERVICE_NAME_GUIDANCE = "the bare service name as declared in the proto `service` block (e.g., `CartService`, NOT `package.CartService`). Do NOT include the proto package prefix \u2014 the tool looks up the service by its unqualified name in the proto file. If proxy-derived specs (`skyramp_query_proxy_mocks`) return a fully-qualified name like `idl.PartnerAccounts`, strip the package prefix before passing it to mock generation";
|
|
16
|
+
/** Assertion API guidance — use SDK helper with JSON path for field access. */
|
|
17
|
+
export declare const ASSERTION_API_GUIDANCE = "Use the SDK helper for all field-level assertions: Python `skyramp.get_response_value(response, \"json.path\")`, TypeScript `getResponseValue(response, \"json.path\")`. The helper supports dot-path notation for nested access (e.g., `\"data.items[0].name\"`). Do NOT use dict/attribute access on the response variable (`response[\"field\"]`, `response.field`) or `json.loads(response.response_body)`";
|
|
18
|
+
export interface LocalDevPlanCtx {
|
|
19
|
+
repositoryPath: string;
|
|
20
|
+
baseCommit: string;
|
|
21
|
+
maxRecommendations: number;
|
|
22
|
+
maxGenerate: number;
|
|
23
|
+
stateOutputFile?: string;
|
|
24
|
+
sandboxWorkerUrl?: string;
|
|
25
|
+
schemaSourceGuidance: string;
|
|
26
|
+
serviceRoutingBlock: string;
|
|
27
|
+
serviceContext: string;
|
|
28
|
+
/**
|
|
29
|
+
* True when proxy access parameters were supplied (a URL, or kubeconfig+namespace)
|
|
30
|
+
* — NOT a reachability check. skyramp_query_proxy_mocks decides reachability at
|
|
31
|
+
* call time and falls back to code/OpenAPI inference if the proxy is unreachable.
|
|
32
|
+
*/
|
|
33
|
+
hasProxyAccess?: boolean;
|
|
34
|
+
}
|
|
35
|
+
export declare const localDevPlan: PromptPlan<LocalDevPlanCtx>;
|