@skyramp/mcp 0.4.4-rc.1 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/build/index.js +239 -210
  2. package/build/playwright/PlaywrightTraceService.d.ts +1 -1
  3. package/build/playwright/blueprintDigestStore.d.ts +1 -1
  4. package/build/playwright/registerPlaywrightTools.d.ts +1 -1
  5. package/build/playwright/traceRecordingPrompt.d.ts +1 -1
  6. package/build/playwright/traceRecordingPrompt.js +2 -2
  7. package/build/prompts/local-dev/local-dev-prompts.d.ts +1 -1
  8. package/build/prompts/local-dev/local-dev-prompts.js +2 -2
  9. package/build/prompts/startTraceCollectionPrompts.d.ts +1 -1
  10. package/build/prompts/startTraceCollectionPrompts.js +2 -3
  11. package/build/prompts/test-recommendation/registerRecommendTestsPrompt.d.ts +1 -1
  12. package/build/prompts/test-recommendation/registerRecommendTestsPrompt.js +2 -2
  13. package/build/prompts/testbot/testbot-prompts.d.ts +1 -1
  14. package/build/prompts/testbot/testbot-prompts.js +4 -7
  15. package/build/recommendation/answers.d.ts +17 -52
  16. package/build/recommendation/answers.js +29 -99
  17. package/build/recommendation/pullRequestText.d.ts +0 -2
  18. package/build/recommendation/pullRequestText.js +0 -16
  19. package/build/recommendation/registerPlan.d.ts +4 -7
  20. package/build/recommendation/registerPlan.js +11 -37
  21. package/build/recommendation/types.d.ts +4 -21
  22. package/build/recommendation/verifierContracts.d.ts +4 -4
  23. package/build/recommendation/verifierContracts.js +4 -4
  24. package/build/recommendation/verifiers/citedPath.d.ts +2 -2
  25. package/build/recommendation/verifiers/citedPath.js +2 -2
  26. package/build/recommendation/verifiers/issueTraceability.d.ts +5 -1
  27. package/build/recommendation/verifiers/issueTraceability.js +35 -4
  28. package/build/resources/analysisResources.d.ts +1 -1
  29. package/build/resources/analysisResources.js +1 -1
  30. package/build/resources/progressResource.d.ts +1 -1
  31. package/build/resources/sutSetupResource.d.ts +1 -1
  32. package/build/resources/sutSetupResource.js +1 -1
  33. package/build/resources/testbotResource.d.ts +1 -1
  34. package/build/resources/testbotResource.js +1 -1
  35. package/build/services/AnalyticsService.d.ts +1 -1
  36. package/build/services/FleetExecutionService.d.ts +130 -0
  37. package/build/services/FleetExecutionService.js +391 -0
  38. package/build/services/ModularizationService.d.ts +1 -1
  39. package/build/services/TestExecutionService.d.ts +7 -0
  40. package/build/services/TestExecutionService.js +21 -0
  41. package/build/services/TestGenerationService.d.ts +1 -1
  42. package/build/tool-phases.js +2 -0
  43. package/build/tools/auth/loginTool.d.ts +1 -1
  44. package/build/tools/auth/loginTool.js +2 -2
  45. package/build/tools/auth/logoutTool.d.ts +1 -1
  46. package/build/tools/auth/logoutTool.js +2 -2
  47. package/build/tools/code-refactor/alignAssertionsTool.d.ts +1 -1
  48. package/build/tools/code-refactor/alignAssertionsTool.js +1 -1
  49. package/build/tools/code-refactor/assertionSkillTools.d.ts +1 -1
  50. package/build/tools/code-refactor/assertionSkillTools.js +2 -2
  51. package/build/tools/code-refactor/codeReuseTool.d.ts +1 -1
  52. package/build/tools/code-refactor/codeReuseTool.js +2 -2
  53. package/build/tools/code-refactor/enhanceAssertionsTool.d.ts +1 -1
  54. package/build/tools/code-refactor/enhanceAssertionsTool.js +1 -1
  55. package/build/tools/code-refactor/modularizationTool.d.ts +1 -1
  56. package/build/tools/code-refactor/modularizationTool.js +2 -2
  57. package/build/tools/enrichTestWithMocksTool.d.ts +1 -1
  58. package/build/tools/enrichTestWithMocksTool.js +2 -2
  59. package/build/tools/executeFleetTool.d.ts +28 -0
  60. package/build/tools/executeFleetTool.js +107 -0
  61. package/build/tools/executeSkyrampTestTool.d.ts +8 -5
  62. package/build/tools/executeSkyrampTestTool.js +5 -5
  63. package/build/tools/fixErrorTool.d.ts +1 -1
  64. package/build/tools/fixErrorTool.js +1 -1
  65. package/build/tools/generate-tests/batchMockGenerationTool.d.ts +6 -57
  66. package/build/tools/generate-tests/batchMockGenerationTool.js +3 -3
  67. package/build/tools/generate-tests/generateBatchScenarioRestTool.d.ts +9 -45
  68. package/build/tools/generate-tests/generateBatchScenarioRestTool.js +29 -11
  69. package/build/tools/generate-tests/generateContractRestTool.d.ts +1 -2
  70. package/build/tools/generate-tests/generateContractRestTool.js +1 -1
  71. package/build/tools/generate-tests/generateE2ERestTool.d.ts +1 -2
  72. package/build/tools/generate-tests/generateE2ERestTool.js +1 -1
  73. package/build/tools/generate-tests/generateFuzzRestTool.d.ts +1 -1
  74. package/build/tools/generate-tests/generateFuzzRestTool.js +1 -1
  75. package/build/tools/generate-tests/generateIntegrationRestTool.d.ts +1 -2
  76. package/build/tools/generate-tests/generateIntegrationRestTool.js +1 -1
  77. package/build/tools/generate-tests/generateLoadRestTool.d.ts +1 -2
  78. package/build/tools/generate-tests/generateLoadRestTool.js +2 -1
  79. package/build/tools/generate-tests/generateMockRestTool.d.ts +1 -2
  80. package/build/tools/generate-tests/generateMockRestTool.js +3 -3
  81. package/build/tools/generate-tests/generateSmokeRestTool.d.ts +1 -1
  82. package/build/tools/generate-tests/generateSmokeRestTool.js +1 -1
  83. package/build/tools/generate-tests/generateUILoadRestTool.d.ts +64 -0
  84. package/build/tools/generate-tests/generateUILoadRestTool.js +512 -0
  85. package/build/tools/generate-tests/generateUIRestTool.d.ts +6 -7
  86. package/build/tools/generate-tests/generateUIRestTool.js +1 -1
  87. package/build/tools/generate-tests/loadTestSchema.d.ts +15 -15
  88. package/build/tools/generate-tests/trace-reuse-guard.d.ts +1 -1
  89. package/build/tools/generateEnrichedIntegrationTestTool.d.ts +1 -2
  90. package/build/tools/generateEnrichedIntegrationTestTool.js +1 -1
  91. package/build/tools/localDevWorkerComposeTool.d.ts +1 -1
  92. package/build/tools/localDevWorkerComposeTool.js +2 -2
  93. package/build/tools/one-click/oneClickTool.d.ts +1 -1
  94. package/build/tools/one-click/oneClickTool.js +1 -1
  95. package/build/tools/preflightMockCheckTool.d.ts +1 -1
  96. package/build/tools/preflightMockCheckTool.js +3 -3
  97. package/build/tools/queryProxyMocksTool.d.ts +1 -1
  98. package/build/tools/queryProxyMocksTool.js +3 -3
  99. package/build/tools/submitReportTool.d.ts +111 -414
  100. package/build/tools/submitReportTool.js +154 -138
  101. package/build/tools/test-management/actionsTool.d.ts +1 -1
  102. package/build/tools/test-management/actionsTool.js +7 -7
  103. package/build/tools/test-management/analyzeChangesTool.d.ts +22 -118
  104. package/build/tools/test-management/analyzeChangesTool.js +4 -4
  105. package/build/tools/test-management/analyzeTestHealthTool.d.ts +1 -1
  106. package/build/tools/test-management/analyzeTestHealthTool.js +4 -4
  107. package/build/tools/test-management/registerTestPlanTool.d.ts +111 -743
  108. package/build/tools/test-management/registerTestPlanTool.js +20 -36
  109. package/build/tools/test-management/resolveScreenTool.d.ts +1 -1
  110. package/build/tools/test-management/resolveScreenTool.js +6 -2
  111. package/build/tools/trace/startTraceCollectionTool.d.ts +1 -1
  112. package/build/tools/trace/startTraceCollectionTool.js +4 -4
  113. package/build/tools/trace/stopTraceCollectionTool.d.ts +1 -1
  114. package/build/tools/trace/stopTraceCollectionTool.js +2 -2
  115. package/build/tools/verifyTestDependenciesTool.d.ts +1 -1
  116. package/build/tools/verifyTestDependenciesTool.js +1 -1
  117. package/build/tools/workspace/initScanWorkspaceTool.d.ts +1 -1
  118. package/build/tools/workspace/initScanWorkspaceTool.js +1 -1
  119. package/build/tools/workspace/initializeWorkspaceTool.d.ts +1 -1
  120. package/build/tools/workspace/initializeWorkspaceTool.js +1 -1
  121. package/build/types/RepositoryAnalysis.d.ts +164 -1170
  122. package/build/types/RepositoryAnalysis.js +12 -10
  123. package/build/types/StepMethod.d.ts +24 -1
  124. package/build/types/StepMethod.js +1 -1
  125. package/build/types/TestTypes.d.ts +34 -133
  126. package/build/types/TestTypes.js +3 -3
  127. package/build/types/TestbotReport.d.ts +37 -0
  128. package/build/types/TestbotReport.js +22 -0
  129. package/build/types/index.d.ts +1 -1
  130. package/build/types/index.js +1 -1
  131. package/build/utils/docker.d.ts +29 -7
  132. package/build/utils/docker.js +83 -27
  133. package/build/utils/initAgent.d.ts +3 -3
  134. package/build/utils/initAgent.js +58 -26
  135. package/build/utils/progress.d.ts +3 -4
  136. package/build/utils/progress.js +4 -4
  137. package/build/utils/utils.d.ts +1 -1
  138. package/build/utils/versions.d.ts +3 -3
  139. package/build/utils/versions.js +1 -1
  140. package/build/workspace/workspace.d.ts +117 -538
  141. package/build/workspace/workspace.js +2 -2
  142. package/package.json +6 -5
  143. package/plugin/prompts/testbot-task1.md +1 -1
  144. package/plugin/skills/repair-staged-files/SKILL.md +17 -0
  145. package/build/recommendation/blockerProbes.d.ts +0 -13
  146. package/build/recommendation/blockerProbes.js +0 -91
  147. package/build/recommendation/blockers.d.ts +0 -65
  148. package/build/recommendation/blockers.js +0 -135
@@ -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.nativeEnum(AnalysisScope);
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.union([z.record(z.any()), z.array(z.any())]).optional(),
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.ZodEffects<z.ZodEnum<["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS", "TRACE", "CONNECT", "assert", "click", "drag", "drag-hold", "hover", "inspect", "navigate", "press", "release", "tap", "type", "wait", "OPERATION"]>, "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS" | "type" | "TRACE" | "CONNECT" | "assert" | "click" | "drag" | "drag-hold" | "hover" | "inspect" | "navigate" | "press" | "release" | "tap" | "wait" | "OPERATION", unknown>;
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
- errorMap: () => ({ message: `method ${STEP_METHOD_HELP}` }),
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.ZodNativeEnum<typeof RuntimeEnvironment>;
55
- export declare const runtimeEnvironmentInputSchema: z.ZodEffects<z.ZodNativeEnum<typeof RuntimeEnvironment>, RuntimeEnvironment, unknown>;
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.ZodSchema>;
61
+ additionalFields?: Record<string, z.ZodType>;
62
62
  }
63
63
  export declare const languageSchema: z.ZodObject<{
64
- language: z.ZodNativeEnum<typeof ProgrammingLanguage>;
64
+ language: z.ZodEnum<typeof ProgrammingLanguage>;
65
65
  framework: z.ZodString;
66
- }, "strip", z.ZodTypeAny, {
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.ZodEffects<z.ZodNativeEnum<typeof RuntimeEnvironment>, RuntimeEnvironment, unknown>>;
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.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
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.ZodNativeEnum<typeof ProgrammingLanguage>;
84
+ language: z.ZodEnum<typeof ProgrammingLanguage>;
91
85
  framework: z.ZodString;
92
- }, "strip", z.ZodTypeAny, {
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<["", "hd", "full-hd", "2k"]>, z.ZodString]>>;
136
- browser: z.ZodDefault<z.ZodEnum<["chromium", "firefox", "webkit"]>>;
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
- }, "strip", z.ZodTypeAny, {
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.ZodEffects<z.ZodNativeEnum<typeof RuntimeEnvironment>, RuntimeEnvironment, unknown>>;
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.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
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.ZodNativeEnum<typeof ProgrammingLanguage>;
121
+ language: z.ZodEnum<typeof ProgrammingLanguage>;
171
122
  framework: z.ZodString;
172
123
  trace: z.ZodString;
173
- include: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
174
- exclude: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
175
- }, "strip", z.ZodTypeAny, {
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.ZodEffects<z.ZodNativeEnum<typeof RuntimeEnvironment>, RuntimeEnvironment, unknown>>;
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,27 @@ 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.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
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.ZodNativeEnum<typeof ProgrammingLanguage>;
144
+ language: z.ZodEnum<typeof ProgrammingLanguage>;
238
145
  framework: z.ZodString;
239
146
  endpointURL: z.ZodString;
240
- method: z.ZodDefault<z.ZodUnion<[z.ZodNativeEnum<typeof HttpMethod>, z.ZodLiteral<"">]>>;
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.ZodEffects<z.ZodDefault<z.ZodString>, string, string | undefined>;
246
- responseStatusCode: z.ZodEffects<z.ZodDefault<z.ZodString>, string, string | undefined>;
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
- }, "strip", z.ZodTypeAny, {
252
- codeReuse: boolean;
253
- modularizeCode: boolean;
254
- }, {
255
- codeReuse?: boolean | undefined;
256
- modularizeCode?: boolean | undefined;
257
- }>;
158
+ }, z.core.$strip>;
258
159
  /** The `testName` field for a recording-driven generation tool.
259
160
  *
260
161
  * Single-sourced because the description is prompt text: it is the only thing
@@ -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.nativeEnum(RuntimeEnvironment);
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
- .nativeEnum(ProgrammingLanguage)
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.nativeEnum(HttpMethod), z.literal("")])
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
@@ -13,6 +13,26 @@ export declare enum IssueFoundCategory {
13
13
  Type = "type",
14
14
  Config = "config"
15
15
  }
16
+ /** Why a Fail or Skipped testResults row did not pass. Application is the code
17
+ * under test (or a test written to prove a defect, failing as intended);
18
+ * Environment is the test environment stopping the test before it reached the
19
+ * behaviour; TestDefect is the generated test itself being wrong. */
20
+ export declare enum FailureCauseKind {
21
+ Application = "application",
22
+ Environment = "environment",
23
+ TestDefect = "test_defect"
24
+ }
25
+ /** Which test-environment gap stopped a test: the `family` of an Environment
26
+ * failureCause, and the `environmentFamily` of a config issuesFound entry. */
27
+ export declare enum EnvironmentFamily {
28
+ AuthToken = "auth_token",
29
+ Secret = "secret",
30
+ DataConnection = "data_connection",
31
+ AppNotStarted = "app_not_started",
32
+ Login = "login",
33
+ ExternalDependency = "external_dependency",
34
+ RecordingReplay = "recording_replay"
35
+ }
16
36
  /**
17
37
  * Shape of the JSON report written by skyramp_submit_report and read by testbot
18
38
  * for rendering as Markdown. All fields mirror the corresponding Zod schemas in
@@ -104,6 +124,19 @@ export interface TestbotReport {
104
124
  endpoint: string;
105
125
  status: "Pass" | "Fail" | "Skipped";
106
126
  details: string;
127
+ /** Server-derived: the basename of the `testFilePath` the agent submitted,
128
+ * which never reaches the report. The join key to `newTestsCreated` and
129
+ * `testMaintenance`: match it against the basename of their `fileName`
130
+ * (a `newTestsCreated` row may carry a repository-relative path), plus
131
+ * `repository`. */
132
+ fileName: string;
133
+ /** Why a Fail or Skipped row did not pass. The submit schema requires it on
134
+ * those rows and refuses it on a Pass row; `family` is set exactly when
135
+ * `kind` is Environment. Absent in reports from MCP versions predating it. */
136
+ failureCause?: {
137
+ kind: FailureCauseKind;
138
+ family?: EnvironmentFamily;
139
+ };
107
140
  videoPath?: string;
108
141
  /** See newTestsCreated[].repository. */
109
142
  repository: string;
@@ -158,6 +191,10 @@ export interface TestbotReport {
158
191
  sourceFile?: string;
159
192
  sourceSymbol?: string;
160
193
  sourceLine?: number;
194
+ /** On a `config` entry that is a test-environment gap, which gap. The submit
195
+ * schema refuses it on any other category. Optional: a config entry need
196
+ * not be an environment gap, and older MCP versions never set it. */
197
+ environmentFamily?: EnvironmentFamily;
161
198
  /** See newTestsCreated[].repository. */
162
199
  repository: string;
163
200
  }[];
@@ -8,3 +8,25 @@ export var IssueFoundCategory;
8
8
  IssueFoundCategory["Type"] = "type";
9
9
  IssueFoundCategory["Config"] = "config";
10
10
  })(IssueFoundCategory || (IssueFoundCategory = {}));
11
+ /** Why a Fail or Skipped testResults row did not pass. Application is the code
12
+ * under test (or a test written to prove a defect, failing as intended);
13
+ * Environment is the test environment stopping the test before it reached the
14
+ * behaviour; TestDefect is the generated test itself being wrong. */
15
+ export var FailureCauseKind;
16
+ (function (FailureCauseKind) {
17
+ FailureCauseKind["Application"] = "application";
18
+ FailureCauseKind["Environment"] = "environment";
19
+ FailureCauseKind["TestDefect"] = "test_defect";
20
+ })(FailureCauseKind || (FailureCauseKind = {}));
21
+ /** Which test-environment gap stopped a test: the `family` of an Environment
22
+ * failureCause, and the `environmentFamily` of a config issuesFound entry. */
23
+ export var EnvironmentFamily;
24
+ (function (EnvironmentFamily) {
25
+ EnvironmentFamily["AuthToken"] = "auth_token";
26
+ EnvironmentFamily["Secret"] = "secret";
27
+ EnvironmentFamily["DataConnection"] = "data_connection";
28
+ EnvironmentFamily["AppNotStarted"] = "app_not_started";
29
+ EnvironmentFamily["Login"] = "login";
30
+ EnvironmentFamily["ExternalDependency"] = "external_dependency";
31
+ EnvironmentFamily["RecordingReplay"] = "recording_replay";
32
+ })(EnvironmentFamily || (EnvironmentFamily = {}));
@@ -2,7 +2,7 @@ export { TestExecutionStatus } from "./TestExecution.js";
2
2
  export { DriftAction } from "./TestAnalysis.js";
3
3
  export { TestType, HttpMethod } from "./TestTypes.js";
4
4
  export type { TestbotReport } from "./TestbotReport.js";
5
- export { IssueFoundCategory } from "./TestbotReport.js";
5
+ export { IssueFoundCategory, FailureCauseKind, EnvironmentFamily, } from "./TestbotReport.js";
6
6
  export { ReuseDeclinedBy, ReuseVerificationOutcome, HelperVerificationOutcome, } from "./ReuseOutcome.js";
7
7
  export type { ReuseOutcome, ReuseSkippedEntry, ReuseMissedEntry, HelperReuseOutcome, RetrofitOutcome, ChangedHelperEntry, ChangedHelperCaller, OrphanedHelper, } from "./ReuseOutcome.js";
8
8
  export type { RelatedRepository, TestbotPromptOptions, } from "./TestbotPromptOptions.js";
@@ -1,5 +1,5 @@
1
1
  export { TestExecutionStatus } from "./TestExecution.js";
2
2
  export { DriftAction } from "./TestAnalysis.js";
3
3
  export { TestType, HttpMethod } from "./TestTypes.js";
4
- export { IssueFoundCategory } from "./TestbotReport.js";
4
+ export { IssueFoundCategory, FailureCauseKind, EnvironmentFamily, } from "./TestbotReport.js";
5
5
  export { ReuseDeclinedBy, ReuseVerificationOutcome, HelperVerificationOutcome, } from "./ReuseOutcome.js";
@@ -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
- * When `dockerPlatform` is provided, pulls with that exact platform — no
5
- * fallback logic runs. Use this for images whose platform is known ahead
6
- * of time (e.g. executor is amd64-only).
7
- *
8
- * When `dockerPlatform` is omitted, uses the host architecture and falls
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.
@@ -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
- * When `dockerPlatform` is provided, pulls with that exact platform — no
59
- * fallback logic runs. Use this for images whose platform is known ahead
60
- * of time (e.g. executor is amd64-only).
61
- *
62
- * When `dockerPlatform` is omitted, uses the host architecture and falls
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
- if (dockerPlatform) {
69
- await doPull(client, imageName, dockerPlatform);
70
- return;
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
- const platform = getDockerPlatform();
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
- await doPull(client, imageName, platform);
141
+ const info = (await new Dockerode().info());
142
+ return info?.OSType;
75
143
  }
76
144
  catch (err) {
77
- if (platform === "linux/arm64" && isManifestMismatchError(err)) {
78
- logger.info("arm64 pull failed, retrying with linux/amd64 (emulation on Apple Silicon)", { image: imageName });
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
  /**