@skyramp/mcp 0.4.3 → 0.4.4-rc.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/index.js +239 -210
- package/build/playwright/PlaywrightTraceService.d.ts +1 -1
- package/build/playwright/blueprintDigestStore.d.ts +1 -1
- package/build/playwright/registerPlaywrightTools.d.ts +1 -1
- package/build/playwright/traceRecordingPrompt.d.ts +1 -1
- package/build/playwright/traceRecordingPrompt.js +4 -3
- package/build/prompts/local-dev/local-dev-prompts.d.ts +1 -1
- package/build/prompts/local-dev/local-dev-prompts.js +2 -2
- package/build/prompts/orderAssertionRule.d.ts +9 -0
- package/build/prompts/orderAssertionRule.js +9 -0
- package/build/prompts/startTraceCollectionPrompts.d.ts +1 -1
- package/build/prompts/startTraceCollectionPrompts.js +2 -3
- package/build/prompts/test-maintenance/driftAnalysisShared.js +2 -0
- package/build/prompts/test-recommendation/registerRecommendTestsPrompt.d.ts +1 -1
- package/build/prompts/test-recommendation/registerRecommendTestsPrompt.js +2 -2
- package/build/prompts/testbot/testbot-prompts.d.ts +1 -1
- package/build/prompts/testbot/testbot-prompts.js +9 -9
- package/build/recommendation/answers.d.ts +3 -3
- package/build/recommendation/answers.js +3 -2
- package/build/recommendation/verifierContracts.d.ts +4 -4
- package/build/recommendation/verifierContracts.js +6 -5
- package/build/recommendation/verifiers/coverage.js +25 -25
- package/build/recommendation/verifiers/deliveredMatchesPlan.js +3 -3
- package/build/resources/analysisResources.d.ts +1 -1
- package/build/resources/analysisResources.js +1 -1
- package/build/resources/progressResource.d.ts +1 -1
- package/build/resources/sutSetupResource.d.ts +1 -1
- package/build/resources/sutSetupResource.js +1 -1
- package/build/resources/testbotResource.d.ts +1 -1
- package/build/resources/testbotResource.js +1 -1
- package/build/services/AnalyticsService.d.ts +1 -1
- package/build/services/FleetExecutionService.d.ts +130 -0
- package/build/services/FleetExecutionService.js +391 -0
- package/build/services/ModularizationService.d.ts +1 -1
- package/build/services/TestExecutionService.d.ts +7 -0
- package/build/services/TestExecutionService.js +21 -0
- package/build/services/TestGenerationService.d.ts +1 -1
- package/build/tool-phases.js +2 -0
- package/build/tools/auth/loginTool.d.ts +1 -1
- package/build/tools/auth/loginTool.js +2 -2
- package/build/tools/auth/logoutTool.d.ts +1 -1
- package/build/tools/auth/logoutTool.js +2 -2
- package/build/tools/code-refactor/alignAssertionsTool.d.ts +1 -1
- package/build/tools/code-refactor/alignAssertionsTool.js +1 -1
- package/build/tools/code-refactor/assertionSkillTools.d.ts +1 -1
- package/build/tools/code-refactor/assertionSkillTools.js +2 -2
- package/build/tools/code-refactor/codeReuseTool.d.ts +1 -1
- package/build/tools/code-refactor/codeReuseTool.js +2 -2
- package/build/tools/code-refactor/enhanceAssertionsTool.d.ts +1 -1
- package/build/tools/code-refactor/enhanceAssertionsTool.js +1 -1
- package/build/tools/code-refactor/modularizationTool.d.ts +1 -1
- package/build/tools/code-refactor/modularizationTool.js +2 -2
- package/build/tools/enrichTestWithMocksTool.d.ts +1 -1
- package/build/tools/enrichTestWithMocksTool.js +2 -2
- package/build/tools/executeFleetTool.d.ts +28 -0
- package/build/tools/executeFleetTool.js +107 -0
- package/build/tools/executeSkyrampTestTool.d.ts +8 -5
- package/build/tools/executeSkyrampTestTool.js +13 -5
- package/build/tools/fixErrorTool.d.ts +1 -1
- package/build/tools/fixErrorTool.js +1 -1
- package/build/tools/generate-tests/batchMockGenerationTool.d.ts +6 -57
- package/build/tools/generate-tests/batchMockGenerationTool.js +3 -3
- package/build/tools/generate-tests/generateBatchScenarioRestTool.d.ts +9 -45
- package/build/tools/generate-tests/generateBatchScenarioRestTool.js +29 -11
- package/build/tools/generate-tests/generateContractRestTool.d.ts +1 -2
- package/build/tools/generate-tests/generateContractRestTool.js +1 -1
- package/build/tools/generate-tests/generateE2ERestTool.d.ts +2 -2
- package/build/tools/generate-tests/generateE2ERestTool.js +10 -2
- package/build/tools/generate-tests/generateFuzzRestTool.d.ts +1 -1
- package/build/tools/generate-tests/generateFuzzRestTool.js +1 -1
- package/build/tools/generate-tests/generateIntegrationRestTool.d.ts +1 -2
- package/build/tools/generate-tests/generateIntegrationRestTool.js +1 -1
- package/build/tools/generate-tests/generateLoadRestTool.d.ts +1 -2
- package/build/tools/generate-tests/generateLoadRestTool.js +2 -1
- package/build/tools/generate-tests/generateMockRestTool.d.ts +1 -2
- package/build/tools/generate-tests/generateMockRestTool.js +3 -3
- package/build/tools/generate-tests/generateSmokeRestTool.d.ts +1 -1
- package/build/tools/generate-tests/generateSmokeRestTool.js +1 -1
- package/build/tools/generate-tests/generateUILoadRestTool.d.ts +64 -0
- package/build/tools/generate-tests/generateUILoadRestTool.js +512 -0
- package/build/tools/generate-tests/generateUIRestTool.d.ts +8 -7
- package/build/tools/generate-tests/generateUIRestTool.js +10 -2
- package/build/tools/generate-tests/loadTestSchema.d.ts +15 -15
- package/build/tools/generate-tests/trace-reuse-guard.d.ts +1 -1
- package/build/tools/generateEnrichedIntegrationTestTool.d.ts +1 -2
- package/build/tools/generateEnrichedIntegrationTestTool.js +1 -1
- package/build/tools/localDevWorkerComposeTool.d.ts +1 -1
- package/build/tools/localDevWorkerComposeTool.js +2 -2
- package/build/tools/one-click/oneClickTool.d.ts +1 -1
- package/build/tools/one-click/oneClickTool.js +1 -1
- package/build/tools/preflightMockCheckTool.d.ts +1 -1
- package/build/tools/preflightMockCheckTool.js +3 -3
- package/build/tools/queryProxyMocksTool.d.ts +1 -1
- package/build/tools/queryProxyMocksTool.js +3 -3
- package/build/tools/submitReportTool.d.ts +111 -414
- package/build/tools/submitReportTool.js +88 -38
- package/build/tools/test-management/actionsTool.d.ts +1 -1
- package/build/tools/test-management/actionsTool.js +7 -7
- package/build/tools/test-management/analyzeChangesTool.d.ts +22 -118
- package/build/tools/test-management/analyzeChangesTool.js +4 -4
- package/build/tools/test-management/analyzeTestHealthTool.d.ts +1 -1
- package/build/tools/test-management/analyzeTestHealthTool.js +4 -4
- package/build/tools/test-management/registerTestPlanTool.d.ts +107 -733
- package/build/tools/test-management/registerTestPlanTool.js +12 -12
- package/build/tools/test-management/resolveScreenTool.d.ts +1 -1
- package/build/tools/test-management/resolveScreenTool.js +6 -2
- package/build/tools/trace/startTraceCollectionTool.d.ts +1 -1
- package/build/tools/trace/startTraceCollectionTool.js +4 -4
- package/build/tools/trace/stopTraceCollectionTool.d.ts +1 -1
- package/build/tools/trace/stopTraceCollectionTool.js +2 -2
- package/build/tools/verifyTestDependenciesTool.d.ts +1 -1
- package/build/tools/verifyTestDependenciesTool.js +1 -1
- package/build/tools/workspace/initScanWorkspaceTool.d.ts +1 -1
- package/build/tools/workspace/initScanWorkspaceTool.js +1 -1
- package/build/tools/workspace/initializeWorkspaceTool.d.ts +1 -1
- package/build/tools/workspace/initializeWorkspaceTool.js +1 -1
- package/build/types/RepositoryAnalysis.d.ts +164 -1170
- package/build/types/RepositoryAnalysis.js +12 -10
- package/build/types/StepMethod.d.ts +24 -1
- package/build/types/StepMethod.js +1 -1
- package/build/types/TestTypes.d.ts +41 -133
- package/build/types/TestTypes.js +25 -3
- package/build/types/TestbotReport.d.ts +4 -1
- package/build/utils/assertion-verify/metrics.js +12 -0
- package/build/utils/docker.d.ts +29 -7
- package/build/utils/docker.js +83 -27
- package/build/utils/findUp.d.ts +20 -0
- package/build/utils/findUp.js +59 -0
- package/build/utils/initAgent.d.ts +3 -3
- package/build/utils/initAgent.js +58 -26
- package/build/utils/language-helper.js +1 -1
- package/build/utils/progress.d.ts +3 -4
- package/build/utils/progress.js +4 -4
- package/build/utils/repoSdkVersion.d.ts +16 -0
- package/build/utils/repoSdkVersion.js +88 -0
- package/build/utils/testDependencyPolicy.d.ts +20 -0
- package/build/utils/testDependencyPolicy.js +64 -4
- package/build/utils/utils-verify/typecheck.js +3 -18
- package/build/utils/utils.d.ts +1 -1
- package/build/utils/versions.d.ts +3 -3
- package/build/utils/versions.js +1 -1
- package/build/workspace/workspace.d.ts +117 -538
- package/build/workspace/workspace.js +2 -2
- package/node_modules/playwright/lib/mcp/skyramp/assertOrder.js +66 -0
- package/node_modules/playwright/lib/mcp/skyramp/assertTool.js +12 -3
- package/node_modules/playwright/lib/mcp/skyramp/common/liveReadError.js +40 -0
- package/node_modules/playwright/lib/mcp/skyramp/loadTraceTool.js +21 -0
- package/node_modules/playwright/lib/mcp/skyramp/skyRampImport.js +2 -1
- package/node_modules/playwright/lib/mcp/skyramp/traceRecordingBackend.js +96 -16
- package/node_modules/playwright/lib/mcp/test/skyRampExport.js +10 -0
- package/node_modules/playwright/node_modules/playwright-core/lib/server/codegen/skyramp/jsonlReader.js +1 -0
- package/node_modules/playwright/node_modules/playwright-core/lib/server/recorder/recorderRunner.js +22 -0
- package/node_modules/playwright/node_modules/playwright-core/lib/utils/isomorphic/elementOrder.js +57 -0
- package/node_modules/playwright/node_modules/playwright-core/lib/utils.js +2 -0
- package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/{index.uiPTFncY.js → index.0MJW0uG7.js} +1 -1
- package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/index.html +1 -1
- package/node_modules/playwright/node_modules/playwright-core/package.json +1 -1
- package/node_modules/playwright/node_modules/playwright-core/src/server/codegen/skyramp/jsonlReader.ts +1 -1
- package/node_modules/playwright/node_modules/playwright-core/src/server/recorder/recorderRunner.ts +26 -1
- package/node_modules/playwright/node_modules/playwright-core/src/utils/isomorphic/elementOrder.ts +83 -0
- package/node_modules/playwright/node_modules/playwright-core/src/utils.ts +1 -0
- package/node_modules/playwright/package.json +1 -1
- package/package.json +9 -6
- package/plugin/prompts/plan-tests.md +9 -17
- package/plugin/skills/enhance-assertions/reference/shared-rules.md +1 -1
- package/plugin/skills/enhance-assertions/reference/ui.md +2 -2
- package/plugin/skills/fix-test-import-errors/SKILL.md +1 -1
- package/plugin/skills/repair-staged-files/SKILL.md +17 -0
|
@@ -20,7 +20,7 @@ export var ScenarioSource;
|
|
|
20
20
|
ScenarioSource["AgentEnriched"] = "agent-enriched";
|
|
21
21
|
})(ScenarioSource || (ScenarioSource = {}));
|
|
22
22
|
// ── Zod schemas ──
|
|
23
|
-
export const analysisScopeSchema = z.
|
|
23
|
+
export const analysisScopeSchema = z.enum(AnalysisScope);
|
|
24
24
|
export const paramInfoSchema = z.object({
|
|
25
25
|
name: z.string(),
|
|
26
26
|
type: z.string(),
|
|
@@ -40,15 +40,15 @@ export const endpointInteractionSchema = z.object({
|
|
|
40
40
|
type: z.enum(["success", "error", "edge-case"]),
|
|
41
41
|
request: z.object({
|
|
42
42
|
contentType: z.string().optional(),
|
|
43
|
-
body: z.record(z.any()).optional(),
|
|
44
|
-
headers: z.record(z.string()).optional(),
|
|
45
|
-
queryParams: z.record(z.any()).optional(),
|
|
43
|
+
body: z.record(z.string(), z.any()).optional(),
|
|
44
|
+
headers: z.record(z.string(), z.string()).optional(),
|
|
45
|
+
queryParams: z.record(z.string(), z.any()).optional(),
|
|
46
46
|
}),
|
|
47
47
|
response: z.object({
|
|
48
48
|
statusCode: z.number(),
|
|
49
49
|
description: z.string(),
|
|
50
|
-
body: z.record(z.any()).optional(),
|
|
51
|
-
headers: z.record(z.string()).optional(),
|
|
50
|
+
body: z.record(z.string(), z.any()).optional(),
|
|
51
|
+
headers: z.record(z.string(), z.string()).optional(),
|
|
52
52
|
cookies: z.array(cookieInfoSchema).optional(),
|
|
53
53
|
}),
|
|
54
54
|
});
|
|
@@ -83,9 +83,11 @@ export const scenarioStepSchema = z.object({
|
|
|
83
83
|
path: z.string(),
|
|
84
84
|
description: z.string(),
|
|
85
85
|
interactionType: z.enum(["success", "error", "edge-case"]),
|
|
86
|
-
requestBody: z.record(z.any()).optional(),
|
|
87
|
-
queryParams: z.record(z.any()).optional(),
|
|
88
|
-
responseBody: z
|
|
86
|
+
requestBody: z.record(z.string(), z.any()).optional(),
|
|
87
|
+
queryParams: z.record(z.string(), z.any()).optional(),
|
|
88
|
+
responseBody: z
|
|
89
|
+
.union([z.record(z.string(), z.any()), z.array(z.any())])
|
|
90
|
+
.optional(),
|
|
89
91
|
expectedStatusCode: z.number(),
|
|
90
92
|
expectedResponseFields: z.array(z.string()).optional(),
|
|
91
93
|
chainsFrom: z
|
|
@@ -192,7 +194,7 @@ export const repositoryAnalysisSchema = z.object({
|
|
|
192
194
|
contract: z.number(),
|
|
193
195
|
smoke: z.number(),
|
|
194
196
|
}),
|
|
195
|
-
testLocations: z.record(z.string()),
|
|
197
|
+
testLocations: z.record(z.string(), z.string()),
|
|
196
198
|
hasCoverageReports: z.boolean(),
|
|
197
199
|
estimatedCoverage: z.number().optional(),
|
|
198
200
|
relevantExternalTestPaths: z.array(z.string()).optional(),
|
|
@@ -37,4 +37,27 @@ export declare const STEP_METHOD_DESCRIPTION: string;
|
|
|
37
37
|
* The field itself: normalised first, then checked, so a rejection is about the
|
|
38
38
|
* verb and never about its capitalisation.
|
|
39
39
|
*/
|
|
40
|
-
export declare const stepMethodSchema: z.
|
|
40
|
+
export declare const stepMethodSchema: z.ZodPreprocess<z.ZodEnum<{
|
|
41
|
+
GET: "GET";
|
|
42
|
+
POST: "POST";
|
|
43
|
+
PUT: "PUT";
|
|
44
|
+
DELETE: "DELETE";
|
|
45
|
+
PATCH: "PATCH";
|
|
46
|
+
HEAD: "HEAD";
|
|
47
|
+
OPTIONS: "OPTIONS";
|
|
48
|
+
type: "type";
|
|
49
|
+
TRACE: "TRACE";
|
|
50
|
+
CONNECT: "CONNECT";
|
|
51
|
+
assert: "assert";
|
|
52
|
+
click: "click";
|
|
53
|
+
drag: "drag";
|
|
54
|
+
"drag-hold": "drag-hold";
|
|
55
|
+
hover: "hover";
|
|
56
|
+
inspect: "inspect";
|
|
57
|
+
navigate: "navigate";
|
|
58
|
+
press: "press";
|
|
59
|
+
release: "release";
|
|
60
|
+
tap: "tap";
|
|
61
|
+
wait: "wait";
|
|
62
|
+
OPERATION: "OPERATION";
|
|
63
|
+
}>, unknown>;
|
|
@@ -87,5 +87,5 @@ export const STEP_METHOD_DESCRIPTION = "What this step does to the system: an HT
|
|
|
87
87
|
export const stepMethodSchema = z.preprocess((value) => typeof value === "string"
|
|
88
88
|
? (normalizeStepMethod(value) ?? value.trim())
|
|
89
89
|
: value, z.enum(STEP_METHODS, {
|
|
90
|
-
|
|
90
|
+
error: () => `method ${STEP_METHOD_HELP}`,
|
|
91
91
|
}));
|
|
@@ -51,28 +51,22 @@ export declare enum RuntimeEnvironment {
|
|
|
51
51
|
DOCKER = "docker",
|
|
52
52
|
KUBERNETES = "k8s"
|
|
53
53
|
}
|
|
54
|
-
export declare const runtimeEnvironmentSchema: z.
|
|
55
|
-
export declare const runtimeEnvironmentInputSchema: z.
|
|
54
|
+
export declare const runtimeEnvironmentSchema: z.ZodEnum<typeof RuntimeEnvironment>;
|
|
55
|
+
export declare const runtimeEnvironmentInputSchema: z.ZodPreprocess<z.ZodEnum<typeof RuntimeEnvironment>, unknown>;
|
|
56
56
|
export declare function normalizeRuntimeEnvironment(value: RuntimeEnvironment | "kubernetes"): RuntimeEnvironment;
|
|
57
57
|
export interface TestConfig {
|
|
58
58
|
testType: TestType;
|
|
59
59
|
toolName: string;
|
|
60
60
|
description: string;
|
|
61
|
-
additionalFields?: Record<string, z.
|
|
61
|
+
additionalFields?: Record<string, z.ZodType>;
|
|
62
62
|
}
|
|
63
63
|
export declare const languageSchema: z.ZodObject<{
|
|
64
|
-
language: z.
|
|
64
|
+
language: z.ZodEnum<typeof ProgrammingLanguage>;
|
|
65
65
|
framework: z.ZodString;
|
|
66
|
-
},
|
|
67
|
-
language: ProgrammingLanguage;
|
|
68
|
-
framework: string;
|
|
69
|
-
}, {
|
|
70
|
-
language: ProgrammingLanguage;
|
|
71
|
-
framework: string;
|
|
72
|
-
}>;
|
|
66
|
+
}, z.core.$strip>;
|
|
73
67
|
export declare const baseSchema: z.ZodObject<{
|
|
74
68
|
deployDashboard: z.ZodDefault<z.ZodBoolean>;
|
|
75
|
-
runtime: z.ZodDefault<z.
|
|
69
|
+
runtime: z.ZodDefault<z.ZodPreprocess<z.ZodEnum<typeof RuntimeEnvironment>, unknown>>;
|
|
76
70
|
dockerNetwork: z.ZodDefault<z.ZodString>;
|
|
77
71
|
dockerWorkerPort: z.ZodDefault<z.ZodNumber>;
|
|
78
72
|
k8sNamespace: z.ZodDefault<z.ZodString>;
|
|
@@ -81,78 +75,35 @@ export declare const baseSchema: z.ZodObject<{
|
|
|
81
75
|
authHeader: z.ZodDefault<z.ZodString>;
|
|
82
76
|
authScheme: z.ZodDefault<z.ZodString>;
|
|
83
77
|
insecure: z.ZodDefault<z.ZodBoolean>;
|
|
84
|
-
output: z.
|
|
78
|
+
output: z.ZodOptional<z.ZodString>;
|
|
85
79
|
outputDir: z.ZodString;
|
|
86
80
|
force: z.ZodDefault<z.ZodBoolean>;
|
|
87
81
|
mockPort: z.ZodDefault<z.ZodNumber>;
|
|
88
82
|
optionalFields: z.ZodDefault<z.ZodBoolean>;
|
|
89
83
|
prompt: z.ZodString;
|
|
90
|
-
language: z.
|
|
84
|
+
language: z.ZodEnum<typeof ProgrammingLanguage>;
|
|
91
85
|
framework: z.ZodString;
|
|
92
|
-
},
|
|
93
|
-
language: ProgrammingLanguage;
|
|
94
|
-
framework: string;
|
|
95
|
-
deployDashboard: boolean;
|
|
96
|
-
runtime: RuntimeEnvironment;
|
|
97
|
-
dockerNetwork: string;
|
|
98
|
-
dockerWorkerPort: number;
|
|
99
|
-
k8sNamespace: string;
|
|
100
|
-
k8sConfig: string;
|
|
101
|
-
k8sContext: string;
|
|
102
|
-
authHeader: string;
|
|
103
|
-
authScheme: string;
|
|
104
|
-
insecure: boolean;
|
|
105
|
-
outputDir: string;
|
|
106
|
-
force: boolean;
|
|
107
|
-
mockPort: number;
|
|
108
|
-
optionalFields: boolean;
|
|
109
|
-
prompt: string;
|
|
110
|
-
output?: string | undefined;
|
|
111
|
-
}, {
|
|
112
|
-
language: ProgrammingLanguage;
|
|
113
|
-
framework: string;
|
|
114
|
-
outputDir: string;
|
|
115
|
-
prompt: string;
|
|
116
|
-
deployDashboard?: boolean | undefined;
|
|
117
|
-
runtime?: unknown;
|
|
118
|
-
dockerNetwork?: string | undefined;
|
|
119
|
-
dockerWorkerPort?: number | undefined;
|
|
120
|
-
k8sNamespace?: string | undefined;
|
|
121
|
-
k8sConfig?: string | undefined;
|
|
122
|
-
k8sContext?: string | undefined;
|
|
123
|
-
authHeader?: string | undefined;
|
|
124
|
-
authScheme?: string | undefined;
|
|
125
|
-
insecure?: boolean | undefined;
|
|
126
|
-
output?: string | undefined;
|
|
127
|
-
force?: boolean | undefined;
|
|
128
|
-
mockPort?: number | undefined;
|
|
129
|
-
optionalFields?: boolean | undefined;
|
|
130
|
-
}>;
|
|
86
|
+
}, z.core.$strip>;
|
|
131
87
|
export declare const basePlaywrightSchema: z.ZodObject<{
|
|
132
88
|
playwrightInput: z.ZodString;
|
|
133
89
|
playwrightStoragePath: z.ZodOptional<z.ZodString>;
|
|
134
90
|
playwrightSaveStoragePath: z.ZodOptional<z.ZodString>;
|
|
135
|
-
playwrightViewportSize: z.ZodDefault<z.ZodUnion<[z.ZodEnum<
|
|
136
|
-
|
|
91
|
+
playwrightViewportSize: z.ZodDefault<z.ZodUnion<readonly [z.ZodEnum<{
|
|
92
|
+
"": "";
|
|
93
|
+
hd: "hd";
|
|
94
|
+
"full-hd": "full-hd";
|
|
95
|
+
"2k": "2k";
|
|
96
|
+
}>, z.ZodString]>>;
|
|
97
|
+
browser: z.ZodDefault<z.ZodEnum<{
|
|
98
|
+
chromium: "chromium";
|
|
99
|
+
firefox: "firefox";
|
|
100
|
+
webkit: "webkit";
|
|
101
|
+
}>>;
|
|
137
102
|
device: z.ZodDefault<z.ZodString>;
|
|
138
|
-
},
|
|
139
|
-
playwrightInput: string;
|
|
140
|
-
playwrightViewportSize: string;
|
|
141
|
-
browser: "chromium" | "firefox" | "webkit";
|
|
142
|
-
device: string;
|
|
143
|
-
playwrightStoragePath?: string | undefined;
|
|
144
|
-
playwrightSaveStoragePath?: string | undefined;
|
|
145
|
-
}, {
|
|
146
|
-
playwrightInput: string;
|
|
147
|
-
playwrightStoragePath?: string | undefined;
|
|
148
|
-
playwrightSaveStoragePath?: string | undefined;
|
|
149
|
-
playwrightViewportSize?: string | undefined;
|
|
150
|
-
browser?: "chromium" | "firefox" | "webkit" | undefined;
|
|
151
|
-
device?: string | undefined;
|
|
152
|
-
}>;
|
|
103
|
+
}, z.core.$strip>;
|
|
153
104
|
export declare const baseTraceSchema: z.ZodObject<{
|
|
154
105
|
deployDashboard: z.ZodDefault<z.ZodBoolean>;
|
|
155
|
-
runtime: z.ZodDefault<z.
|
|
106
|
+
runtime: z.ZodDefault<z.ZodPreprocess<z.ZodEnum<typeof RuntimeEnvironment>, unknown>>;
|
|
156
107
|
dockerNetwork: z.ZodDefault<z.ZodString>;
|
|
157
108
|
dockerWorkerPort: z.ZodDefault<z.ZodNumber>;
|
|
158
109
|
k8sNamespace: z.ZodDefault<z.ZodString>;
|
|
@@ -161,65 +112,21 @@ export declare const baseTraceSchema: z.ZodObject<{
|
|
|
161
112
|
authHeader: z.ZodDefault<z.ZodString>;
|
|
162
113
|
authScheme: z.ZodDefault<z.ZodString>;
|
|
163
114
|
insecure: z.ZodDefault<z.ZodBoolean>;
|
|
164
|
-
output: z.
|
|
115
|
+
output: z.ZodOptional<z.ZodString>;
|
|
165
116
|
outputDir: z.ZodString;
|
|
166
117
|
force: z.ZodDefault<z.ZodBoolean>;
|
|
167
118
|
mockPort: z.ZodDefault<z.ZodNumber>;
|
|
168
119
|
optionalFields: z.ZodDefault<z.ZodBoolean>;
|
|
169
120
|
prompt: z.ZodString;
|
|
170
|
-
language: z.
|
|
121
|
+
language: z.ZodEnum<typeof ProgrammingLanguage>;
|
|
171
122
|
framework: z.ZodString;
|
|
172
123
|
trace: z.ZodString;
|
|
173
|
-
include: z.ZodDefault<z.ZodArray<z.ZodString
|
|
174
|
-
exclude: z.ZodDefault<z.ZodArray<z.ZodString
|
|
175
|
-
},
|
|
176
|
-
language: ProgrammingLanguage;
|
|
177
|
-
framework: string;
|
|
178
|
-
deployDashboard: boolean;
|
|
179
|
-
runtime: RuntimeEnvironment;
|
|
180
|
-
dockerNetwork: string;
|
|
181
|
-
dockerWorkerPort: number;
|
|
182
|
-
k8sNamespace: string;
|
|
183
|
-
k8sConfig: string;
|
|
184
|
-
k8sContext: string;
|
|
185
|
-
authHeader: string;
|
|
186
|
-
authScheme: string;
|
|
187
|
-
insecure: boolean;
|
|
188
|
-
outputDir: string;
|
|
189
|
-
force: boolean;
|
|
190
|
-
mockPort: number;
|
|
191
|
-
optionalFields: boolean;
|
|
192
|
-
prompt: string;
|
|
193
|
-
trace: string;
|
|
194
|
-
include: string[];
|
|
195
|
-
exclude: string[];
|
|
196
|
-
output?: string | undefined;
|
|
197
|
-
}, {
|
|
198
|
-
language: ProgrammingLanguage;
|
|
199
|
-
framework: string;
|
|
200
|
-
outputDir: string;
|
|
201
|
-
prompt: string;
|
|
202
|
-
trace: string;
|
|
203
|
-
deployDashboard?: boolean | undefined;
|
|
204
|
-
runtime?: unknown;
|
|
205
|
-
dockerNetwork?: string | undefined;
|
|
206
|
-
dockerWorkerPort?: number | undefined;
|
|
207
|
-
k8sNamespace?: string | undefined;
|
|
208
|
-
k8sConfig?: string | undefined;
|
|
209
|
-
k8sContext?: string | undefined;
|
|
210
|
-
authHeader?: string | undefined;
|
|
211
|
-
authScheme?: string | undefined;
|
|
212
|
-
insecure?: boolean | undefined;
|
|
213
|
-
output?: string | undefined;
|
|
214
|
-
force?: boolean | undefined;
|
|
215
|
-
mockPort?: number | undefined;
|
|
216
|
-
optionalFields?: boolean | undefined;
|
|
217
|
-
include?: string[] | undefined;
|
|
218
|
-
exclude?: string[] | undefined;
|
|
219
|
-
}>;
|
|
124
|
+
include: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
125
|
+
exclude: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
126
|
+
}, z.core.$strip>;
|
|
220
127
|
export declare const baseTestSchema: {
|
|
221
128
|
deployDashboard: z.ZodDefault<z.ZodBoolean>;
|
|
222
|
-
runtime: z.ZodDefault<z.
|
|
129
|
+
runtime: z.ZodDefault<z.ZodPreprocess<z.ZodEnum<typeof RuntimeEnvironment>, unknown>>;
|
|
223
130
|
dockerNetwork: z.ZodDefault<z.ZodString>;
|
|
224
131
|
dockerWorkerPort: z.ZodDefault<z.ZodNumber>;
|
|
225
132
|
k8sNamespace: z.ZodDefault<z.ZodString>;
|
|
@@ -228,33 +135,34 @@ export declare const baseTestSchema: {
|
|
|
228
135
|
authHeader: z.ZodDefault<z.ZodString>;
|
|
229
136
|
authScheme: z.ZodDefault<z.ZodString>;
|
|
230
137
|
insecure: z.ZodDefault<z.ZodBoolean>;
|
|
231
|
-
output: z.
|
|
138
|
+
output: z.ZodOptional<z.ZodString>;
|
|
232
139
|
outputDir: z.ZodString;
|
|
233
140
|
force: z.ZodDefault<z.ZodBoolean>;
|
|
234
141
|
mockPort: z.ZodDefault<z.ZodNumber>;
|
|
235
142
|
optionalFields: z.ZodDefault<z.ZodBoolean>;
|
|
236
143
|
prompt: z.ZodString;
|
|
237
|
-
language: z.
|
|
144
|
+
language: z.ZodEnum<typeof ProgrammingLanguage>;
|
|
238
145
|
framework: z.ZodString;
|
|
239
146
|
endpointURL: z.ZodString;
|
|
240
|
-
method: z.ZodDefault<z.ZodUnion<[z.
|
|
147
|
+
method: z.ZodDefault<z.ZodUnion<readonly [z.ZodEnum<typeof HttpMethod>, z.ZodLiteral<"">]>>;
|
|
241
148
|
apiSchema: z.ZodDefault<z.ZodString>;
|
|
242
149
|
pathParams: z.ZodDefault<z.ZodString>;
|
|
243
150
|
queryParams: z.ZodDefault<z.ZodString>;
|
|
244
151
|
formParams: z.ZodDefault<z.ZodString>;
|
|
245
|
-
requestData: z.
|
|
246
|
-
responseStatusCode: z.
|
|
152
|
+
requestData: z.ZodDefault<z.ZodString>;
|
|
153
|
+
responseStatusCode: z.ZodDefault<z.ZodString>;
|
|
247
154
|
};
|
|
248
155
|
export declare const codeRefactoringSchema: z.ZodObject<{
|
|
249
156
|
codeReuse: z.ZodDefault<z.ZodBoolean>;
|
|
250
157
|
modularizeCode: z.ZodDefault<z.ZodBoolean>;
|
|
251
|
-
},
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
158
|
+
}, z.core.$strip>;
|
|
159
|
+
/** The `testName` field for a recording-driven generation tool.
|
|
160
|
+
*
|
|
161
|
+
* Single-sourced because the description is prompt text: it is the only thing
|
|
162
|
+
* steering the agent's choice of title, it gets re-tuned against eval results,
|
|
163
|
+
* and two copies would let the UI and E2E tools drift apart silently. Each
|
|
164
|
+
* tool passes the title its own generator falls back to (SKYR-4468). */
|
|
165
|
+
export declare const testNameField: (fallbackTitle: string) => z.ZodOptional<z.ZodString>;
|
|
258
166
|
/** Test types skyramp_enhance_assertions supports — single-sourced so the
|
|
259
167
|
* tool's schema enum and generation-time baseline seeding cannot drift
|
|
260
168
|
* (contract additionally requires provider mode at the seeding site). */
|
package/build/types/TestTypes.js
CHANGED
|
@@ -64,14 +64,14 @@ export var RuntimeEnvironment;
|
|
|
64
64
|
RuntimeEnvironment["DOCKER"] = "docker";
|
|
65
65
|
RuntimeEnvironment["KUBERNETES"] = "k8s";
|
|
66
66
|
})(RuntimeEnvironment || (RuntimeEnvironment = {}));
|
|
67
|
-
export const runtimeEnvironmentSchema = z.
|
|
67
|
+
export const runtimeEnvironmentSchema = z.enum(RuntimeEnvironment);
|
|
68
68
|
export const runtimeEnvironmentInputSchema = z.preprocess((value) => (value === "kubernetes" ? RuntimeEnvironment.KUBERNETES : value), runtimeEnvironmentSchema);
|
|
69
69
|
export function normalizeRuntimeEnvironment(value) {
|
|
70
70
|
return value === "kubernetes" ? RuntimeEnvironment.KUBERNETES : value;
|
|
71
71
|
}
|
|
72
72
|
export const languageSchema = z.object({
|
|
73
73
|
language: z
|
|
74
|
-
.
|
|
74
|
+
.enum(ProgrammingLanguage)
|
|
75
75
|
.describe("Programming language for the generated test (default: python). Must be one of: python, typescript, javascript, java"),
|
|
76
76
|
framework: z
|
|
77
77
|
.string()
|
|
@@ -217,7 +217,7 @@ export const baseTestSchema = {
|
|
|
217
217
|
"(e.g., https://demoshop.skyramp.dev/api/v1/products). " +
|
|
218
218
|
"MUST include both the base URL and the endpoint path — never just the base URL alone."),
|
|
219
219
|
method: z
|
|
220
|
-
.union([z.
|
|
220
|
+
.union([z.enum(HttpMethod), z.literal("")])
|
|
221
221
|
.default("")
|
|
222
222
|
.describe('HTTP method to use. DEFAULT: Use empty string ("") to test ALL available methods from OpenAPI schema (recommended). Only specify a specific method (GET, POST, PUT, DELETE, etc.) if user explicitly requests testing a single method only.'),
|
|
223
223
|
apiSchema: z
|
|
@@ -291,6 +291,28 @@ export const codeRefactoringSchema = z.object({
|
|
|
291
291
|
.default(false)
|
|
292
292
|
.describe("Whether to modularize the code"),
|
|
293
293
|
});
|
|
294
|
+
/** The `testName` field for a recording-driven generation tool.
|
|
295
|
+
*
|
|
296
|
+
* Single-sourced because the description is prompt text: it is the only thing
|
|
297
|
+
* steering the agent's choice of title, it gets re-tuned against eval results,
|
|
298
|
+
* and two copies would let the UI and E2E tools drift apart silently. Each
|
|
299
|
+
* tool passes the title its own generator falls back to (SKYR-4468). */
|
|
300
|
+
export const testNameField = (fallbackTitle) => z
|
|
301
|
+
.string()
|
|
302
|
+
// .trim() normalises incidental whitespace and, combined with .min(1),
|
|
303
|
+
// rejects a whitespace-only title, which would otherwise produce a
|
|
304
|
+
// meaningless test title and identifier (SKYR-4468).
|
|
305
|
+
.trim()
|
|
306
|
+
.min(1)
|
|
307
|
+
.optional()
|
|
308
|
+
.describe("Title for the generated test. Name the BEHAVIOUR this recording verifies, " +
|
|
309
|
+
"taken from the recommendation the recording came from — not the page it happens on. " +
|
|
310
|
+
"Keep it to one short phrase, under about 60 characters. " +
|
|
311
|
+
'Example: "Add to cart from search results", not "Search page". ' +
|
|
312
|
+
"Skyramp emits it verbatim as the Playwright test title for TypeScript/JavaScript. " +
|
|
313
|
+
"Python and Java get it as a comment above the test, and a function name built from " +
|
|
314
|
+
"its ASCII words and cut at 80 characters. " +
|
|
315
|
+
`Omit it and the test stays titled \`${fallbackTitle}\`, which claims nothing.`);
|
|
294
316
|
/** Test types skyramp_enhance_assertions supports — single-sourced so the
|
|
295
317
|
* tool's schema enum and generation-time baseline seeding cannot drift
|
|
296
318
|
* (contract additionally requires provider mode at the seeding site). */
|
|
@@ -227,7 +227,10 @@ export interface TestbotReport {
|
|
|
227
227
|
/** Files an UPDATE or REGENERATE verdict edited, minus any already counted as
|
|
228
228
|
* generated — one file owes one run however it was written. */
|
|
229
229
|
updated: number;
|
|
230
|
-
/**
|
|
230
|
+
/** Files a VERIFY verdict names in the primary repository, minus any already
|
|
231
|
+
* counted above. Never edited, but each owes one run. */
|
|
232
|
+
verified: number;
|
|
233
|
+
/** How many of those `generated + updated + verified` files were passed to
|
|
231
234
|
* skyramp_execute_test. The file reached the runner; that is not proof a test
|
|
232
235
|
* ran, because a runner can exit 0 having executed nothing. */
|
|
233
236
|
executed: number;
|
|
@@ -197,6 +197,18 @@ function expectSites(raw, stripped) {
|
|
|
197
197
|
matcher = link[1];
|
|
198
198
|
break;
|
|
199
199
|
}
|
|
200
|
+
// `expect(async () => { ... }).toPass()` is a retry wrapper, not an
|
|
201
|
+
// assertion: the assertions are the expect() calls inside it. Record none
|
|
202
|
+
// for the wrapper and resume scanning inside its argument, so the inner
|
|
203
|
+
// ones are scored for what they check (the generated order assertion
|
|
204
|
+
// compares boundingBox() geometry inside toPass()).
|
|
205
|
+
// `.not.toPass()` inverts the block (it must keep failing), so its inner
|
|
206
|
+
// assertions are not positive checks: it falls through to ordinary wrapper
|
|
207
|
+
// scoring (weight 1). Python's Playwright has no to_pass equivalent.
|
|
208
|
+
if (matcher === "toPass" && !links.includes("not")) {
|
|
209
|
+
re.lastIndex = openIdx + 1;
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
200
212
|
let matcherArgs;
|
|
201
213
|
if (matcher !== undefined) {
|
|
202
214
|
const matcherOpen = /^\s*\(/.exec(stripped.slice(cursor));
|
package/build/utils/docker.d.ts
CHANGED
|
@@ -1,15 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a pull failed because the image has nothing for the requested platform. The
|
|
3
|
+
* wording depends on the daemon and its image store: a Windows daemon answers a linux-only
|
|
4
|
+
* image, even a multi-platform one, with "image operating system ... cannot be used on this
|
|
5
|
+
* platform" (observed on Windows Server 2022, Docker 29.7.2); a manifest list without the
|
|
6
|
+
* platform gives "no matching manifest"; the containerd image store says "no match for
|
|
7
|
+
* platform in manifest". Anything else -- the network, a rate limit, a full disk -- is not
|
|
8
|
+
* this.
|
|
9
|
+
*/
|
|
10
|
+
export declare function isPlatformUnavailableError(err: unknown): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Returns the Docker platform string for the current host architecture.
|
|
13
|
+
* Mirrors the backend's getDockerPlatform() in cmd/libs/init.go.
|
|
14
|
+
*/
|
|
15
|
+
export declare function getDockerPlatform(): string;
|
|
1
16
|
/**
|
|
2
17
|
* Pull a Docker image by name.
|
|
3
18
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* back to linux/amd64 if the arm64 pull fails or the image doesn't land
|
|
10
|
-
* locally (Docker Desktop quirk on Apple Silicon).
|
|
19
|
+
* `dockerPlatform` defaults to the host architecture. Whether given or
|
|
20
|
+
* defaulted, a `linux/arm64` pull falls back to `linux/amd64` when the arm64
|
|
21
|
+
* pull reports no matching manifest or completes without the image landing
|
|
22
|
+
* locally (Docker Desktop quirk on Apple Silicon). Any other platform is
|
|
23
|
+
* pulled exactly, with no fallback.
|
|
11
24
|
*/
|
|
12
25
|
export declare function pullDockerImage(imageName: string, dockerPlatform?: string): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* The default daemon's operating system ("windows" or "linux"), or undefined when it
|
|
28
|
+
* cannot be determined. The startup prefetch pulls each image for this OS; when it is
|
|
29
|
+
* undefined the executor is pulled as linux/amd64 and the worker for the host's own
|
|
30
|
+
* architecture (getDockerPlatform). Guessing is acceptable there because the prefetch is
|
|
31
|
+
* best-effort: a wrong guess costs a download, and the run itself refuses to guess
|
|
32
|
+
* (resolvePlatform in FleetExecutionService).
|
|
33
|
+
*/
|
|
34
|
+
export declare function dockerDaemonOsType(): Promise<string | undefined>;
|
|
13
35
|
/**
|
|
14
36
|
* Check if a Docker image exists locally for the given reference (repo:tag or digest).
|
|
15
37
|
* Uses image inspect (daemon name resolution), not listImages tag scanning.
|
package/build/utils/docker.js
CHANGED
|
@@ -26,11 +26,26 @@ function isManifestMismatchError(err) {
|
|
|
26
26
|
const msg = err?.message ?? "";
|
|
27
27
|
return msg.includes("no matching manifest");
|
|
28
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Whether a pull failed because the image has nothing for the requested platform. The
|
|
31
|
+
* wording depends on the daemon and its image store: a Windows daemon answers a linux-only
|
|
32
|
+
* image, even a multi-platform one, with "image operating system ... cannot be used on this
|
|
33
|
+
* platform" (observed on Windows Server 2022, Docker 29.7.2); a manifest list without the
|
|
34
|
+
* platform gives "no matching manifest"; the containerd image store says "no match for
|
|
35
|
+
* platform in manifest". Anything else -- the network, a rate limit, a full disk -- is not
|
|
36
|
+
* this.
|
|
37
|
+
*/
|
|
38
|
+
export function isPlatformUnavailableError(err) {
|
|
39
|
+
const msg = err?.message ?? "";
|
|
40
|
+
return (msg.includes("no matching manifest") ||
|
|
41
|
+
msg.includes("cannot be used on this platform") ||
|
|
42
|
+
msg.includes("no match for platform in manifest"));
|
|
43
|
+
}
|
|
29
44
|
/**
|
|
30
45
|
* Returns the Docker platform string for the current host architecture.
|
|
31
46
|
* Mirrors the backend's getDockerPlatform() in cmd/libs/init.go.
|
|
32
47
|
*/
|
|
33
|
-
function getDockerPlatform() {
|
|
48
|
+
export function getDockerPlatform() {
|
|
34
49
|
return process.arch === "arm64" ? "linux/arm64" : "linux/amd64";
|
|
35
50
|
}
|
|
36
51
|
async function doPull(docker, imageName, platform) {
|
|
@@ -40,14 +55,27 @@ async function doPull(docker, imageName, platform) {
|
|
|
40
55
|
return reject(err);
|
|
41
56
|
if (!stream)
|
|
42
57
|
return reject(new Error("No stream received from docker pull"));
|
|
58
|
+
// A pull can fail INSIDE the progress stream: followProgress still finishes
|
|
59
|
+
// without an error object, and the failure appears only as an `error` field on
|
|
60
|
+
// one of the messages. Without reading them, a pull that stored nothing is
|
|
61
|
+
// logged as a success. The Go side guards the same thing (`message.Error` in
|
|
62
|
+
// RunSkyrampWorker).
|
|
63
|
+
let streamError;
|
|
43
64
|
docker.modem.followProgress(stream, (err) => {
|
|
44
65
|
if (err)
|
|
45
66
|
return reject(err);
|
|
67
|
+
if (streamError) {
|
|
68
|
+
return reject(new Error(`docker pull ${imageName} (${platform}) failed: ${streamError}`));
|
|
69
|
+
}
|
|
46
70
|
logger.info("Docker image pulled successfully", {
|
|
47
71
|
image: imageName,
|
|
48
72
|
platform,
|
|
49
73
|
});
|
|
50
74
|
resolve();
|
|
75
|
+
}, (msg) => {
|
|
76
|
+
if (msg?.error && streamError === undefined) {
|
|
77
|
+
streamError = msg.errorDetail?.message ?? msg.error;
|
|
78
|
+
}
|
|
51
79
|
});
|
|
52
80
|
});
|
|
53
81
|
});
|
|
@@ -55,39 +83,67 @@ async function doPull(docker, imageName, platform) {
|
|
|
55
83
|
/**
|
|
56
84
|
* Pull a Docker image by name.
|
|
57
85
|
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
* back to linux/amd64 if the arm64 pull fails or the image doesn't land
|
|
64
|
-
* locally (Docker Desktop quirk on Apple Silicon).
|
|
86
|
+
* `dockerPlatform` defaults to the host architecture. Whether given or
|
|
87
|
+
* defaulted, a `linux/arm64` pull falls back to `linux/amd64` when the arm64
|
|
88
|
+
* pull reports no matching manifest or completes without the image landing
|
|
89
|
+
* locally (Docker Desktop quirk on Apple Silicon). Any other platform is
|
|
90
|
+
* pulled exactly, with no fallback.
|
|
65
91
|
*/
|
|
66
92
|
export async function pullDockerImage(imageName, dockerPlatform) {
|
|
67
93
|
const client = new Dockerode();
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
94
|
+
const platform = dockerPlatform ?? getDockerPlatform();
|
|
95
|
+
// Docker Desktop on Apple Silicon serves amd64-only images under emulation, but an arm64
|
|
96
|
+
// pull of one either reports no matching manifest or completes and stores nothing. Those
|
|
97
|
+
// are the same rule, not two special cases: try these platforms in order until one
|
|
98
|
+
// actually lands.
|
|
99
|
+
const candidates = platform === "linux/arm64" ? [platform, "linux/amd64"] : [platform];
|
|
100
|
+
for (let i = 0; i < candidates.length; i++) {
|
|
101
|
+
const candidate = candidates[i];
|
|
102
|
+
const next = candidates[i + 1];
|
|
103
|
+
try {
|
|
104
|
+
await doPull(client, imageName, candidate);
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
// A manifest mismatch is the one failure another platform can answer.
|
|
108
|
+
if (next === undefined || !isManifestMismatchError(err))
|
|
109
|
+
throw err;
|
|
110
|
+
logger.info("pull failed, retrying on the next platform", {
|
|
111
|
+
image: imageName,
|
|
112
|
+
failed: candidate,
|
|
113
|
+
next,
|
|
114
|
+
});
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
// A pull can end its stream cleanly and store nothing, so success is the image being
|
|
118
|
+
// present -- not the pull returning.
|
|
119
|
+
if (await dockerImageExistsLocally(imageName))
|
|
120
|
+
return;
|
|
121
|
+
if (next === undefined)
|
|
122
|
+
break;
|
|
123
|
+
logger.info("pull completed but the image is absent, retrying on the next platform", {
|
|
124
|
+
image: imageName,
|
|
125
|
+
failed: candidate,
|
|
126
|
+
next,
|
|
127
|
+
});
|
|
71
128
|
}
|
|
72
|
-
|
|
129
|
+
throw new Error(`docker pull ${imageName} (${candidates.join(", ")}) reported success but the image is not present locally`);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* The default daemon's operating system ("windows" or "linux"), or undefined when it
|
|
133
|
+
* cannot be determined. The startup prefetch pulls each image for this OS; when it is
|
|
134
|
+
* undefined the executor is pulled as linux/amd64 and the worker for the host's own
|
|
135
|
+
* architecture (getDockerPlatform). Guessing is acceptable there because the prefetch is
|
|
136
|
+
* best-effort: a wrong guess costs a download, and the run itself refuses to guess
|
|
137
|
+
* (resolvePlatform in FleetExecutionService).
|
|
138
|
+
*/
|
|
139
|
+
export async function dockerDaemonOsType() {
|
|
73
140
|
try {
|
|
74
|
-
|
|
141
|
+
const info = (await new Dockerode().info());
|
|
142
|
+
return info?.OSType;
|
|
75
143
|
}
|
|
76
144
|
catch (err) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
await doPull(client, imageName, "linux/amd64");
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
throw err;
|
|
83
|
-
}
|
|
84
|
-
// On Docker Desktop/Mac, pulling an amd64-only image with linux/arm64 can
|
|
85
|
-
// complete the stream without error yet not store the image locally.
|
|
86
|
-
// Verify it actually landed, and fall back to amd64 if not.
|
|
87
|
-
if (platform === "linux/arm64" &&
|
|
88
|
-
!(await dockerImageExistsLocally(imageName))) {
|
|
89
|
-
logger.info("arm64 pull completed but image not found locally, retrying with linux/amd64", { image: imageName });
|
|
90
|
-
await doPull(client, imageName, "linux/amd64");
|
|
145
|
+
logger.warning("Could not determine the Docker daemon OS", { error: err });
|
|
146
|
+
return undefined;
|
|
91
147
|
}
|
|
92
148
|
}
|
|
93
149
|
/**
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The first `<dir>/<candidate>` that exists, checking `from` and then each
|
|
3
|
+
* ancestor, or undefined.
|
|
4
|
+
*
|
|
5
|
+
* With `stopAtRepoRoot`, only the directories up to the nearest one holding
|
|
6
|
+
* `.git` (a directory or a file, so worktrees count) are searched, and a `from`
|
|
7
|
+
* outside any checkout searches nothing: a parent directory is not the
|
|
8
|
+
* repository's to answer for. The walk never passes the filesystem root or
|
|
9
|
+
* MAX_LEVELS.
|
|
10
|
+
*/
|
|
11
|
+
export declare function findUp(from: string, candidates: readonly string[], { stopAtRepoRoot }?: {
|
|
12
|
+
stopAtRepoRoot?: boolean;
|
|
13
|
+
}): string | undefined;
|
|
14
|
+
/** The package's manifest as Node would find it from `from`: the nearest
|
|
15
|
+
* `node_modules/<pkg>/package.json` walking UP from there. Node's own lookup
|
|
16
|
+
* never reads NODE_PATH for this, and neither does this one. A manifest that
|
|
17
|
+
* does not parse is logged and treated as absent. */
|
|
18
|
+
export declare function installedManifest(pkg: string, from: string, options?: {
|
|
19
|
+
stopAtRepoRoot?: boolean;
|
|
20
|
+
}): Record<string, unknown> | undefined;
|