@skyramp/mcp 0.2.6 → 0.2.8-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.
- package/build/commands/commandLibrary.d.ts +12 -0
- package/build/commands/recommendTestsAndExecuteCommand.d.ts +2 -0
- package/build/commands/testThisEndpointCommand.d.ts +2 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +6 -4
- package/build/playwright/PlaywrightTraceService.d.ts +32 -0
- package/build/playwright/index.d.ts +3 -0
- package/build/playwright/registerPlaywrightTools.d.ts +8 -0
- package/build/playwright/registerPlaywrightTools.js +12 -11
- package/build/playwright/traceRecordingPrompt.d.ts +13 -0
- package/build/playwright/traceRecordingPrompt.js +3 -11
- package/build/prompts/code-reuse.d.ts +1 -0
- package/build/prompts/enhance-assertions/contractProviderAssertionsPrompt.d.ts +2 -0
- package/build/prompts/enhance-assertions/integrationAssertionsPrompt.d.ts +2 -0
- package/build/prompts/enhance-assertions/sharedAssertionRules.d.ts +15 -0
- package/build/prompts/enhance-assertions/uiAssertionsPrompt.d.ts +2 -0
- package/build/prompts/enhance-assertions/uiAssertionsPrompt.js +24 -5
- package/build/prompts/fix-error-prompt.d.ts +1 -0
- package/build/prompts/initialize-workspace/initializeWorkspacePrompt.d.ts +1 -0
- package/build/prompts/modularization/integration-test-modularization.d.ts +1 -0
- package/build/prompts/modularization/ui-test-modularization.d.ts +1 -0
- package/build/prompts/personas.d.ts +21 -0
- package/build/prompts/pom-aware-code-reuse.d.ts +1 -0
- package/build/prompts/startTraceCollectionPrompts.d.ts +2 -0
- package/build/prompts/sut-setup/modes/adaptWorkflowPrompt.d.ts +2 -0
- package/build/prompts/sut-setup/modes/adaptWorkflowPrompt.js +114 -0
- package/build/prompts/sut-setup/modes/dockerComposePrompt.d.ts +2 -0
- package/build/prompts/sut-setup/modes/dockerComposePrompt.js +292 -0
- package/build/prompts/sut-setup/shared.d.ts +39 -0
- package/build/prompts/sut-setup/shared.js +132 -0
- package/build/prompts/test-maintenance/actionsInstructions.d.ts +35 -0
- package/build/prompts/test-maintenance/drift-analysis-prompt.d.ts +4 -0
- package/build/prompts/test-maintenance/driftAnalysisSections.d.ts +13 -0
- package/build/prompts/test-maintenance/driftAnalysisSections.js +9 -3
- package/build/prompts/test-recommendation/analysisOutputPrompt.d.ts +84 -0
- package/build/prompts/test-recommendation/analysisOutputPrompt.js +1 -1
- package/build/prompts/test-recommendation/analysisOutputPrompt.test.d.ts +1 -0
- package/build/prompts/test-recommendation/analysisOutputPrompt.test.js +1 -0
- package/build/prompts/test-recommendation/diffExecutionPlan.d.ts +17 -0
- package/build/prompts/test-recommendation/diffExecutionPlan.js +83 -18
- package/build/prompts/test-recommendation/fullRepoCatalog.d.ts +7 -0
- package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.d.ts +1 -0
- package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.js +1 -0
- package/build/prompts/test-recommendation/promptPlan.d.ts +203 -0
- package/build/prompts/test-recommendation/promptPlan.test.d.ts +1 -0
- package/build/prompts/test-recommendation/recommendationSections.d.ts +35 -0
- package/build/prompts/test-recommendation/recommendationShared.d.ts +31 -0
- package/build/prompts/test-recommendation/registerRecommendTestsPrompt.d.ts +7 -0
- package/build/prompts/test-recommendation/scopeAssessment.d.ts +55 -0
- package/build/prompts/test-recommendation/scopeAssessment.js +2 -2
- package/build/prompts/test-recommendation/scopeAssessment.test.d.ts +1 -0
- package/build/prompts/test-recommendation/scopeAssessment.test.js +1 -0
- package/build/prompts/test-recommendation/test-recommendation-prompt.d.ts +6 -0
- package/build/prompts/test-recommendation/test-recommendation-prompt.js +4 -4
- package/build/prompts/test-recommendation/test-recommendation-prompt.test.d.ts +1 -0
- package/build/prompts/test-recommendation/test-recommendation-prompt.test.js +97 -99
- package/build/prompts/testbot/testbot-prompts.d.ts +26 -0
- package/build/prompts/testbot/testbot-prompts.js +301 -46
- package/build/prompts/testbot/testbot-prompts.test.d.ts +1 -0
- package/build/prompts/testbot/testbot-prompts.test.js +109 -117
- package/build/resources/analysisResources.d.ts +17 -0
- package/build/resources/progressResource.d.ts +2 -0
- package/build/resources/sutSetupResource.d.ts +2 -0
- package/build/resources/sutSetupResource.js +45 -0
- package/build/resources/testbotResource.d.ts +2 -0
- package/build/resources/testbotResource.js +2 -2
- package/build/services/AnalyticsService.d.ts +13 -0
- package/build/services/AnalyticsService.test.d.ts +1 -0
- package/build/services/AnalyticsService.test.js +86 -0
- package/build/services/ModularizationService.d.ts +11 -0
- package/build/services/ScenarioGenerationService.d.ts +37 -0
- package/build/services/ScenarioGenerationService.integration.test.d.ts +1 -0
- package/build/services/ScenarioGenerationService.integration.test.js +4 -0
- package/build/services/ScenarioGenerationService.test.d.ts +1 -0
- package/build/services/TestDiscoveryService.d.ts +128 -0
- package/build/services/TestDiscoveryService.js +22 -12
- package/build/services/TestDiscoveryService.test.d.ts +1 -0
- package/build/services/TestDiscoveryService.test.js +4 -3
- package/build/services/TestExecutionService.d.ts +55 -0
- package/build/services/TestExecutionService.js +158 -26
- package/build/services/TestExecutionService.test.d.ts +1 -0
- package/build/services/TestExecutionService.test.js +339 -25
- package/build/services/TestGenerationService.d.ts +56 -0
- package/build/services/TestGenerationService.test.d.ts +1 -0
- package/build/services/TestGenerationService.test.js +10 -8
- package/build/services/containerEnv.d.ts +14 -0
- package/build/tool-phase-coverage.test.d.ts +1 -0
- package/build/tool-phase-coverage.test.js +2 -0
- package/build/tool-phases.d.ts +38 -0
- package/build/tools/auth/loginTool.d.ts +2 -0
- package/build/tools/auth/logoutTool.d.ts +2 -0
- package/build/tools/code-refactor/codeReuseTool.d.ts +2 -0
- package/build/tools/code-refactor/enhanceAssertionsTool.d.ts +2 -0
- package/build/tools/code-refactor/modularizationTool.d.ts +2 -0
- package/build/tools/executeSkyrampTestTool.d.ts +2 -0
- package/build/tools/executeSkyrampTestTool.js +26 -7
- package/build/tools/fixErrorTool.d.ts +2 -0
- package/build/tools/generate-tests/generateBatchScenarioRestTool.d.ts +45 -0
- package/build/tools/generate-tests/generateBatchScenarioRestTool.js +1 -1
- package/build/tools/generate-tests/generateBatchScenarioRestTool.test.d.ts +1 -0
- package/build/tools/generate-tests/generateBatchScenarioRestTool.test.js +11 -9
- package/build/tools/generate-tests/generateContractRestTool.d.ts +31 -0
- package/build/tools/generate-tests/generateE2ERestTool.d.ts +13 -0
- package/build/tools/generate-tests/generateFuzzRestTool.d.ts +10 -0
- package/build/tools/generate-tests/generateIntegrationRestTool.d.ts +16 -0
- package/build/tools/generate-tests/generateLoadRestTool.d.ts +18 -0
- package/build/tools/generate-tests/generateLoadRestTool.test.d.ts +1 -0
- package/build/tools/generate-tests/generateMockRestTool.d.ts +64 -0
- package/build/tools/generate-tests/generateSmokeRestTool.d.ts +8 -0
- package/build/tools/generate-tests/generateUIRestTool.d.ts +14 -0
- package/build/tools/generate-tests/generateUIRestTool.js +1 -1
- package/build/tools/generate-tests/loadTestSchema.d.ts +39 -0
- package/build/tools/one-click/oneClickTool.d.ts +11 -0
- package/build/tools/submitReportTool.d.ts +394 -0
- package/build/tools/submitReportTool.js +250 -41
- package/build/tools/submitReportTool.test.d.ts +1 -0
- package/build/tools/submitReportTool.test.js +511 -55
- package/build/tools/test-management/actionsTool.d.ts +10 -0
- package/build/tools/test-management/actionsTool.js +21 -7
- package/build/tools/test-management/analyzeChangesTool.d.ts +27 -0
- package/build/tools/test-management/analyzeChangesTool.js +150 -48
- package/build/tools/test-management/analyzeChangesTool.test.d.ts +1 -0
- package/build/tools/test-management/analyzeChangesTool.test.js +95 -78
- package/build/tools/test-management/analyzeTestHealthTool.d.ts +2 -0
- package/build/tools/test-management/analyzeTestHealthTool.js +16 -9
- package/build/tools/test-management/index.d.ts +3 -0
- package/build/tools/test-management/index.js +0 -1
- package/build/tools/trace/resolveSaveStoragePath.d.ts +7 -0
- package/build/tools/trace/resolveSaveStoragePath.test.d.ts +1 -0
- package/build/tools/trace/resolveSessionPaths.d.ts +40 -0
- package/build/tools/trace/resolveSessionPaths.test.d.ts +1 -0
- package/build/tools/trace/sessionState.d.ts +2 -0
- package/build/tools/trace/sessionState.test.d.ts +1 -0
- package/build/tools/trace/startTraceCollectionTool.d.ts +2 -0
- package/build/tools/trace/stopTraceCollectionTool.d.ts +2 -0
- package/build/tools/workspace/initScanWorkspaceTool.d.ts +4 -0
- package/build/tools/workspace/initializeWorkspaceTool.d.ts +2 -0
- package/build/tools/workspace/initializeWorkspaceTool.js +39 -22
- package/build/tools/workspace/initializeWorkspaceTool.test.d.ts +1 -0
- package/build/tools/workspace/initializeWorkspaceTool.test.js +134 -0
- package/build/tools/workspace/serviceUpsert.d.ts +12 -0
- package/build/tools/workspace/serviceUpsert.js +23 -0
- package/build/tools/workspace/serviceUpsert.test.d.ts +1 -0
- package/build/tools/workspace/serviceUpsert.test.js +50 -0
- package/build/types/OneClickCommands.d.ts +68 -0
- package/build/types/RepositoryAnalysis.d.ts +3004 -0
- package/build/types/TestAnalysis.d.ts +97 -0
- package/build/types/TestExecution.d.ts +63 -0
- package/build/types/TestExecution.js +11 -1
- package/build/types/TestRecommendation.d.ts +12 -0
- package/build/types/TestTypes.d.ts +234 -0
- package/build/types/TestbotReport.d.ts +68 -0
- package/build/types/TestbotReport.js +1 -0
- package/build/types/index.d.ts +4 -0
- package/build/types/index.js +3 -0
- package/build/utils/AnalysisStateManager.d.ts +242 -0
- package/build/utils/AnalysisStateManager.js +144 -3
- package/build/utils/AnalysisStateManager.test.d.ts +1 -0
- package/build/utils/AnalysisStateManager.test.js +98 -0
- package/build/utils/analyze-openapi.d.ts +1 -0
- package/build/utils/branchDiff.d.ts +18 -0
- package/build/utils/dartRouteExtractor.d.ts +45 -0
- package/build/utils/dartRouteExtractor.test.d.ts +1 -0
- package/build/utils/docker.d.ts +19 -0
- package/build/utils/docker.test.d.ts +1 -0
- package/build/utils/docker.test.js +10 -9
- package/build/utils/featureFlags.d.ts +37 -0
- package/build/utils/featureFlags.test.d.ts +1 -0
- package/build/utils/gitStaging.d.ts +24 -0
- package/build/utils/gitStaging.test.d.ts +1 -0
- package/build/utils/gitStaging.test.js +13 -7
- package/build/utils/httpDefaults.d.ts +10 -0
- package/build/utils/httpDefaults.test.d.ts +1 -0
- package/build/utils/initAgent.d.ts +36 -0
- package/build/utils/language-helper.d.ts +6 -0
- package/build/utils/logger.d.ts +11 -0
- package/build/utils/normalizeParams.d.ts +14 -0
- package/build/utils/normalizeSkyrampImports.d.ts +13 -0
- package/build/utils/pr-comment-parser.d.ts +31 -0
- package/build/utils/pr-comment-parser.test.d.ts +1 -0
- package/build/utils/pr-comment-parser.test.js +6 -5
- package/build/utils/projectMetadata.d.ts +15 -0
- package/build/utils/projectMetadata.test.d.ts +1 -0
- package/build/utils/proxy-terminal.d.ts +2 -0
- package/build/utils/repoScanner.d.ts +27 -0
- package/build/utils/repoScanner.test.d.ts +1 -0
- package/build/utils/routeParsers.d.ts +53 -0
- package/build/utils/routeParsers.js +31 -38
- package/build/utils/routeParsers.test.d.ts +1 -0
- package/build/utils/scenarioDrafting.d.ts +71 -0
- package/build/utils/scenarioDrafting.js +23 -1
- package/build/utils/scenarioDrafting.test.d.ts +1 -0
- package/build/utils/skyrampMdContent.d.ts +5 -0
- package/build/utils/sourceRouteExtractor.d.ts +48 -0
- package/build/utils/sourceRouteExtractor.test.d.ts +1 -0
- package/build/utils/telemetry.d.ts +32 -0
- package/build/utils/telemetry.test.d.ts +1 -0
- package/build/utils/trace-parser.d.ts +32 -0
- package/build/utils/trace-parser.test.d.ts +6 -0
- package/build/utils/uiPageEnumerator.d.ts +146 -0
- package/build/utils/uiPageEnumerator.js +58 -14
- package/build/utils/uiPageEnumerator.test.d.ts +1 -0
- package/build/utils/uiPageEnumerator.test.js +223 -43
- package/build/utils/utils.d.ts +45 -0
- package/build/utils/utils.js +10 -0
- package/build/utils/utils.test.d.ts +1 -0
- package/build/utils/versions.d.ts +3 -0
- package/build/utils/versions.js +1 -1
- package/build/utils/workspaceAuth.d.ts +127 -0
- package/build/utils/workspaceAuth.test.d.ts +1 -0
- package/build/utils/workspaceAuth.test.js +25 -25
- package/build/workspace/index.d.ts +1 -0
- package/build/workspace/workspace.d.ts +390 -0
- package/build/workspace/workspace.js +7 -7
- package/build/workspace/workspace.test.d.ts +1 -0
- package/build/workspace/workspace.test.js +6 -6
- package/node_modules/playwright/lib/mcp/skyramp/loadTraceTool.js +31 -13
- package/node_modules/playwright/lib/mcp/skyramp/traceRecordingBackend.js +88 -15
- package/node_modules/playwright/lib/mcp/test/skyRampExport.js +4 -3
- package/node_modules/playwright/node_modules/playwright-core/ThirdPartyNotices.txt +23 -126
- package/node_modules/playwright/node_modules/playwright-core/lib/generated/injectedScriptSource.js +1 -1
- package/node_modules/playwright/node_modules/playwright-core/lib/server/recorder/recorderApp.js +79 -19
- package/node_modules/playwright/node_modules/playwright-core/lib/server/recorder/skyramp/aliasRemapper.js +84 -0
- package/node_modules/playwright/node_modules/playwright-core/lib/server/recorder/skyramp/replayEngine.js +15 -4
- package/node_modules/playwright/node_modules/playwright-core/lib/vite/recorder/assets/{codeMirrorModule-CPZKmjFR.js → codeMirrorModule-D0BjbCb7.js} +1 -1
- package/node_modules/playwright/node_modules/playwright-core/lib/vite/recorder/assets/index-lvTRGFx-.js +193 -0
- package/node_modules/playwright/node_modules/playwright-core/lib/vite/recorder/index.html +1 -1
- package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/assets/{codeMirrorModule-B0JOjboO.js → codeMirrorModule-Cqp3cwEJ.js} +1 -1
- package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/assets/{defaultSettingsView-1anWeyDf.js → defaultSettingsView-CYf9adZh.js} +79 -79
- package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/{index.Cc5029a3.js → index.B_7ywgmr.js} +1 -1
- package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/index.html +2 -2
- package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/uiMode.html +2 -2
- package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/{uiMode.Wo5yvvVh.js → uiMode.u4_8VnCV.js} +1 -1
- package/node_modules/playwright/node_modules/playwright-core/package.json +1 -1
- package/node_modules/playwright/node_modules/playwright-core/src/generated/injectedScriptSource.ts +1 -1
- package/node_modules/playwright/node_modules/playwright-core/src/server/recorder/recorderApp.ts +129 -43
- package/node_modules/playwright/node_modules/playwright-core/src/server/recorder/skyramp/aliasRemapper.ts +119 -0
- package/node_modules/playwright/node_modules/playwright-core/src/server/recorder/skyramp/replayEngine.ts +33 -10
- package/node_modules/playwright/package.json +1 -1
- package/package.json +16 -4
- package/build/tools/test-management/uiAnalyzeChangesTool.js +0 -155
- package/build/tools/test-management/uiAnalyzeChangesTool.test.js +0 -147
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/.bin/node-which +0 -52
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/.bin/is-docker +0 -5
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/.bin/mime +0 -46
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/.bin/yaml +0 -11
- package/node_modules/playwright/node_modules/playwright-core/lib/vite/recorder/assets/index-CsgPR2wy.js +0 -193
- package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/index.CP3Y8Zsb.js +0 -2
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
import * as fs from "fs";
|
|
2
|
-
import * as path from "path";
|
|
3
|
-
import { z } from "zod";
|
|
4
|
-
import { logger } from "../../utils/logger.js";
|
|
5
|
-
import { enumerateCandidateUiPages } from "../../utils/uiPageEnumerator.js";
|
|
6
|
-
import { hasFlutterSdkDep, isFrontendFile, isTestFile } from "../../prompts/test-recommendation/scopeAssessment.js";
|
|
7
|
-
import { parseChangedFilesFromDiff } from "../../utils/branchDiff.js";
|
|
8
|
-
import { toolText } from "../../utils/utils.js";
|
|
9
|
-
import { isTestbotEnabled } from "../../utils/featureFlags.js";
|
|
10
|
-
/**
|
|
11
|
-
* skyramp_ui_analyze_changes — runs before skyramp_analyze_changes when the
|
|
12
|
-
* caller (typically the testbot agent) wants blueprint-grounded recommendations.
|
|
13
|
-
*
|
|
14
|
-
* Computes candidateUiPages[] using the same source-grounded logic that
|
|
15
|
-
* analyze_changes uses internally (shared enumerator), then emits explicit
|
|
16
|
-
* instructions for the agent: navigate to each candidate URL, capture a
|
|
17
|
-
* browser_blueprint, then call skyramp_analyze_changes with the captures
|
|
18
|
-
* available as element vocabulary when the agent writes UI rec reasoning.
|
|
19
|
-
*
|
|
20
|
-
* Graceful degradation: backend-only PRs produce a "no UI work" instruction;
|
|
21
|
-
* unresolvable frontend baseUrl produces "skip captures, call analyze_changes
|
|
22
|
-
* with empty array." analyze_changes still works in either case — same
|
|
23
|
-
* source-grounded output as before slice 4.
|
|
24
|
-
*/
|
|
25
|
-
export async function runUiAnalyzeChanges(params) {
|
|
26
|
-
const repoPath = params.repositoryPath;
|
|
27
|
-
// Read changedFiles from the canonical PR diff file. The testbot runtime
|
|
28
|
-
// writes this before the prompt runs.
|
|
29
|
-
const diffPath = path.join(repoPath, ".skyramp_git_diff");
|
|
30
|
-
let changedFiles = [];
|
|
31
|
-
let diffFileMissing = false;
|
|
32
|
-
try {
|
|
33
|
-
const raw = fs.readFileSync(diffPath, "utf-8");
|
|
34
|
-
changedFiles = parseChangedFilesFromDiff(raw);
|
|
35
|
-
}
|
|
36
|
-
catch {
|
|
37
|
-
// No diff file — for testbot this would be a runtime bug (it always
|
|
38
|
-
// writes one); for non-testbot callers it means "diff unavailable",
|
|
39
|
-
// which is NOT the same as "no UI changes". Surface that distinction.
|
|
40
|
-
diffFileMissing = true;
|
|
41
|
-
}
|
|
42
|
-
if (diffFileMissing) {
|
|
43
|
-
const uiContext = {
|
|
44
|
-
changedFrontendFiles: [],
|
|
45
|
-
candidateUiPages: [],
|
|
46
|
-
};
|
|
47
|
-
return {
|
|
48
|
-
uiContext,
|
|
49
|
-
instructions: DIFF_FILE_MISSING_INSTRUCTIONS,
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
// Compute hasFlutterSdkDep once at the tool boundary; pass into isFrontendFile
|
|
53
|
-
// so .dart files are recognised as frontend in Flutter repos. See Confluence
|
|
54
|
-
// "Flutter support in Testbot" — this is one of two budget-driving call sites
|
|
55
|
-
// that must thread the flag (the other is analyzeChangesTool). Without it,
|
|
56
|
-
// a Flutter PR shows zero frontend files and never enters the UI pipeline.
|
|
57
|
-
const flutterSdk = hasFlutterSdkDep(repoPath);
|
|
58
|
-
const frontendFiles = changedFiles.filter((f) => isFrontendFile(f, { hasFlutterSdkDep: flutterSdk }) && !isTestFile(f));
|
|
59
|
-
if (frontendFiles.length === 0) {
|
|
60
|
-
const uiContext = {
|
|
61
|
-
changedFrontendFiles: [],
|
|
62
|
-
candidateUiPages: [],
|
|
63
|
-
};
|
|
64
|
-
return {
|
|
65
|
-
uiContext,
|
|
66
|
-
instructions: NO_UI_INSTRUCTIONS,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
const candidateUiPages = await enumerateCandidateUiPages(repoPath, frontendFiles);
|
|
70
|
-
const uiContext = {
|
|
71
|
-
changedFrontendFiles: frontendFiles,
|
|
72
|
-
candidateUiPages,
|
|
73
|
-
};
|
|
74
|
-
const instructions = candidateUiPages.length === 0
|
|
75
|
-
? NO_RESOLVABLE_URLS_INSTRUCTIONS
|
|
76
|
-
: buildCaptureInstructions(candidateUiPages, params.uiCredentials);
|
|
77
|
-
logger.info("ui_analyze_changes computed candidate UI pages", {
|
|
78
|
-
repositoryPath: repoPath,
|
|
79
|
-
frontendFileCount: frontendFiles.length,
|
|
80
|
-
candidateUiPageCount: candidateUiPages.length,
|
|
81
|
-
hasUiCredentials: !!params.uiCredentials,
|
|
82
|
-
});
|
|
83
|
-
return { uiContext, instructions };
|
|
84
|
-
}
|
|
85
|
-
const NO_UI_INSTRUCTIONS = `No UI changes detected in this PR. Proceed directly to \`skyramp_analyze_changes\`.`;
|
|
86
|
-
const NO_RESOLVABLE_URLS_INSTRUCTIONS = `Frontend changes detected but no candidate URLs could be resolved (workspace baseUrl missing or no router files matched). Proceed to \`skyramp_analyze_changes\`; UI recommendations will be source-grounded only.`;
|
|
87
|
-
const DIFF_FILE_MISSING_INSTRUCTIONS = `\`.skyramp_git_diff\` not found in the repository. This file is normally written by the testbot runtime before the prompt runs; without it, this tool cannot determine which files changed. **Do not skip blueprint capture on the assumption there are no UI changes** — that conclusion is not supported by the available data. If you have access to the changed-files list elsewhere (e.g. a \`gh pr diff\` command, an environment variable), determine UI candidates yourself and capture their blueprints before proceeding. Otherwise proceed to \`skyramp_analyze_changes\` and add an \`issuesFound\` info entry: "ui_analyze_changes could not read .skyramp_git_diff; recommendations are source-grounded only".`;
|
|
88
|
-
function buildCaptureInstructions(pages, uiCredentials) {
|
|
89
|
-
// The `<ui-credentials>` tag is only emitted by the testbot orchestration
|
|
90
|
-
// prompt. When this tool is called from an IDE (Cursor, etc.) outside
|
|
91
|
-
// testbot, the agent has no such tag — embed the credentials inline
|
|
92
|
-
// instead. uiCredentials is "email:password" formatted by the caller.
|
|
93
|
-
const loginStep = uiCredentials
|
|
94
|
-
? (isTestbotEnabled()
|
|
95
|
-
? `\n0. **Log in first.** \`browser_navigate\` to the app's login URL, then use \`<ui-credentials>\` from the testbot prompt to authenticate (you have those credentials in context). Without authentication, the candidate URLs below may redirect to login and the captured blueprints will be of the login page, not the feature.\n`
|
|
96
|
-
: `\n0. **Log in first.** \`browser_navigate\` to the app's login URL, then authenticate with the credentials \`${uiCredentials}\` (formatted as \`email:password\`). Without authentication, the candidate URLs below may redirect to login and the captured blueprints will be of the login page, not the feature.\n`)
|
|
97
|
-
: "";
|
|
98
|
-
const pagesYaml = pages
|
|
99
|
-
.map((p, i) => ` ${i + 1}. ${p.url} (sourcedFrom: ${p.sourcedFrom.join(", ") || "(none)"}, strategy: ${p.strategy})`)
|
|
100
|
-
.join("\n");
|
|
101
|
-
return `Frontend changes detected. **Before calling \`skyramp_analyze_changes\`, capture blueprints on the candidate UI pages below.** Those captures stay in your tool-result history and serve as element vocabulary when you write UI test recommendations — \`skyramp_analyze_changes\` returns the authoring rules; you bring the observed elements.
|
|
102
|
-
${loginStep}
|
|
103
|
-
**Candidate URLs:**
|
|
104
|
-
${pagesYaml}
|
|
105
|
-
|
|
106
|
-
**For each candidate URL:**
|
|
107
|
-
- \`browser_navigate\` to the URL
|
|
108
|
-
- \`browser_blueprint\` to capture the page
|
|
109
|
-
|
|
110
|
-
You don't need to thread the blueprints back into a tool call — they're in your context once captured. **Then call \`skyramp_analyze_changes\`** to get the recommendation catalog and the UI authoring rules.
|
|
111
|
-
|
|
112
|
-
If a candidate URL 404s or redirects unexpectedly, navigate from the workspace baseUrl and explore (admin apps mount routes under base prefixes the source extraction can't see). If the page rendered but lacks the changed feature (gated UI: modal, dropdown, accordion), do NOT iterate further during this step — UI recs will fall back to source-grounded prose for those, and the agent's later trace recording (Task 2) will navigate into the gate via capture-act-capture.
|
|
113
|
-
|
|
114
|
-
If \`browser_blueprint\` fails on every candidate URL (app unreachable, all 404s), proceed to \`skyramp_analyze_changes\` and log an \`issuesFound\` info entry. Recommendations will be source-grounded; non-UI work is unaffected.`;
|
|
115
|
-
}
|
|
116
|
-
export const uiAnalyzeChangesInputSchema = {
|
|
117
|
-
repositoryPath: z
|
|
118
|
-
.string()
|
|
119
|
-
.describe("Absolute path to the repository root"),
|
|
120
|
-
uiCredentials: z
|
|
121
|
-
.string()
|
|
122
|
-
.optional()
|
|
123
|
-
.describe("Optional ui-credentials for authed apps. When present, the returned " +
|
|
124
|
-
"instructions include a login step before blueprint capture."),
|
|
125
|
-
};
|
|
126
|
-
export function registerUiAnalyzeChangesTool(server) {
|
|
127
|
-
server.registerTool("skyramp_ui_analyze_changes", {
|
|
128
|
-
description: [
|
|
129
|
-
"Run BEFORE skyramp_analyze_changes when the PR may contain frontend changes.",
|
|
130
|
-
"Enumerates candidate UI pages from the diff and instructs the agent to",
|
|
131
|
-
"capture browser_blueprints on each before calling analyze_changes. The",
|
|
132
|
-
"captures stay in the agent's tool-result history and serve as the",
|
|
133
|
-
"element vocabulary for UI rec reasoning.",
|
|
134
|
-
"",
|
|
135
|
-
"On backend-only PRs, returns a 'no UI work' instruction — caller can",
|
|
136
|
-
"proceed directly to skyramp_analyze_changes.",
|
|
137
|
-
].join("\n"),
|
|
138
|
-
inputSchema: uiAnalyzeChangesInputSchema,
|
|
139
|
-
annotations: {
|
|
140
|
-
readOnlyHint: true, // reads .skyramp_git_diff + workspace.yml; no writes
|
|
141
|
-
idempotentHint: true, // pure function of repo state + uiCredentials
|
|
142
|
-
openWorldHint: false, // no external service calls
|
|
143
|
-
},
|
|
144
|
-
}, async (params) => {
|
|
145
|
-
const result = await runUiAnalyzeChanges(params);
|
|
146
|
-
const summary = JSON.stringify({ uiContext: result.uiContext }, null, 2);
|
|
147
|
-
return toolText(`<summary>
|
|
148
|
-
${summary}
|
|
149
|
-
</summary>
|
|
150
|
-
|
|
151
|
-
<instructions>
|
|
152
|
-
${result.instructions}
|
|
153
|
-
</instructions>`);
|
|
154
|
-
});
|
|
155
|
-
}
|
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
jest.mock("@skyramp/skyramp", () => ({
|
|
2
|
-
WorkspaceConfigManager: { create: jest.fn() },
|
|
3
|
-
}));
|
|
4
|
-
import { runUiAnalyzeChanges } from "./uiAnalyzeChangesTool.js";
|
|
5
|
-
import * as workspaceAuth from "../../utils/workspaceAuth.js";
|
|
6
|
-
import * as fs from "fs";
|
|
7
|
-
import * as os from "os";
|
|
8
|
-
import * as path from "path";
|
|
9
|
-
function makeRepoWithDiff(changedFiles) {
|
|
10
|
-
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "skyramp-uiac-test-"));
|
|
11
|
-
// Write .skyramp_git_diff with the requested file changes — match the
|
|
12
|
-
// format the runtime uses (raw `diff --git a/X b/X` block).
|
|
13
|
-
const diff = changedFiles
|
|
14
|
-
.map((f) => `diff --git a/${f} b/${f}\n+++ b/${f}\n@@ -0,0 +1,1 @@\n+x`)
|
|
15
|
-
.join("\n");
|
|
16
|
-
fs.writeFileSync(path.join(dir, ".skyramp_git_diff"), diff);
|
|
17
|
-
return dir;
|
|
18
|
-
}
|
|
19
|
-
describe("runUiAnalyzeChanges", () => {
|
|
20
|
-
let readSpy;
|
|
21
|
-
beforeEach(() => {
|
|
22
|
-
readSpy = jest.spyOn(workspaceAuth, "readWorkspaceConfigRaw");
|
|
23
|
-
});
|
|
24
|
-
afterEach(() => {
|
|
25
|
-
readSpy.mockRestore();
|
|
26
|
-
});
|
|
27
|
-
it("returns empty changedFrontendFiles for backend-only diffs", async () => {
|
|
28
|
-
readSpy.mockResolvedValue({ services: [] });
|
|
29
|
-
const repo = makeRepoWithDiff(["api/handlers/users.ts"]);
|
|
30
|
-
const result = await runUiAnalyzeChanges({ repositoryPath: repo });
|
|
31
|
-
expect(result.uiContext.changedFrontendFiles).toEqual([]);
|
|
32
|
-
expect(result.uiContext.candidateUiPages).toEqual([]);
|
|
33
|
-
expect(result.instructions).toMatch(/no UI changes/i);
|
|
34
|
-
fs.rmSync(repo, { recursive: true, force: true });
|
|
35
|
-
});
|
|
36
|
-
it("returns candidateUiPages and capture instructions for frontend diffs", async () => {
|
|
37
|
-
readSpy.mockResolvedValue({
|
|
38
|
-
services: [{ serviceName: "frontend", api: { baseUrl: "http://localhost:3000" } }],
|
|
39
|
-
});
|
|
40
|
-
const repo = makeRepoWithDiff(["frontend/src/components/Cart.tsx"]);
|
|
41
|
-
const result = await runUiAnalyzeChanges({ repositoryPath: repo });
|
|
42
|
-
expect(result.uiContext.changedFrontendFiles.length).toBeGreaterThan(0);
|
|
43
|
-
expect(result.uiContext.candidateUiPages.length).toBeGreaterThan(0);
|
|
44
|
-
expect(result.instructions).toMatch(/browser_navigate/);
|
|
45
|
-
expect(result.instructions).toMatch(/browser_blueprint/);
|
|
46
|
-
expect(result.instructions).toMatch(/skyramp_analyze_changes/);
|
|
47
|
-
// Captures stay in agent's tool-result history; we no longer thread them
|
|
48
|
-
// back through analyze_changes as a param.
|
|
49
|
-
expect(result.instructions).not.toMatch(/capturedBlueprints/);
|
|
50
|
-
fs.rmSync(repo, { recursive: true, force: true });
|
|
51
|
-
});
|
|
52
|
-
it("includes inline-credentials login step in non-testbot mode", async () => {
|
|
53
|
-
// SKYRAMP_FEATURE_TESTBOT is not set here, so the tool emits the
|
|
54
|
-
// credentials inline rather than referencing the testbot's
|
|
55
|
-
// <ui-credentials> context tag (which doesn't exist outside testbot).
|
|
56
|
-
delete process.env.SKYRAMP_FEATURE_TESTBOT;
|
|
57
|
-
readSpy.mockResolvedValue({
|
|
58
|
-
services: [{ serviceName: "frontend", api: { baseUrl: "http://localhost:3000" } }],
|
|
59
|
-
});
|
|
60
|
-
const repo = makeRepoWithDiff(["frontend/src/components/Cart.tsx"]);
|
|
61
|
-
const result = await runUiAnalyzeChanges({
|
|
62
|
-
repositoryPath: repo,
|
|
63
|
-
uiCredentials: "admin@example.com:admin",
|
|
64
|
-
});
|
|
65
|
-
expect(result.instructions).toMatch(/log in/i);
|
|
66
|
-
expect(result.instructions).toContain("admin@example.com:admin");
|
|
67
|
-
fs.rmSync(repo, { recursive: true, force: true });
|
|
68
|
-
});
|
|
69
|
-
it("references the <ui-credentials> testbot context tag in testbot mode", async () => {
|
|
70
|
-
process.env.SKYRAMP_FEATURE_TESTBOT = "1";
|
|
71
|
-
try {
|
|
72
|
-
readSpy.mockResolvedValue({
|
|
73
|
-
services: [{ serviceName: "frontend", api: { baseUrl: "http://localhost:3000" } }],
|
|
74
|
-
});
|
|
75
|
-
const repo = makeRepoWithDiff(["frontend/src/components/Cart.tsx"]);
|
|
76
|
-
const result = await runUiAnalyzeChanges({
|
|
77
|
-
repositoryPath: repo,
|
|
78
|
-
uiCredentials: "admin@example.com:admin",
|
|
79
|
-
});
|
|
80
|
-
expect(result.instructions).toMatch(/log in/i);
|
|
81
|
-
expect(result.instructions).toContain("ui-credentials");
|
|
82
|
-
// Inline credentials should NOT leak in testbot mode (the
|
|
83
|
-
// <ui-credentials> tag is the secure carrier in that flow).
|
|
84
|
-
expect(result.instructions).not.toContain("admin@example.com:admin");
|
|
85
|
-
fs.rmSync(repo, { recursive: true, force: true });
|
|
86
|
-
}
|
|
87
|
-
finally {
|
|
88
|
-
delete process.env.SKYRAMP_FEATURE_TESTBOT;
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
|
-
it("instructs the agent to proceed to analyze_changes (source-grounded) when frontend baseUrl unresolvable", async () => {
|
|
92
|
-
readSpy.mockResolvedValue(null); // no workspace yml
|
|
93
|
-
const repo = makeRepoWithDiff(["frontend/src/components/Cart.tsx"]);
|
|
94
|
-
const result = await runUiAnalyzeChanges({ repositoryPath: repo });
|
|
95
|
-
expect(result.uiContext.changedFrontendFiles.length).toBeGreaterThan(0);
|
|
96
|
-
expect(result.uiContext.candidateUiPages).toEqual([]);
|
|
97
|
-
expect(result.instructions).toMatch(/source-grounded/i);
|
|
98
|
-
fs.rmSync(repo, { recursive: true, force: true });
|
|
99
|
-
});
|
|
100
|
-
// Flutter support — the headline case the Confluence plan validates.
|
|
101
|
-
// Without the .dart classifier change, a Flutter PR returns
|
|
102
|
-
// changedFrontendFiles: [] → "No UI changes detected" → agent skips
|
|
103
|
-
// browser_navigate entirely. With the change + a Flutter pubspec, the
|
|
104
|
-
// diff registers as frontend and the agent gets told to navigate.
|
|
105
|
-
it("recognises .dart files as frontend in a Flutter project (with pubspec.yaml)", async () => {
|
|
106
|
-
readSpy.mockResolvedValue({
|
|
107
|
-
services: [
|
|
108
|
-
{
|
|
109
|
-
serviceName: "birdle-frontend",
|
|
110
|
-
language: "typescript",
|
|
111
|
-
framework: "playwright",
|
|
112
|
-
api: { baseUrl: "http://localhost:8080" },
|
|
113
|
-
},
|
|
114
|
-
],
|
|
115
|
-
});
|
|
116
|
-
const repo = makeRepoWithDiff(["lib/main.dart"]);
|
|
117
|
-
// Write a Flutter pubspec.yaml at the repo root so hasFlutterSdkDep returns true
|
|
118
|
-
fs.writeFileSync(path.join(repo, "pubspec.yaml"), `name: birdle\ndependencies:\n flutter:\n sdk: flutter\n`);
|
|
119
|
-
const result = await runUiAnalyzeChanges({ repositoryPath: repo });
|
|
120
|
-
expect(result.uiContext.changedFrontendFiles).toContain("lib/main.dart");
|
|
121
|
-
expect(result.uiContext.candidateUiPages.length).toBeGreaterThan(0);
|
|
122
|
-
expect(result.instructions).toMatch(/browser_navigate/);
|
|
123
|
-
fs.rmSync(repo, { recursive: true, force: true });
|
|
124
|
-
});
|
|
125
|
-
it("does NOT recognise .dart files as frontend without a Flutter pubspec.yaml", async () => {
|
|
126
|
-
// Pure Dart project (server/CLI) — pubspec.yaml absent or missing the SDK dep.
|
|
127
|
-
// .dart files should NOT enter the UI pipeline.
|
|
128
|
-
readSpy.mockResolvedValue({ services: [] });
|
|
129
|
-
const repo = makeRepoWithDiff(["bin/server.dart"]);
|
|
130
|
-
// No pubspec.yaml written at all
|
|
131
|
-
const result = await runUiAnalyzeChanges({ repositoryPath: repo });
|
|
132
|
-
expect(result.uiContext.changedFrontendFiles).toEqual([]);
|
|
133
|
-
expect(result.uiContext.candidateUiPages).toEqual([]);
|
|
134
|
-
expect(result.instructions).toMatch(/no UI changes/i);
|
|
135
|
-
fs.rmSync(repo, { recursive: true, force: true });
|
|
136
|
-
});
|
|
137
|
-
it("does NOT recognise .dart files as frontend in a pure Dart project (pubspec without flutter SDK dep)", async () => {
|
|
138
|
-
// pubspec.yaml exists but declares a Dart server (e.g. shelf) — no flutter SDK
|
|
139
|
-
readSpy.mockResolvedValue({ services: [] });
|
|
140
|
-
const repo = makeRepoWithDiff(["bin/server.dart"]);
|
|
141
|
-
fs.writeFileSync(path.join(repo, "pubspec.yaml"), `name: my_dart_server\ndependencies:\n shelf: ^1.4.0\n`);
|
|
142
|
-
const result = await runUiAnalyzeChanges({ repositoryPath: repo });
|
|
143
|
-
expect(result.uiContext.changedFrontendFiles).toEqual([]);
|
|
144
|
-
expect(result.uiContext.candidateUiPages).toEqual([]);
|
|
145
|
-
fs.rmSync(repo, { recursive: true, force: true });
|
|
146
|
-
});
|
|
147
|
-
});
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
var which = require("../")
|
|
3
|
-
if (process.argv.length < 3)
|
|
4
|
-
usage()
|
|
5
|
-
|
|
6
|
-
function usage () {
|
|
7
|
-
console.error('usage: which [-as] program ...')
|
|
8
|
-
process.exit(1)
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
var all = false
|
|
12
|
-
var silent = false
|
|
13
|
-
var dashdash = false
|
|
14
|
-
var args = process.argv.slice(2).filter(function (arg) {
|
|
15
|
-
if (dashdash || !/^-/.test(arg))
|
|
16
|
-
return true
|
|
17
|
-
|
|
18
|
-
if (arg === '--') {
|
|
19
|
-
dashdash = true
|
|
20
|
-
return false
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
var flags = arg.substr(1).split('')
|
|
24
|
-
for (var f = 0; f < flags.length; f++) {
|
|
25
|
-
var flag = flags[f]
|
|
26
|
-
switch (flag) {
|
|
27
|
-
case 's':
|
|
28
|
-
silent = true
|
|
29
|
-
break
|
|
30
|
-
case 'a':
|
|
31
|
-
all = true
|
|
32
|
-
break
|
|
33
|
-
default:
|
|
34
|
-
console.error('which: illegal option -- ' + flag)
|
|
35
|
-
usage()
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return false
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
process.exit(args.reduce(function (pv, current) {
|
|
42
|
-
try {
|
|
43
|
-
var f = which.sync(current, { all: all })
|
|
44
|
-
if (all)
|
|
45
|
-
f = f.join('\n')
|
|
46
|
-
if (!silent)
|
|
47
|
-
console.log(f)
|
|
48
|
-
return pv;
|
|
49
|
-
} catch (e) {
|
|
50
|
-
return 1;
|
|
51
|
-
}
|
|
52
|
-
}, 0))
|
package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/.bin/mime
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
'use strict';
|
|
4
|
-
|
|
5
|
-
process.title = 'mime';
|
|
6
|
-
let mime = require('.');
|
|
7
|
-
let pkg = require('./package.json');
|
|
8
|
-
let args = process.argv.splice(2);
|
|
9
|
-
|
|
10
|
-
if (args.includes('--version') || args.includes('-v') || args.includes('--v')) {
|
|
11
|
-
console.log(pkg.version);
|
|
12
|
-
process.exit(0);
|
|
13
|
-
} else if (args.includes('--name') || args.includes('-n') || args.includes('--n')) {
|
|
14
|
-
console.log(pkg.name);
|
|
15
|
-
process.exit(0);
|
|
16
|
-
} else if (args.includes('--help') || args.includes('-h') || args.includes('--h')) {
|
|
17
|
-
console.log(pkg.name + ' - ' + pkg.description + '\n');
|
|
18
|
-
console.log(`Usage:
|
|
19
|
-
|
|
20
|
-
mime [flags] [path_or_extension]
|
|
21
|
-
|
|
22
|
-
Flags:
|
|
23
|
-
--help, -h Show this message
|
|
24
|
-
--version, -v Display the version
|
|
25
|
-
--name, -n Print the name of the program
|
|
26
|
-
|
|
27
|
-
Note: the command will exit after it executes if a command is specified
|
|
28
|
-
The path_or_extension is the path to the file or the extension of the file.
|
|
29
|
-
|
|
30
|
-
Examples:
|
|
31
|
-
mime --help
|
|
32
|
-
mime --version
|
|
33
|
-
mime --name
|
|
34
|
-
mime -v
|
|
35
|
-
mime src/log.js
|
|
36
|
-
mime new.py
|
|
37
|
-
mime foo.sh
|
|
38
|
-
`);
|
|
39
|
-
process.exit(0);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
let file = args[0];
|
|
43
|
-
let type = mime.getType(file);
|
|
44
|
-
|
|
45
|
-
process.stdout.write(type + '\n');
|
|
46
|
-
|
package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/.bin/yaml
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { UserError, cli, help } from './dist/cli.mjs'
|
|
4
|
-
|
|
5
|
-
cli(process.stdin, error => {
|
|
6
|
-
if (error instanceof UserError) {
|
|
7
|
-
if (error.code === UserError.ARGS) console.error(`${help}\n`)
|
|
8
|
-
console.error(error.message)
|
|
9
|
-
process.exitCode = error.code
|
|
10
|
-
} else if (error) throw error
|
|
11
|
-
})
|