@skyramp/mcp 0.4.1 → 0.4.2-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (543) hide show
  1. package/build/adapters/jestAdapter.js +23 -5
  2. package/build/adapters/mochaAdapter.js +7 -1
  3. package/build/adapters/playwrightAdapter.js +3 -1
  4. package/build/adapters/pytestAdapter.js +14 -3
  5. package/build/commands/localDevTestChangesCommand.js +1 -0
  6. package/build/commands/recommendTestsAndExecuteCommand.js +5 -6
  7. package/build/commands/testThisEndpointCommand.js +16 -4
  8. package/build/index.js +34 -4
  9. package/build/playwright/blueprintDigest.js +28 -7
  10. package/build/playwright/registerPlaywrightTools.js +33 -28
  11. package/build/playwright/traceRecordingPrompt.js +9 -2
  12. package/build/prompts/code-reuse.js +95 -29
  13. package/build/prompts/fix-error-prompt.d.ts +9 -1
  14. package/build/prompts/fix-error-prompt.js +31 -28
  15. package/build/prompts/local-dev/local-dev-plan.d.ts +3 -0
  16. package/build/prompts/local-dev/local-dev-plan.js +3 -1
  17. package/build/prompts/local-dev/local-dev-prompts.d.ts +1 -1
  18. package/build/prompts/local-dev/local-dev-prompts.js +30 -3
  19. package/build/prompts/modularization/integration-test-modularization.js +13 -6
  20. package/build/prompts/modularization/ui-test-modularization.js +1 -1
  21. package/build/prompts/personas.js +1 -1
  22. package/build/prompts/pom-aware-code-reuse.js +7 -9
  23. package/build/prompts/reuse-hand-off.d.ts +64 -0
  24. package/build/prompts/reuse-hand-off.js +130 -0
  25. package/build/prompts/shared-helper-policy.d.ts +88 -2
  26. package/build/prompts/shared-helper-policy.js +145 -11
  27. package/build/prompts/sut-setup/modes/adaptWorkflowPrompt.js +1 -1
  28. package/build/prompts/sut-setup/modes/dockerComposePrompt.js +1 -1
  29. package/build/prompts/sut-setup/shared.d.ts +4 -1
  30. package/build/prompts/sut-setup/shared.js +2 -2
  31. package/build/prompts/test-maintenance/actionsInstructions.d.ts +19 -11
  32. package/build/prompts/test-maintenance/actionsInstructions.js +47 -26
  33. package/build/prompts/test-maintenance/drift-analysis-prompt.js +3 -2
  34. package/build/prompts/test-maintenance/driftAnalysisSections.js +5 -3
  35. package/build/prompts/test-maintenance/driftAnalysisShared.js +4 -2
  36. package/build/prompts/test-maintenance/uiDriftAnalysisSections.js +7 -4
  37. package/build/prompts/test-recommendation/recommendationSections.js +19 -8
  38. package/build/prompts/test-recommendation/registerRecommendTestsPrompt.js +5 -2
  39. package/build/prompts/test-recommendation/test-recommendation-prompt.js +10 -7
  40. package/build/prompts/testbot/testbot-prompts.js +123 -55
  41. package/build/recommendation/answers.js +18 -9
  42. package/build/recommendation/pullRequestText.js +1 -1
  43. package/build/recommendation/registerPlan.js +31 -17
  44. package/build/recommendation/subjectStep.d.ts +8 -10
  45. package/build/recommendation/subjectStep.js +17 -16
  46. package/build/recommendation/types.d.ts +71 -17
  47. package/build/recommendation/types.js +9 -15
  48. package/build/recommendation/verifierContracts.d.ts +7 -3
  49. package/build/recommendation/verifierContracts.js +8 -4
  50. package/build/recommendation/verifiers/changedFile.js +11 -13
  51. package/build/recommendation/verifiers/citedPath.d.ts +8 -0
  52. package/build/recommendation/verifiers/citedPath.js +16 -2
  53. package/build/recommendation/verifiers/coverage.d.ts +2 -2
  54. package/build/recommendation/verifiers/coverage.js +190 -134
  55. package/build/recommendation/verifiers/defects.js +56 -16
  56. package/build/recommendation/verifiers/deliveredMatchesPlan.d.ts +7 -1
  57. package/build/recommendation/verifiers/deliveredMatchesPlan.js +28 -14
  58. package/build/recommendation/verifiers/endpointGrounded.js +14 -8
  59. package/build/recommendation/verifiers/existingCoverage.d.ts +6 -0
  60. package/build/recommendation/verifiers/existingCoverage.js +30 -21
  61. package/build/recommendation/verifiers/expectedOutcome.js +17 -8
  62. package/build/recommendation/verifiers/expectedValueSourced.js +54 -43
  63. package/build/recommendation/verifiers/issueTraceability.d.ts +5 -0
  64. package/build/recommendation/verifiers/issueTraceability.js +64 -7
  65. package/build/recommendation/verifiers/removedElementGuarded.js +19 -11
  66. package/build/recommendation/verifiers/reportedCategory.js +9 -4
  67. package/build/recommendation/verifiers/requirementSourced.js +34 -21
  68. package/build/recommendation/verifiers/screenRoute.js +15 -10
  69. package/build/recommendation/verifiers/statedDifference.js +15 -8
  70. package/build/recommendation/verifiers/uiElementGrounded.js +50 -16
  71. package/build/resources/analysisResources.js +7 -3
  72. package/build/resources/progressResource.js +4 -2
  73. package/build/resources/sutSetupResource.js +20 -2
  74. package/build/resources/testbotResource.js +19 -1
  75. package/build/services/AnalyticsService.js +3 -1
  76. package/build/services/ScenarioGenerationService.js +5 -5
  77. package/build/services/TestDiscoveryService.js +21 -5
  78. package/build/services/TestExecutionService.js +63 -21
  79. package/build/services/TestGenerationService.d.ts +1 -1
  80. package/build/services/TestGenerationService.js +43 -24
  81. package/build/skills/enhanceAssertionsSkill.d.ts +45 -0
  82. package/build/skills/enhanceAssertionsSkill.js +103 -0
  83. package/build/skills/fixTestImportErrorsSkill.d.ts +2 -2
  84. package/build/skills/fixTestImportErrorsSkill.js +2 -2
  85. package/build/skills/skillFiles.d.ts +38 -0
  86. package/build/skills/skillFiles.js +94 -0
  87. package/build/skills/validateAssertionAlignmentSkill.d.ts +34 -0
  88. package/build/skills/validateAssertionAlignmentSkill.js +59 -0
  89. package/build/tool-phases.js +4 -0
  90. package/build/tools/auth/loginTool.js +3 -1
  91. package/build/tools/auth/logoutTool.js +3 -1
  92. package/build/tools/code-refactor/alignAssertionsTool.d.ts +2 -0
  93. package/build/tools/code-refactor/alignAssertionsTool.js +51 -0
  94. package/build/tools/code-refactor/assertion-state.d.ts +1 -1
  95. package/build/tools/code-refactor/assertion-state.js +1 -1
  96. package/build/tools/code-refactor/assertionOperations.d.ts +44 -0
  97. package/build/tools/code-refactor/assertionOperations.js +82 -0
  98. package/build/tools/code-refactor/assertionSkillTools.d.ts +3 -0
  99. package/build/tools/code-refactor/assertionSkillTools.js +86 -0
  100. package/build/tools/code-refactor/codeReuseTool.js +27 -3
  101. package/build/tools/code-refactor/enhanceAssertionsTool.js +19 -83
  102. package/build/tools/code-refactor/gate-markers.d.ts +51 -0
  103. package/build/tools/code-refactor/gate-markers.js +95 -0
  104. package/build/tools/code-refactor/retrofit-state.d.ts +3 -1
  105. package/build/tools/code-refactor/retrofit-state.js +44 -2
  106. package/build/tools/code-refactor/reuse-outcome.d.ts +23 -1
  107. package/build/tools/code-refactor/reuse-outcome.js +36 -13
  108. package/build/tools/code-refactor/reuse-state.d.ts +90 -16
  109. package/build/tools/code-refactor/reuse-state.js +191 -61
  110. package/build/tools/code-refactor/utils-verify-gates.d.ts +4 -0
  111. package/build/tools/code-refactor/utils-verify-gates.js +252 -27
  112. package/build/tools/code-refactor/verify-gates.d.ts +15 -1
  113. package/build/tools/code-refactor/verify-gates.js +36 -4
  114. package/build/tools/enrichTestWithMocksTool.d.ts +1 -1
  115. package/build/tools/enrichTestWithMocksTool.js +9 -5
  116. package/build/tools/executeSkyrampTestTool.d.ts +22 -1
  117. package/build/tools/executeSkyrampTestTool.js +571 -271
  118. package/build/tools/execution-video-state.js +1 -1
  119. package/build/tools/fixErrorTool.js +5 -6
  120. package/build/tools/generate-tests/batchMockGenerationTool.js +1 -1
  121. package/build/tools/generate-tests/generateBatchScenarioRestTool.js +114 -73
  122. package/build/tools/generate-tests/generateContractRestTool.js +34 -16
  123. package/build/tools/generate-tests/generateE2ERestTool.d.ts +1 -0
  124. package/build/tools/generate-tests/generateE2ERestTool.js +9 -1
  125. package/build/tools/generate-tests/generateIntegrationRestTool.js +22 -7
  126. package/build/tools/generate-tests/generateMockRestTool.js +3 -1
  127. package/build/tools/generate-tests/generateUIRestTool.d.ts +2 -0
  128. package/build/tools/generate-tests/generateUIRestTool.js +11 -2
  129. package/build/tools/generate-tests/loadTestSchema.js +1 -3
  130. package/build/tools/generate-tests/planGuard.js +6 -3
  131. package/build/tools/generate-tests/scenarioFileIdentity.js +4 -1
  132. package/build/tools/generate-tests/scenarioLint.js +17 -5
  133. package/build/tools/generate-tests/trace-reuse-guard.js +5 -2
  134. package/build/tools/generateEnrichedIntegrationTestTool.js +9 -3
  135. package/build/tools/one-click/oneClickTool.js +3 -1
  136. package/build/tools/preflightMockCheckTool.js +23 -7
  137. package/build/tools/runExistingTestsTool.d.ts +1 -1
  138. package/build/tools/runExistingTestsTool.js +43 -21
  139. package/build/tools/submitReportTool.d.ts +51 -12
  140. package/build/tools/submitReportTool.js +860 -161
  141. package/build/tools/test-management/actionsTool.js +210 -51
  142. package/build/tools/test-management/analyzeChangesTool.d.ts +4 -5
  143. package/build/tools/test-management/analyzeChangesTool.js +127 -68
  144. package/build/tools/test-management/analyzeTestHealthTool.js +35 -13
  145. package/build/tools/test-management/registerTestPlanTool.d.ts +44 -34
  146. package/build/tools/test-management/registerTestPlanTool.js +255 -111
  147. package/build/tools/test-management/resolveScreenTool.js +33 -9
  148. package/build/tools/trace/startTraceCollectionTool.js +3 -1
  149. package/build/tools/trace/stopTraceCollectionTool.js +41 -5
  150. package/build/tools/verifyTestDependenciesTool.d.ts +3 -0
  151. package/build/tools/verifyTestDependenciesTool.js +54 -0
  152. package/build/tools/workspace/initScanWorkspaceTool.js +9 -3
  153. package/build/tools/workspace/initializeWorkspaceTool.js +3 -1
  154. package/build/types/AssertionOutcome.d.ts +1 -1
  155. package/build/types/EnhanceType.d.ts +6 -0
  156. package/build/types/EnhanceType.js +1 -0
  157. package/build/types/ExternalTestExecution.d.ts +2 -2
  158. package/build/types/RepositoryAnalysis.d.ts +0 -40
  159. package/build/types/ReuseOutcome.d.ts +96 -4
  160. package/build/types/ReuseOutcome.js +16 -0
  161. package/build/types/StepMethod.js +20 -6
  162. package/build/types/TestAnalysis.d.ts +10 -2
  163. package/build/types/TestExecution.d.ts +45 -0
  164. package/build/types/TestRecommendation.d.ts +1 -1
  165. package/build/types/TestRecommendation.js +4 -1
  166. package/build/types/TestTypes.d.ts +13 -0
  167. package/build/types/TestTypes.js +34 -3
  168. package/build/types/TestbotPromptOptions.d.ts +9 -1
  169. package/build/types/TestbotReport.d.ts +45 -9
  170. package/build/utils/AnalysisStateManager.d.ts +137 -27
  171. package/build/utils/AnalysisStateManager.js +227 -43
  172. package/build/utils/assertion-verify/api-shared-lints.js +34 -16
  173. package/build/utils/assertion-verify/metrics.js +39 -6
  174. package/build/utils/assertion-verify/ui-lints.js +4 -2
  175. package/build/utils/branchDiff.js +47 -12
  176. package/build/utils/canonicalJson.js +3 -1
  177. package/build/utils/dartRouteExtractor.js +36 -7
  178. package/build/utils/fixAttempts.d.ts +26 -0
  179. package/build/utils/fixAttempts.js +109 -0
  180. package/build/utils/frontendSelectors.js +23 -4
  181. package/build/utils/generatedTestRecord.d.ts +19 -0
  182. package/build/utils/generatedTestRecord.js +61 -0
  183. package/build/utils/gitStaging.js +7 -2
  184. package/build/utils/initAgent.js +26 -6
  185. package/build/utils/language-helper.js +39 -45
  186. package/build/utils/pathMatching.js +2 -1
  187. package/build/utils/pathSignatures.js +6 -2
  188. package/build/utils/planMatchKeys.d.ts +2 -2
  189. package/build/utils/planMatchKeys.js +20 -14
  190. package/build/utils/pom-catalog-parse.js +7 -2
  191. package/build/utils/pom-scope/import-expansion.js +6 -1
  192. package/build/utils/pom-scope/index.js +50 -12
  193. package/build/utils/pom-scope/scoring.js +13 -3
  194. package/build/utils/pom-scope/selector-extractor.js +16 -3
  195. package/build/utils/pom-scope/strip.d.ts +8 -0
  196. package/build/utils/pom-scope/strip.js +238 -0
  197. package/build/utils/pom-scope/testIdDiscovery.js +14 -2
  198. package/build/utils/pom-verify/__fixtures__/af-style/asset-list.page.d.ts +1 -1
  199. package/build/utils/pom-verify/__fixtures__/af-style/asset-list.page.js +4 -2
  200. package/build/utils/pom-verify/__fixtures__/af-style/report.iframe.page.js +3 -1
  201. package/build/utils/pom-verify/__fixtures__/af-style/workflow-footer.page.js +3 -1
  202. package/build/utils/pom-verify/bindings.js +5 -1
  203. package/build/utils/pom-verify/calls.js +9 -2
  204. package/build/utils/pom-verify/verify.js +27 -5
  205. package/build/utils/pr-comment-parser.js +20 -7
  206. package/build/utils/proxy-terminal.d.ts +19 -1
  207. package/build/utils/proxy-terminal.js +346 -21
  208. package/build/utils/removedUiElements.js +1 -1
  209. package/build/utils/reportLanguage.js +35 -7
  210. package/build/utils/reportVerification.d.ts +14 -8
  211. package/build/utils/reportVerification.js +19 -19
  212. package/build/utils/repositorySlug.d.ts +32 -0
  213. package/build/utils/repositorySlug.js +77 -0
  214. package/build/utils/reuseRouting.js +6 -2
  215. package/build/utils/runSerialized.d.ts +3 -0
  216. package/build/utils/runSerialized.js +39 -0
  217. package/build/utils/screenRoutes.js +74 -18
  218. package/build/utils/sourceRouteExtractor.js +13 -6
  219. package/build/utils/telemetry.d.ts +1 -0
  220. package/build/utils/telemetry.js +8 -5
  221. package/build/utils/testDependencyPolicy.d.ts +9 -0
  222. package/build/utils/testDependencyPolicy.js +788 -0
  223. package/build/utils/testExecutionRecord.d.ts +90 -0
  224. package/build/utils/testExecutionRecord.js +267 -0
  225. package/build/utils/testFileClassification.js +3 -1
  226. package/build/utils/trace-parser.js +62 -14
  227. package/build/utils/urlPath.js +3 -1
  228. package/build/utils/utils-verify/action-key.d.ts +4 -0
  229. package/build/utils/utils-verify/action-key.js +2 -2
  230. package/build/utils/utils-verify/allow.d.ts +122 -3
  231. package/build/utils/utils-verify/allow.js +146 -21
  232. package/build/utils/utils-verify/body-reach.d.ts +120 -0
  233. package/build/utils/utils-verify/body-reach.js +335 -0
  234. package/build/utils/utils-verify/call-sites.d.ts +6 -1
  235. package/build/utils/utils-verify/call-sites.js +72 -8
  236. package/build/utils/utils-verify/delivered-imports.d.ts +43 -0
  237. package/build/utils/utils-verify/delivered-imports.js +84 -0
  238. package/build/utils/utils-verify/fixed-sleep.d.ts +96 -0
  239. package/build/utils/utils-verify/fixed-sleep.js +461 -0
  240. package/build/utils/utils-verify/in-house.d.ts +93 -0
  241. package/build/utils/utils-verify/in-house.js +719 -0
  242. package/build/utils/utils-verify/incumbent.d.ts +3 -0
  243. package/build/utils/utils-verify/incumbent.js +75 -0
  244. package/build/utils/utils-verify/index.d.ts +1 -0
  245. package/build/utils/utils-verify/index.js +1 -0
  246. package/build/utils/utils-verify/language-spec.d.ts +26 -10
  247. package/build/utils/utils-verify/language-spec.js +217 -20
  248. package/build/utils/utils-verify/locate.d.ts +26 -0
  249. package/build/utils/utils-verify/locate.js +125 -23
  250. package/build/utils/utils-verify/module-name.d.ts +40 -0
  251. package/build/utils/utils-verify/module-name.js +98 -0
  252. package/build/utils/utils-verify/parse.d.ts +46 -6
  253. package/build/utils/utils-verify/parse.js +176 -38
  254. package/build/utils/utils-verify/retrofit-equivalence.d.ts +5 -0
  255. package/build/utils/utils-verify/retrofit-equivalence.js +4 -2
  256. package/build/utils/utils-verify/stage.d.ts +5 -0
  257. package/build/utils/utils-verify/stage.js +47 -2
  258. package/build/utils/utils-verify/status-once.d.ts +62 -0
  259. package/build/utils/utils-verify/status-once.js +207 -0
  260. package/build/utils/utils-verify/typecheck.d.ts +61 -0
  261. package/build/utils/utils-verify/typecheck.js +338 -0
  262. package/build/utils/utils-verify/verify.d.ts +76 -1
  263. package/build/utils/utils-verify/verify.js +516 -44
  264. package/build/utils/versions.d.ts +3 -3
  265. package/build/utils/versions.js +1 -1
  266. package/build/utils/workspaceAuth.js +107 -37
  267. package/build/workspace/queryParamResolution.js +11 -4
  268. package/build/workspace/workspace.js +7 -7
  269. package/node_modules/playwright/ThirdPartyNotices.txt +19 -19
  270. package/node_modules/playwright/lib/mcp/skyramp/assertTool.js +8 -2
  271. package/node_modules/playwright/lib/mcp/skyramp/common/cssValue.js +87 -0
  272. package/node_modules/playwright/lib/mcp/skyramp/loadTraceTool.js +31 -0
  273. package/node_modules/playwright/lib/mcp/skyramp/skyRampImport.js +3 -0
  274. package/node_modules/playwright/lib/mcp/skyramp/traceRecordingBackend.js +181 -15
  275. package/node_modules/playwright/lib/mcp/test/skyRampExport.js +24 -0
  276. package/node_modules/playwright/lib/transform/babelBundleImpl.js +2353 -190
  277. package/node_modules/playwright/node_modules/playwright-core/ThirdPartyNotices.txt +62 -34
  278. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/.package-lock.json +72 -41
  279. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/@hono/node-server/dist/serve-static.js +1 -1
  280. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/@hono/node-server/dist/serve-static.mjs +1 -1
  281. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/@hono/node-server/package.json +2 -2
  282. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/README.md +16 -1
  283. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/index.js +4 -20
  284. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/lib/read.js +17 -17
  285. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/lib/types/json.js +60 -32
  286. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/lib/types/raw.js +3 -3
  287. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/lib/types/text.js +3 -3
  288. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/lib/types/urlencoded.js +16 -20
  289. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/lib/utils.js +18 -16
  290. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/node_modules/content-type/LICENSE +22 -0
  291. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/node_modules/content-type/README.md +71 -0
  292. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/node_modules/content-type/dist/index.d.ts +46 -0
  293. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/node_modules/content-type/dist/index.js +176 -0
  294. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/node_modules/content-type/dist/index.js.map +1 -0
  295. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/node_modules/content-type/package.json +52 -0
  296. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/package.json +23 -10
  297. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/es-object-atoms/CHANGELOG.md +21 -14
  298. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/es-object-atoms/isObject.d.ts +1 -1
  299. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/es-object-atoms/package.json +6 -7
  300. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/es-object-atoms/tsconfig.json +1 -0
  301. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/index.js +266 -45
  302. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/lib/schemes.js +9 -4
  303. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/lib/utils.js +396 -92
  304. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/package.json +1 -1
  305. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/component-safe-serialization.test.js +163 -0
  306. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/equal.test.js +31 -3
  307. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/fixtures/uri-js-parse.json +2 -0
  308. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/ipv6-canonical.test.js +34 -0
  309. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/ipv6-validation.test.js +124 -0
  310. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/malformed-percent.test.js +77 -0
  311. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/malformed-urn.test.js +61 -0
  312. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/parse.test.js +7 -3
  313. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/query-fragment-normalization.test.js +33 -0
  314. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/reserved-path-normalization.test.js +109 -0
  315. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/scheme-validation.test.js +124 -0
  316. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/security-normalization.test.js +101 -0
  317. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/security.test.js +301 -3
  318. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/urn-full-input.test.js +29 -0
  319. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/websocket-query-preservation.test.js +24 -0
  320. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hasown/CHANGELOG.md +7 -0
  321. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hasown/index.d.ts +0 -1
  322. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hasown/package.json +4 -5
  323. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/client/client.js +30 -16
  324. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/client/utils.js +4 -1
  325. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/context.js +32 -13
  326. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/helper/accepts/accepts.js +36 -2
  327. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/helper/proxy/index.js +4 -0
  328. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/helper/ssg/ssg.js +1 -1
  329. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/helper/ssg/utils.js +30 -10
  330. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/helper/streaming/sse.js +5 -4
  331. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/hono-base.js +10 -8
  332. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/jsx/base.js +44 -23
  333. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/jsx/components.js +25 -26
  334. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/jsx/context.js +5 -5
  335. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/jsx/dom/render.js +2 -0
  336. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/jsx/dom/server.js +5 -1
  337. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/jsx/hooks/index.js +16 -13
  338. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/jsx/intrinsic-element/components.js +3 -3
  339. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/jsx/streaming.js +4 -5
  340. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/cache/index.js +103 -8
  341. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/compress/index.js +5 -0
  342. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/cors/index.js +17 -14
  343. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/csrf/index.js +1 -1
  344. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/etag/digest.js +47 -1
  345. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/etag/index.js +7 -4
  346. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/jwk/jwk.js +9 -4
  347. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/jwt/jwt.js +9 -4
  348. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/language/language.js +10 -6
  349. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/method-not-allowed/index.js +90 -0
  350. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/pretty-json/index.js +3 -1
  351. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/secure-headers/secure-headers.js +16 -7
  352. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/request.js +20 -13
  353. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/router/linear-router/router.js +7 -2
  354. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/router/pattern-router/router.js +3 -9
  355. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/router/reg-exp-router/node.js +65 -59
  356. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/router/reg-exp-router/router.js +71 -128
  357. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/router/reg-exp-router/trie.js +14 -5
  358. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/router/trie-router/node.js +47 -70
  359. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/router/trie-router/router.js +3 -11
  360. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/router/utils.js +27 -0
  361. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/router.js +1 -1
  362. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/utils/accept.js +1 -1
  363. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/utils/body.js +21 -3
  364. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/utils/cookie.js +4 -3
  365. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/utils/ipaddr.js +5 -3
  366. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/utils/stream.js +12 -3
  367. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/utils/url.js +19 -11
  368. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/client/client.js +30 -16
  369. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/client/utils.js +4 -1
  370. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/context.js +32 -13
  371. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/helper/accepts/accepts.js +36 -2
  372. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/helper/proxy/index.js +4 -0
  373. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/helper/ssg/ssg.js +1 -1
  374. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/helper/ssg/utils.js +30 -10
  375. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/helper/streaming/sse.js +5 -4
  376. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/hono-base.js +10 -8
  377. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/jsx/base.js +41 -23
  378. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/jsx/components.js +26 -27
  379. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/jsx/context.js +6 -6
  380. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/jsx/dom/render.js +2 -0
  381. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/jsx/dom/server.js +5 -1
  382. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/jsx/hooks/index.js +16 -13
  383. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/jsx/intrinsic-element/components.js +4 -4
  384. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/jsx/streaming.js +5 -6
  385. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/cache/index.js +103 -8
  386. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/compress/index.js +5 -0
  387. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/cors/index.js +17 -14
  388. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/csrf/index.js +1 -1
  389. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/etag/digest.js +47 -1
  390. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/etag/index.js +7 -4
  391. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/jwk/jwk.js +9 -4
  392. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/jwt/jwt.js +9 -4
  393. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/language/language.js +10 -6
  394. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/method-not-allowed/index.js +68 -0
  395. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/pretty-json/index.js +3 -1
  396. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/secure-headers/secure-headers.js +16 -7
  397. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/request.js +21 -14
  398. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/router/linear-router/router.js +7 -2
  399. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/router/pattern-router/router.js +3 -9
  400. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/router/reg-exp-router/node.js +61 -58
  401. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/router/reg-exp-router/router.js +77 -129
  402. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/router/reg-exp-router/trie.js +14 -5
  403. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/router/trie-router/node.js +47 -70
  404. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/router/trie-router/router.js +3 -11
  405. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/router/utils.js +5 -0
  406. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/router.js +1 -1
  407. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/adapter/aws-lambda/types.d.ts +9 -0
  408. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/client/types.d.ts +1 -1
  409. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/context.d.ts +6 -2
  410. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/hono-base.d.ts +4 -3
  411. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/jsx/base.d.ts +7 -2
  412. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/jsx/dom/index.d.ts +5 -5
  413. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/jsx/dom/intrinsic-element/components.d.ts +2 -2
  414. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/jsx/dom/server.d.ts +5 -5
  415. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/jsx/hooks/index.d.ts +8 -6
  416. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/jsx/index.d.ts +5 -5
  417. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/middleware/cache/index.d.ts +6 -4
  418. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/middleware/combine/index.d.ts +1 -1
  419. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/middleware/cors/index.d.ts +1 -1
  420. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/middleware/jsx-renderer/index.d.ts +2 -2
  421. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/middleware/jwk/jwk.d.ts +2 -0
  422. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/middleware/jwt/jwt.d.ts +2 -0
  423. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/middleware/method-not-allowed/index.d.ts +49 -0
  424. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/middleware/secure-headers/permissions-policy.d.ts +3 -3
  425. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/router/reg-exp-router/node.d.ts +4 -1
  426. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/router/reg-exp-router/trie.d.ts +2 -1
  427. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/router/trie-router/node.d.ts +1 -2
  428. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/router/trie-router/router.d.ts +0 -1
  429. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/router/utils.d.ts +1 -0
  430. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/router.d.ts +1 -1
  431. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/utils/headers.d.ts +2 -2
  432. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/utils/url.d.ts +5 -0
  433. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/utils/accept.js +1 -1
  434. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/utils/body.js +21 -3
  435. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/utils/cookie.js +5 -4
  436. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/utils/ipaddr.js +5 -3
  437. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/utils/stream.js +12 -3
  438. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/utils/url.js +17 -10
  439. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/package.json +11 -4
  440. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/README.md +173 -143
  441. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/address-error.d.ts +11 -0
  442. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/address-error.js.map +1 -1
  443. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/common.d.ts +49 -0
  444. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/common.js +79 -4
  445. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/common.js.map +1 -1
  446. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/ipv4.d.ts +78 -5
  447. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/ipv4.js +119 -24
  448. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/ipv4.js.map +1 -1
  449. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/ipv6.d.ts +151 -10
  450. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/ipv6.js +316 -90
  451. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/ipv6.js.map +1 -1
  452. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/v4/constants.d.ts +12 -0
  453. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/v4/constants.js +45 -2
  454. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/v4/constants.js.map +1 -1
  455. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/v6/constants.d.ts +14 -0
  456. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/v6/constants.js +50 -3
  457. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/v6/constants.js.map +1 -1
  458. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/package.json +6 -4
  459. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/.github/THREAT_MODEL.md +3 -3
  460. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/CHANGELOG.md +26 -0
  461. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/README.md +19 -1
  462. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/dist/qs.js +25 -25
  463. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/eslint.config.mjs +1 -1
  464. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/lib/parse.js +16 -6
  465. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/lib/stringify.js +23 -8
  466. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/lib/utils.js +57 -11
  467. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/package.json +8 -7
  468. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/test/parse.js +419 -0
  469. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/test/stringify.js +317 -0
  470. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/test/utils.js +206 -0
  471. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/side-channel/CHANGELOG.md +10 -0
  472. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/side-channel/README.md +1 -1
  473. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/side-channel/index.js +5 -2
  474. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/side-channel/package.json +10 -10
  475. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/side-channel/test/index.js +16 -0
  476. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/type-is/index.js +8 -18
  477. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/type-is/node_modules/content-type/LICENSE +22 -0
  478. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/type-is/node_modules/content-type/README.md +71 -0
  479. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/type-is/node_modules/content-type/dist/index.d.ts +46 -0
  480. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/type-is/node_modules/content-type/dist/index.js +176 -0
  481. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/type-is/node_modules/content-type/dist/index.js.map +1 -0
  482. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/type-is/node_modules/content-type/package.json +52 -0
  483. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/type-is/package.json +9 -5
  484. package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/package-lock.json +72 -41
  485. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/.package-lock.json +6 -6
  486. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/brace-expansion/README.md +23 -1
  487. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/brace-expansion/index.js +265 -86
  488. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/brace-expansion/package.json +1 -1
  489. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/README.md +173 -143
  490. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/address-error.d.ts +11 -0
  491. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/address-error.js.map +1 -1
  492. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/common.d.ts +49 -0
  493. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/common.js +79 -4
  494. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/common.js.map +1 -1
  495. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/ipv4.d.ts +78 -5
  496. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/ipv4.js +119 -24
  497. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/ipv4.js.map +1 -1
  498. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/ipv6.d.ts +151 -10
  499. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/ipv6.js +316 -90
  500. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/ipv6.js.map +1 -1
  501. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/v4/constants.d.ts +12 -0
  502. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/v4/constants.js +45 -2
  503. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/v4/constants.js.map +1 -1
  504. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/v6/constants.d.ts +14 -0
  505. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/v6/constants.js +50 -3
  506. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/v6/constants.js.map +1 -1
  507. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/package.json +6 -4
  508. package/node_modules/playwright/node_modules/playwright-core/bundles/utils/package-lock.json +6 -6
  509. package/node_modules/playwright/node_modules/playwright-core/lib/cli/program.js +18 -9
  510. package/node_modules/playwright/node_modules/playwright-core/lib/mcpBundleImpl/index.js +47 -47
  511. package/node_modules/playwright/node_modules/playwright-core/lib/server/codegen/skyramp/jsonlReader.js +3 -0
  512. package/node_modules/playwright/node_modules/playwright-core/lib/server/recorder/recorderRunner.js +42 -0
  513. package/node_modules/playwright/node_modules/playwright-core/lib/utilsBundleImpl/index.js +121 -121
  514. package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/{index.B7KbSQcC.js → index.BAkLd5DX.js} +1 -1
  515. package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/index.html +1 -1
  516. package/node_modules/playwright/node_modules/playwright-core/package.json +1 -1
  517. package/node_modules/playwright/node_modules/playwright-core/src/cli/program.ts +31 -9
  518. package/node_modules/playwright/node_modules/playwright-core/src/server/codegen/skyramp/jsonlReader.ts +1 -0
  519. package/node_modules/playwright/node_modules/playwright-core/src/server/recorder/recorderRunner.ts +57 -1
  520. package/node_modules/playwright/package.json +2 -2
  521. package/package.json +7 -6
  522. package/plugin/prompts/code-reuse/hand-off.md +30 -0
  523. package/plugin/prompts/generate-tests/generation.md +1 -1
  524. package/plugin/prompts/plan-tests.md +14 -14
  525. package/plugin/prompts/testbot-task1.md +4 -2
  526. package/plugin/skills/enhance-assertions/SKILL.md +25 -0
  527. package/plugin/skills/enhance-assertions/reference/contract.md +51 -0
  528. package/plugin/skills/enhance-assertions/reference/integration.md +58 -0
  529. package/plugin/skills/enhance-assertions/reference/shared-rules.md +220 -0
  530. package/plugin/skills/enhance-assertions/reference/ui.md +373 -0
  531. package/plugin/skills/fix-test-import-errors/SKILL.md +44 -50
  532. package/plugin/skills/validate-assertion-alignment-post-execution/SKILL.md +32 -0
  533. package/plugin/skills/validate-assertion-alignment-post-execution/reference/checks.md +44 -0
  534. package/plugin/skills/validate-assertion-alignment-post-execution/reference/evidence.md +47 -0
  535. package/build/prompts/enhance-assertions/contractProviderAssertionsPrompt.d.ts +0 -2
  536. package/build/prompts/enhance-assertions/contractProviderAssertionsPrompt.js +0 -29
  537. package/build/prompts/enhance-assertions/integrationAssertionsPrompt.d.ts +0 -2
  538. package/build/prompts/enhance-assertions/integrationAssertionsPrompt.js +0 -36
  539. package/build/prompts/enhance-assertions/sharedAssertionRules.d.ts +0 -16
  540. package/build/prompts/enhance-assertions/sharedAssertionRules.js +0 -284
  541. package/build/prompts/enhance-assertions/uiAssertionsPrompt.d.ts +0 -2
  542. package/build/prompts/enhance-assertions/uiAssertionsPrompt.js +0 -388
  543. package/node_modules/playwright/node_modules/playwright-core/.DS_Store +0 -0
@@ -0,0 +1,130 @@
1
+ /**
2
+ * The modularize → reuse hand-off, shared by the two places that arm the chain:
3
+ * generation (TestGenerationService, for the files a codeReuse call wrote) and
4
+ * maintenance (skyramp_actions, for a test it updates or regenerates). One
5
+ * predicate decides whether a file owes the pair, and one builder produces the
6
+ * next-steps text, so the two callers cannot drift on either.
7
+ */
8
+ import { isUtilsReuseEnabled } from "../utils/featureFlags.js";
9
+ import { fillPlaceholders } from "../recommendation/verifierContracts.js";
10
+ import { readPromptAsset, sectionBody } from "./promptAssets.js";
11
+ import { isBrowserTestType, isModularizeFirstTarget, } from "../utils/reuseRouting.js";
12
+ import { utilsSpecFor, } from "../utils/utils-verify/index.js";
13
+ import { enhanceAssertionsCall } from "../skills/enhanceAssertionsSkill.js";
14
+ /** Why Java generation never asks for codeReuse. */
15
+ const CODE_REUSE_JAVA_REASON = "cross-file helpers do not compile in the test executor";
16
+ /** Why every other unsupported language is left out. Java has its own reason
17
+ * above; a language the shared-helper verifier does not cover is left out
18
+ * because nothing can check the module it would write. Naming Java's reason for
19
+ * a Go or Ruby test would be a false statement about that file. */
20
+ function codeReuseUnverifiableReason(language) {
21
+ return `the shared-helper verifier has no rules for ${language}`;
22
+ }
23
+ /**
24
+ * The generation-call clause that asks for codeReuse, language-conditional in
25
+ * words, as the testbot prompt appends it to its integration generation step
26
+ * when utils reuse is on.
27
+ *
28
+ * States the RULE, not one exception. Naming Java as the only language left out
29
+ * is false — code reuse covers three languages and discovery records seventeen —
30
+ * and an agent in a Go repository reads "unset for Java", concludes Go is not
31
+ * excepted, and asks for a reuse pass that can move no helpers for Go.
32
+ */
33
+ export const CODE_REUSE_GENERATION_CLAUSE = `, setting \`modularizeCode: false\` and \`codeReuse: true\` for TypeScript, JavaScript and Python, and leaving \`codeReuse\` unset for any other language (for Java, ${CODE_REUSE_JAVA_REASON}; for the rest, ${codeReuseUnverifiableReason("them")})`;
34
+ /**
35
+ * Whether the maintenance step can actually rewrite a test of this type. Its
36
+ * REGENERATE strategy names the integration and contract generators only and
37
+ * forbids skyramp_ui_test_generation, which needs a recorded trace this tool does
38
+ * not have. A browser test's REGENERATE is therefore advice to the developer: no
39
+ * call here rewrites the file, so nothing may be armed against it — a hand-off
40
+ * would refuse the execution of a file the plan never told anyone to rewrite.
41
+ */
42
+ export function isMaintenanceRegenerable(testType) {
43
+ return !isBrowserTestType(testType);
44
+ }
45
+ /**
46
+ * What the regenerate instruction asks of the generation call, as words for the
47
+ * summary (`clause`) and as the arguments the structured plan carries (`args`),
48
+ * from one decision. Undefined when the call must not ask for code reuse: utils
49
+ * reuse off, or a test type that is not a modularize-first target — contract, for
50
+ * one, whose generator accepts neither `codeReuse` nor `modularizeCode`. For a
51
+ * modularize-first type: the resolved clause and arguments for a language with a
52
+ * utils spec; the leave-unset clause and no arguments for Java; the generic clause
53
+ * and no arguments when the language is not cataloged.
54
+ */
55
+ export function regenerateCodeReuse(testType,
56
+ /** Optional because the discovery catalog does not always carry one: an
57
+ * uncataloged but real test file is accepted deliberately, and its language is
58
+ * unknown. The clause is omitted in that case. */
59
+ language) {
60
+ if (!isUtilsReuseEnabled())
61
+ return undefined;
62
+ if (!isMaintenanceRegenerable(testType))
63
+ return undefined;
64
+ if (!isModularizeFirstTarget(testType, language))
65
+ return undefined;
66
+ // No cataloged language: nothing records a hand-off for the file and no
67
+ // arguments are emitted for it, so a clause asking the agent to set
68
+ // codeReuse: true would ask for a call the structured plan does not — the very
69
+ // split that carrying the options on the entry closed. Say nothing instead.
70
+ if (!language)
71
+ return undefined;
72
+ return utilsSpecFor(language)
73
+ ? {
74
+ clause: ", setting `modularizeCode: false` and `codeReuse: true`",
75
+ args: { codeReuse: true, modularizeCode: false },
76
+ }
77
+ : {
78
+ clause: `, and leave \`codeReuse\` unset (${language.toLowerCase() === "java" ? CODE_REUSE_JAVA_REASON : codeReuseUnverifiableReason(language)}),`,
79
+ };
80
+ }
81
+ /**
82
+ * Whether a test of this type and language owes the modularize → reuse pair.
83
+ * Routing (isModularizeFirstTarget) says which flows modularize first; the utils
84
+ * spec says which languages have a payable reuse half — recordReuseHandOff writes
85
+ * nothing for a language without one (Java), so instructing the pair there would
86
+ * be a debt nothing tracks.
87
+ */
88
+ export function isModularizeFirstHandOffTarget(testType,
89
+ /** Optional because generation's own `language` param is: the predicate is the
90
+ * thing that decides an absent or unsupported language owes nothing. */
91
+ language) {
92
+ return (isModularizeFirstTarget(testType, language) && !!utilsSpecFor(language));
93
+ }
94
+ /** The argument clause of the skyramp_reuse_code call the agent is told to make. */
95
+ export function reuseCodeArgsClause(language, testType, framework) {
96
+ return `\`testFile\` set to the absolute path of the generated test file, \`language: "${language}"\`, \`testType: "${testType}"\`${framework ? `, and \`framework: "${framework}"\`` : ""}`;
97
+ }
98
+ /**
99
+ * The CRITICAL NEXT STEPS block: modularize, then reuse (whose returned steps end
100
+ * in the verify call). `enhanceFirst` prepends the assertion enhancer — browser
101
+ * tests generated with enhanceAssertions run it on the raw file, before the
102
+ * selectors move into the utils file. Maintenance never sets it: the update
103
+ * strategy calls the enhancer after the edit, and the block says the pair runs
104
+ * before it.
105
+ */
106
+ const HAND_OFF_MD = readPromptAsset("code-reuse/hand-off.md");
107
+ /** One section of the hand-off markdown, by heading, with its placeholders
108
+ * filled. The markdown is the single source of this instruction text. */
109
+ function handOffStep(heading, values) {
110
+ return fillPlaceholders(sectionBody(HAND_OFF_MD, `## ${heading}`), values);
111
+ }
112
+ export function buildModularizeFirstNextSteps(params) {
113
+ const { testType, language, framework, enhanceFirst } = params;
114
+ const enhanceCall = enhanceAssertionsCall(testType, "generated test file");
115
+ const values = {
116
+ testType,
117
+ reuseArgs: reuseCodeArgsClause(language, testType, framework),
118
+ enhanceCall: enhanceCall.charAt(0).toUpperCase() + enhanceCall.slice(1),
119
+ };
120
+ const steps = [
121
+ ...(enhanceFirst ? [handOffStep("Enhance first", values)] : []),
122
+ handOffStep("Modularize", values),
123
+ handOffStep("Reuse", values),
124
+ ];
125
+ const ordering = handOffStep(enhanceFirst
126
+ ? "Ordering with the enhancer"
127
+ : "Ordering without the enhancer", values);
128
+ return `⏭️**CRITICAL NEXT STEPS — ${ordering}**:
129
+ ${steps.map((text, i) => `${String.fromCharCode(97 + i)}. ${text}`).join("\n")}`;
130
+ }
@@ -1,6 +1,70 @@
1
+ /**
2
+ * Where a test states the status it expects: ONCE, as the argument of the helper
3
+ * call. The helper asserts it (that is the shared invariant), so the policy has to
4
+ * say what the spec contains after that — left unsaid, the agent left the status
5
+ * behind a defaulted parameter the call omitted, or asserted it a second time on the
6
+ * response the helper returned. Quoted by the prompt and by the two verify findings
7
+ * (`status-default`, `status-restated`) that enforce it, so the sentence the agent
8
+ * reads is the sentence the gate returns.
9
+ */
10
+ export declare const STATUS_ONCE_RULE: {
11
+ /** Written as the ACTION to take and the helpers it applies to. A first version
12
+ * said the parameter "carries NO default" in the present tense; quoted beside a
13
+ * finding that showed `expected_status=201`, it read as a description that was
14
+ * false about the very line it quoted, and the advisory was acted on 0 of 9 times. */
15
+ readonly noDefault: "Give every helper THIS RUN WRITES its expected status as a required parameter: no default value, not optional. A call site that can omit the status hides the expectation, so every call site passes the status it expects. A helper that already exists at HEAD keeps the signature it has, default included — never remove an incumbent's default, since callers this run cannot see rely on it; a call site this run writes still passes the status explicitly, whether or not the helper would default it. A helper whose status NEVER varies may assert the literal instead of taking a parameter at all: what this rule forbids is a DEFAULT, which lets a call site silently inherit an expectation it never stated, and a pinned literal no caller can vary hides nothing. Give it a parameter the moment a second call site needs a different status. Declare the expected-status parameter BEFORE any parameter that carries a default: Python refuses `def create_product(client, headers, body=DEFAULT_BODY, expected_status)` with `SyntaxError: non-default argument follows default argument`, and a module that does not import takes every test in the file with it at collection.";
16
+ readonly notRestated: "the test body does not assert the status again on the response the helper returns — the helper asserted it, and the call's status argument is the one statement of it";
17
+ };
1
18
  /** Why the assertion rule exists — quoted wherever the rule is stated. */
2
19
  export declare const SHARED_HELPER_WHY = "A scenario-specific assertion inside a helper carries one scenario's data into a shared function and fails the next scenario that calls it \u2014 the helper is shared, the claims are not.";
3
- export declare const BROWSER_STRUCTURAL_WAITS = "`waitForResponse`, `waitForLoadState`, `waitFor({ state: \"visible\" })`, and `toBeVisible` on a STRUCTURAL locator (a test id, or a role + name of a control) \u2014 a check that an element rendered, not what it says";
20
+ /**
21
+ * What a shared helper of one family may assert — the ONE declaration.
22
+ *
23
+ * Every statement of the rule is rendered from here: the prompt sentence the agent
24
+ * reads, the per-language predicate the verify pass runs, and the violation message
25
+ * the gate returns. They disagreed before — the prompt permitted one matcher, the
26
+ * gate accepted eight, and the message repeated the gate's reading — so a value
27
+ * assertion could sit in a delivered helper, pass the gate and reach the customer
28
+ * with nothing reported. Widening or narrowing a family is an edit to one array.
29
+ *
30
+ * The api family's permitted assertion is not a matcher list (it is a status-code
31
+ * comparison whose RECEIVER decides: `expect(res.status)` yes, `expect(res.body.status)`
32
+ * no), so `permittedMatchers` is empty for it and its predicate stays hand-written.
33
+ * Stating its list here is what SKYR-4318 does; it edits this table, and the gate
34
+ * reads the table, so no second mechanism is needed for it.
35
+ */
36
+ export interface HelperAssertionPolicy {
37
+ /** Matcher names permitted inside a shared helper, in the camelCase spelling.
38
+ * Empty when the family's rule is not expressible as a matcher list. */
39
+ permittedMatchers: readonly string[];
40
+ /** Matchers the family refuses. Named rather than implied: the boundary reads as
41
+ * a rule the agent can apply, not as a list it must invert. */
42
+ refusedMatchers: readonly string[];
43
+ /** The sentence that states the boundary, quoted VERBATIM by the prompt and by the
44
+ * gate's violation message. One string, so a reader who follows the message and a
45
+ * reader who follows the prompt are told the same thing. */
46
+ boundary: string;
47
+ }
48
+ /**
49
+ * ARIA roles whose accessible name is the page's own CONTENT rather than a control's
50
+ * label. A locator built from one of these plus a name selects by what the page SAYS,
51
+ * which is the scenario's data: `getByRole("heading", { name: "Your cart is empty!" })`
52
+ * is the scenario's outcome wearing a structural locator.
53
+ *
54
+ * A DENY-list, not an allow-list. The rule blocks a customer's run, so a role nobody
55
+ * has listed has to pass — an allow-list refused `getByRole("dialog", { name })`, which
56
+ * is an ordinary wait for a named modal and is permitted everywhere else.
57
+ */
58
+ export declare const CONTENT_ROLES: readonly ["heading", "paragraph", "cell", "gridcell", "columnheader", "rowheader", "row", "listitem", "definition", "term", "img", "figure", "article", "note", "tooltip", "alert", "log", "marquee", "timer", "blockquote", "caption", "option", "menuitem", "menuitemcheckbox", "menuitemradio", "treeitem"];
59
+ /** Spoken once, quoted everywhere. */
60
+ export declare const BROWSER_ASSERTION_BOUNDARY: string;
61
+ export declare const HELPER_ASSERTION_POLICIES: Record<"api" | "browser", HelperAssertionPolicy>;
62
+ /** The WAIT FORMS a shared browser helper may use. It deliberately stops short of
63
+ * what a structural locator is: the boundary states that, once, and this clause is
64
+ * rendered beside it. A second summary of the locator rule was a second rule to keep
65
+ * equal, and it fell behind the boundary the first time the boundary gained an
66
+ * exception. */
67
+ export declare const BROWSER_STRUCTURAL_WAITS: string;
4
68
  /**
5
69
  * Relocation never reorders execution. Two variants, because the two ends of the
6
70
  * chain may do different things with a helper whose value assertion sits BETWEEN
@@ -9,7 +73,13 @@ export declare const BROWSER_STRUCTURAL_WAITS = "`waitForResponse`, `waitForLoad
9
73
  */
10
74
  export declare const ASSERTION_BOUNDARY_RULE_EXTRACT = "Relocation must preserve the original order: an assertion that sits BETWEEN two actions is a HELPER BOUNDARY \u2014 end the helper before it and start the next helper after it (each named per the naming rule), so the assertion sits between the two calls in the test body exactly where it was. Never move an assertion across an action.";
11
75
  export declare const ASSERTION_BOUNDARY_RULE_MOVE = "Relocation must preserve the original order: only a TRAILING assertion (after the helper's last action) may move to the test body right after the call. A helper whose excluded assertion sits BETWEEN two actions is NOT moved and NOT split \u2014 leave it local in the test file; splitting is modularization's job, not this step's.";
12
- export declare const BROWSER_VALUE_ASSERTIONS = "any `expect` whose matcher OR locator carries scenario data: `toHaveText`, `toContainText`, `toHaveValue`, `toHaveCount`, `toHaveURL` with a literal, or ANY matcher \u2014 `toBeVisible` included \u2014 on a locator that embeds scenario text such as `getByText(\"Total: $899.98\")`";
76
+ export declare const BROWSER_VALUE_ASSERTIONS: string;
77
+ /**
78
+ * What qualifies as a browser reuse target — stated once, read by the page-object
79
+ * prompt and by the in-house search on the shared-module path, so the two cannot
80
+ * disagree about which of the customer's modules the run may call.
81
+ */
82
+ export declare const SELECTOR_OWNING_MODULE_RULE = "**A reuse target does not have to be a class.** Selector-owning helper libraries qualify \u2014 modules exporting free functions like `bookFirstEvent(page)` whose bodies contain the selector literals. A helper module qualifies only if its functions OWN selectors; a module whose functions take selectors as parameters (generic interaction utilities) owns nothing and is not a reuse target. Playwright fixture factories wired into the repo's own `test` object (`test.extend`-style) are NOT substitutable either \u2014 using them requires replacing the Skyramp runtime imports, which is forbidden.";
13
83
  /**
14
84
  * A helper kept local must never share a name with a utils export — the import
15
85
  * and the local definition would then describe two different behaviours under
@@ -43,6 +113,22 @@ export interface HelperPolicy {
43
113
  namingExample: string;
44
114
  /** "One X = one helper" closing line for a utils file. */
45
115
  oneHelperRule: (fileName: string) => string;
116
+ /**
117
+ * What may carry a difference in WHAT THE STEP SENDS between two call sites of
118
+ * one operation — the request body for API helpers; for browser helpers, why
119
+ * the question does not arise. Stated once here because both ends of the
120
+ * modularize -> reuse chain decide it: modularization shapes the helper, reuse
121
+ * merges a second caller into it, and a helper shaped so it cannot carry the
122
+ * second caller sends that caller off to write its own copy.
123
+ */
124
+ bodyShapeRule: string;
125
+ /**
126
+ * How the request's options object is built in a language that types it — one
127
+ * literal at the call, optional fields inline. Empty when the kind issues no
128
+ * request (browser helpers). Rendered beside `bodyShapeRule` at both ends of
129
+ * the chain for the same reason it is.
130
+ */
131
+ optionsShapeRule: string;
46
132
  /** Kind-specific near-duplicate / merge section for STEP 4b of code reuse. */
47
133
  nearDupRules: (fileName: string) => string;
48
134
  /**
@@ -14,9 +14,104 @@
14
14
  * values / literal arguments, the helper holds actions + structural waits.
15
15
  */
16
16
  import { isBrowserTestType } from "../utils/reuseRouting.js";
17
+ /**
18
+ * Where a test states the status it expects: ONCE, as the argument of the helper
19
+ * call. The helper asserts it (that is the shared invariant), so the policy has to
20
+ * say what the spec contains after that — left unsaid, the agent left the status
21
+ * behind a defaulted parameter the call omitted, or asserted it a second time on the
22
+ * response the helper returned. Quoted by the prompt and by the two verify findings
23
+ * (`status-default`, `status-restated`) that enforce it, so the sentence the agent
24
+ * reads is the sentence the gate returns.
25
+ */
26
+ export const STATUS_ONCE_RULE = {
27
+ /** Written as the ACTION to take and the helpers it applies to. A first version
28
+ * said the parameter "carries NO default" in the present tense; quoted beside a
29
+ * finding that showed `expected_status=201`, it read as a description that was
30
+ * false about the very line it quoted, and the advisory was acted on 0 of 9 times. */
31
+ noDefault: "Give every helper THIS RUN WRITES its expected status as a required parameter: no default value, not optional. A call site that can omit the status hides the expectation, so every call site passes the status it expects. A helper that already exists at HEAD keeps the signature it has, default included — never remove an incumbent's default, since callers this run cannot see rely on it; a call site this run writes still passes the status explicitly, whether or not the helper would default it. A helper whose status NEVER varies may assert the literal instead of taking a parameter at all: what this rule forbids is a DEFAULT, which lets a call site silently inherit an expectation it never stated, and a pinned literal no caller can vary hides nothing. Give it a parameter the moment a second call site needs a different status. Declare the expected-status parameter BEFORE any parameter that carries a default: Python refuses `def create_product(client, headers, body=DEFAULT_BODY, expected_status)` with `SyntaxError: non-default argument follows default argument`, and a module that does not import takes every test in the file with it at collection.",
32
+ notRestated: "the test body does not assert the status again on the response the helper returns — the helper asserted it, and the call's status argument is the one statement of it",
33
+ };
17
34
  /** Why the assertion rule exists — quoted wherever the rule is stated. */
18
35
  export const SHARED_HELPER_WHY = "A scenario-specific assertion inside a helper carries one scenario's data into a shared function and fails the next scenario that calls it — the helper is shared, the claims are not.";
19
- export const BROWSER_STRUCTURAL_WAITS = '`waitForResponse`, `waitForLoadState`, `waitFor({ state: "visible" })`, and `toBeVisible` on a STRUCTURAL locator (a test id, or a role + name of a control) — a check that an element rendered, not what it says';
36
+ /** Playwright matchers that answer "did this element render" — the browser analogue
37
+ * of a structural wait. `.not` forms included: `not.toBeVisible` is the same claim. */
38
+ const BROWSER_PRESENCE_MATCHERS = [
39
+ "toBeVisible",
40
+ "toBeHidden",
41
+ "toBeAttached",
42
+ ];
43
+ /** Matchers that answer what STATE an element is in. Not a structural wait: a button
44
+ * is enabled in one scenario and disabled in the next, so the claim belongs to the
45
+ * scenario and not to the shared step. Playwright's own actionability checks already
46
+ * wait for Enabled before `click()` and for Editable before `fill()`, so a helper
47
+ * loses no readiness by leaving these out. */
48
+ const BROWSER_STATE_MATCHERS = [
49
+ "toBeEnabled",
50
+ "toBeDisabled",
51
+ "toBeEditable",
52
+ "toBeFocused",
53
+ "toBeInViewport",
54
+ ];
55
+ /**
56
+ * ARIA roles whose accessible name is the page's own CONTENT rather than a control's
57
+ * label. A locator built from one of these plus a name selects by what the page SAYS,
58
+ * which is the scenario's data: `getByRole("heading", { name: "Your cart is empty!" })`
59
+ * is the scenario's outcome wearing a structural locator.
60
+ *
61
+ * A DENY-list, not an allow-list. The rule blocks a customer's run, so a role nobody
62
+ * has listed has to pass — an allow-list refused `getByRole("dialog", { name })`, which
63
+ * is an ordinary wait for a named modal and is permitted everywhere else.
64
+ */
65
+ export const CONTENT_ROLES = [
66
+ "heading",
67
+ "paragraph",
68
+ "cell",
69
+ "gridcell",
70
+ "columnheader",
71
+ "rowheader",
72
+ "row",
73
+ "listitem",
74
+ "definition",
75
+ "term",
76
+ "img",
77
+ "figure",
78
+ "article",
79
+ "note",
80
+ "tooltip",
81
+ "alert",
82
+ "log",
83
+ "marquee",
84
+ "timer",
85
+ "blockquote",
86
+ "caption",
87
+ // A row of data, a list entry or a menu entry is named by what it shows.
88
+ "option",
89
+ "menuitem",
90
+ "menuitemcheckbox",
91
+ "menuitemradio",
92
+ "treeitem",
93
+ ];
94
+ const list = (names) => names.map((n) => `\`${n}\``).join(", ");
95
+ /** Spoken once, quoted everywhere. */
96
+ export const BROWSER_ASSERTION_BOUNDARY = `a shared browser helper holds actions and structural waits only — a check that an element RENDERED (${list(BROWSER_PRESENCE_MATCHERS)}, negated or not — \`.not.toBeVisible()\` in TypeScript, \`not_to_be_visible()\` in Python, which has no \`.not\` to chain through) on a STRUCTURAL locator: a test id, a CSS selector, a label, or a role + name — any role EXCEPT one that names the page's own content (${list(CONTENT_ROLES)}), whose name is the scenario's data rather than a label. A check of element STATE (${list(BROWSER_STATE_MATCHERS)}) is a value assertion, not a wait — it says what the element IS, which the next scenario calling the helper may need to be the opposite of, and \`click()\` and \`fill()\` already wait for the element to be enabled and editable. A matcher on a locator that selects by RENDERED TEXT (\`getByText(...)\`, \`filter({ hasText: ... })\`, or a role + name where the role names CONTENT rather than a control, such as \`getByRole("heading", { name: "Your cart is empty!" })\` or \`getByRole("option", { name: "Order deleted" })\`) is a value assertion too, whether or not the text holds a digit. A digit inside a STRUCTURAL selector — \`locator("h1")\`, \`getByTestId("step-2-panel")\`, \`getByLabel("Address line 1")\` — is not scenario data and is permitted. Two exceptions, because a digit THERE is the scenario's own value: a role name that carries one (\`getByRole("button", { name: "Add 2 items" })\`), and a test id built out of a row rather than written as a name (\`getByTestId("order-def@mail.com - 2 items")\`). The verify pass reports only the locator forms it can recognise as text-selecting, so a locator it does not know passes — write to the rule, not to what the check happens to catch`;
97
+ export const HELPER_ASSERTION_POLICIES = {
98
+ api: {
99
+ permittedMatchers: [],
100
+ refusedMatchers: [],
101
+ boundary: "a shared API helper asserts only the status code; move this assertion to the test body, applied to the response the helper returns",
102
+ },
103
+ browser: {
104
+ permittedMatchers: BROWSER_PRESENCE_MATCHERS,
105
+ refusedMatchers: BROWSER_STATE_MATCHERS,
106
+ boundary: BROWSER_ASSERTION_BOUNDARY,
107
+ },
108
+ };
109
+ /** The WAIT FORMS a shared browser helper may use. It deliberately stops short of
110
+ * what a structural locator is: the boundary states that, once, and this clause is
111
+ * rendered beside it. A second summary of the locator rule was a second rule to keep
112
+ * equal, and it fell behind the boundary the first time the boundary gained an
113
+ * exception. */
114
+ export const BROWSER_STRUCTURAL_WAITS = `\`waitForResponse\`, \`waitForLoadState\`, \`waitFor({ state: "visible" })\`, and ${list(BROWSER_PRESENCE_MATCHERS)} on a STRUCTURAL locator as the boundary below defines one — a check that an element rendered, not what it says or what state it is in`;
20
115
  /**
21
116
  * Relocation never reorders execution. Two variants, because the two ends of the
22
117
  * chain may do different things with a helper whose value assertion sits BETWEEN
@@ -25,15 +120,43 @@ export const BROWSER_STRUCTURAL_WAITS = '`waitForResponse`, `waitForLoadState`,
25
120
  */
26
121
  export const ASSERTION_BOUNDARY_RULE_EXTRACT = "Relocation must preserve the original order: an assertion that sits BETWEEN two actions is a HELPER BOUNDARY — end the helper before it and start the next helper after it (each named per the naming rule), so the assertion sits between the two calls in the test body exactly where it was. Never move an assertion across an action.";
27
122
  export const ASSERTION_BOUNDARY_RULE_MOVE = "Relocation must preserve the original order: only a TRAILING assertion (after the helper's last action) may move to the test body right after the call. A helper whose excluded assertion sits BETWEEN two actions is NOT moved and NOT split — leave it local in the test file; splitting is modularization's job, not this step's.";
28
- export const BROWSER_VALUE_ASSERTIONS = 'any `expect` whose matcher OR locator carries scenario data: `toHaveText`, `toContainText`, `toHaveValue`, `toHaveCount`, `toHaveURL` with a literal, or ANY matcher — `toBeVisible` included — on a locator that embeds scenario text such as `getByText("Total: $899.98")`';
123
+ export const BROWSER_VALUE_ASSERTIONS = `any \`expect\` whose matcher OR locator carries scenario data: \`toHaveText\`, \`toContainText\`, \`toHaveValue\`, \`toHaveCount\`, \`toHaveURL\` with a literal, every element-STATE matcher (${list(BROWSER_STATE_MATCHERS)}), or ANY matcher — \`toBeVisible\` included — on a locator that selects by rendered text, such as \`getByText("Total: $899.98")\`, \`getByText("Order deleted")\` or \`getByRole("heading", { name: "Your cart is empty!" })\``;
29
124
  const BROWSER_LIFTABLE = "fill values, option labels, or literal arguments";
30
- const API_LIFTABLE = "body literals, `data_override` values, or expected status";
125
+ const BROWSER_BODY_SHAPE_RULE = `**A BROWSER HELPER HAS NO REQUEST BODY, SO IT HAS NOTHING ELSE TO LIFT.** What it sends is the sequence of fills and clicks it performs, and every value in that sequence is already a liftable difference under the rule above (${BROWSER_LIFTABLE}). There is no second thing the helper holds that a caller might need to replace, so the body rule the API helpers carry has no counterpart here.`;
126
+ const API_LIFTABLE = "the request body (literals inside it, or the body as a whole), the query parameters it sends, `data_override` values, or expected status";
127
+ const API_BODY_SHAPE_RULE = `**WHAT A CALLER NEEDS TO CHANGE ABOUT THE REQUEST BODY MUST BE REACHABLE FROM THE HELPER'S SIGNATURE.** A helper is shared, and the next caller of the same method+path rarely sends the same body. Whatever a caller needs to change is a PARAMETER, defaulted to what the helper sends today so existing call sites stay valid unchanged. Two forms are acceptable; take the FIRST one that reaches everything the callers need:
128
+ 1. **One parameter per differing value, applied through \`data_override\`** — each defaulted to the literal the helper sends today, applied through the request's \`data_override\` map rather than edited into the body string. Use it whenever every caller's body differs only in the VALUE at a path the generated body already carries. It is the additive form: a caller passes only what it changes, and the body string stays as generated.
129
+ 2. **One parameter carrying the whole body** — defaulted to the body the helper sends today and passed straight to the request. Python: \`def update_order(client, headers, order_id, body=DEFAULT_ORDER_BODY)\` calling \`send_request(..., body=body)\`; TypeScript/JavaScript: \`updateOrder(client, orderId, body = DEFAULT_ORDER_BODY)\` calling \`sendRequest({ ..., body })\`. Use it when a caller needs a body \`data_override\` cannot express: a field the generated body does not carry, a field left out, or a different array shape.
130
+
131
+ A module-level constant is the right home for that default, because the parameter falls back to it and any caller can pass another body instead.
132
+
133
+ **TAKE ONE FORM, NEVER BOTH.** A helper that carries a whole-body parameter AND a general override parameter passed straight to the request reaches the same body twice: the body parameter already reaches every property the override could, so the second one changes nothing the first cannot, and nothing decides whether to write it. That is how one run wrote \`create_order(client, headers, expected_status, body=DEFAULT_ORDER_BODY, data_override=None)\` and the next wrote the same helper for the same route without the override. One mechanism per helper. (An override that BUILDS a map out of named parameters — \`data_override={"name": unique_suffix(name)}\` — is form 1 working, and is not this.)
134
+
135
+ **CHANGE FORM WHEN THE CALLERS OUTGROW IT.** Form 1 reaches the values the generated body already carries and nothing else. The moment a caller needs a body form 1 cannot reach, move to form 2. The shapes named above are the ones seen so far, not the whole set — judge by whether the caller can be carried, not by whether it matches one of them. Leaving it on form 1 is what sends that caller off to write its own helper for the same method+path, which is the duplication this file exists to remove, re-created one directory away.
136
+
137
+ **A BODY NO PARAMETER REACHES AT ALL IS NEVER ACCEPTABLE.** That includes a module-level constant the helper reads DIRECTLY, with no parameter standing in front of it: it is one body, and no caller can send another. Put the current body in the parameter's default, never in a value the parameter cannot stand in for.`;
138
+ /**
139
+ * TypeScript only in effect (Python passes keyword arguments; there is no options
140
+ * object to build). The SDK types `sendRequest`'s argument, and a value built as a
141
+ * record has lost that type by the time it is passed: `TS2345 … missing url, path,
142
+ * method from SendRequestV2Options`. The executor transpiles without typechecking, so
143
+ * the run reports success and the customer's own `tsc` is the first to see it. The
144
+ * verify pass now compiles the delivered files; this is the same rule where the
145
+ * helper is authored, so it is written right the first time.
146
+ */
147
+ const API_OPTIONS_SHAPE_RULE = `**THE REQUEST OPTIONS ARE ONE OBJECT LITERAL, WRITTEN AT THE CALL.** TypeScript/JavaScript: pass \`sendRequest\` a single object literal — \`client.sendRequest({ url, path, method, headers, queryParams: query })\` — with every optional field written INLINE. A query that some callers send and others do not is a parameter defaulted to an empty map — \`query = {}\` in JavaScript; in TypeScript typed by what \`sendRequest\`'s \`queryParams\` accepts (a map of \`string | number | boolean | object | null\`, so \`query: Record<string, string | string[]> = {}\` where a key may repeat); an empty map is the same request as sending none — and passed as \`queryParams: query\`; a field that must be genuinely absent is a conditional spread inside the literal (\`...(filter ? { queryParams: { filter } } : {})\`). NEVER declare the options as \`Record<string, unknown>\` (or an untyped \`{}\`) and add fields to it afterwards: the record has no \`url\`, \`path\` or \`method\` the compiler can see, so \`sendRequest(options)\` fails the customer's typecheck even though the executor runs it. TypeScript only, the same discipline applies to every parameter's type: annotate each with the type the SDK call accepts (\`client: SkyrampClient\`, \`headers: Record<string, string>\`, a path or query value as \`string | number\`) — never \`unknown\`, which is assignable to nothing but itself and fails at its first use, and never \`any\`.`;
31
148
  const API_ASSERTION_MERGE_LINE = `a merged helper asserts ONLY the status code. If either version carries response-body assertions, relocate them to that version's test body (applied to the returned response) before merging. ${SHARED_HELPER_WHY}`;
32
149
  // (API helpers are one request + trailing assertions, so the move variant's
33
150
  // between-actions case does not arise; API_HELPERS.moveRule is empty.)
34
151
  function oneHelperLine(fileName, unit) {
35
152
  return `One ${unit} = one helper in \`${fileName}\`.`;
36
153
  }
154
+ /**
155
+ * What qualifies as a browser reuse target — stated once, read by the page-object
156
+ * prompt and by the in-house search on the shared-module path, so the two cannot
157
+ * disagree about which of the customer's modules the run may call.
158
+ */
159
+ export const SELECTOR_OWNING_MODULE_RULE = `**A reuse target does not have to be a class.** Selector-owning helper libraries qualify — modules exporting free functions like \`bookFirstEvent(page)\` whose bodies contain the selector literals. A helper module qualifies only if its functions OWN selectors; a module whose functions take selectors as parameters (generic interaction utilities) owns nothing and is not a reuse target. Playwright fixture factories wired into the repo's own \`test\` object (\`test.extend\`-style) are NOT substitutable either — using them requires replacing the Skyramp runtime imports, which is forbidden.`;
37
160
  /**
38
161
  * A helper kept local must never share a name with a utils export — the import
39
162
  * and the local definition would then describe two different behaviours under
@@ -46,7 +169,7 @@ export const API_HELPERS = {
46
169
  liftableLiterals: API_LIFTABLE,
47
170
  structuralNoise: "",
48
171
  namingRule: "**NAME** each helper by method + resource ONLY, written in the naming convention of the language it is emitted in — Python `create_product`, `update_order`, `get_order`, `get_orders_list`; TypeScript/JavaScript `createProduct`, `updateOrder`, `getOrder`, `getOrdersList`. Match the surrounding test file: snake_case helpers in a camelCase TS suite read as foreign code the repo did not write. Scenario adjectives in names are FORBIDDEN (`create_discount_test_product`, `updateOrder50Discount`) — other tests define the same step, and a shared utils file can hold only one canonical name per step. Scenario data belongs in ARGUMENTS, never in the name.",
49
- assertionRule: `**THE ONLY ASSERTION INSIDE A SHARED HELPER IS THE STATUS CODE**, written in the test's own assertion syntax (Python \`assert response.status_code == expected_status\`; TypeScript/JavaScript \`expect(response.status).toBe(expectedStatus)\`), with the expected status a parameter defaulted to this scenario's expected code. EVERY response-body assertion (echo-backs, computed totals, field checks) stays in the test body, applied to the response the helper returns. ${SHARED_HELPER_WHY}`,
172
+ assertionRule: `**THE ONLY ASSERTION INSIDE A SHARED HELPER IS THE STATUS CODE**, written in the test's own assertion syntax (Python \`assert response.status_code == expected_status\`; TypeScript/JavaScript \`expect(response.status).toBe(expectedStatus)\`). ${STATUS_ONCE_RULE.noDefault} (\`create_order(client, headers, body, 201)\`, never \`expected_status=201\` in a signature this run writes — a helper named for the happy path that defaults to a rejection reads as a bug on sight, and \`None\` is a default too.) In turn, ${STATUS_ONCE_RULE.notRestated}. EVERY response-body assertion (echo-backs, computed totals, field checks) stays in the test body, applied to the response the helper returns. ${SHARED_HELPER_WHY}`,
50
173
  relocationTarget: "the test body, applied to the response the helper returns",
51
174
  moveRule: "",
52
175
  namingExample: "E.g. `update_order` (Python) / `updateOrder` (TypeScript), not `update_order_discount` or `updateOrder50Discount`.",
@@ -54,6 +177,8 @@ export const API_HELPERS = {
54
177
  // The API section below carries its own worked example; the generic
55
178
  // Playwright one would teach intent-naming and locator merges to a Python prompt.
56
179
  nearDupExample: () => "",
180
+ bodyShapeRule: API_BODY_SHAPE_RULE,
181
+ optionsShapeRule: API_OPTIONS_SHAPE_RULE,
57
182
  // API request helpers are one SDK call + assertions, so near-duplicate
58
183
  // equivalence is judged by method+path, not Playwright primitives — and the
59
184
  // SDK's data_override makes literal-lifting mechanical, which is why this
@@ -65,25 +190,30 @@ For helpers that wrap one SDK request call (e.g. \`client.send_request(...)\`),
65
190
 
66
191
  1. **Same method and same path** (path parameters count as the same path).
67
192
  2. **Same call structure** — same request-call shape; no extra steps in one but not the other.
68
- 3. **Differences are limited to**: literals inside the request-body string, values in \`data_override\`, the expected status code, or which values are lifted to parameters.
193
+ 3. **Differences are limited to**: the request body — literals inside it, or the body as a whole — the query parameters it sends, values in \`data_override\`, the expected status code, or which values are lifted to parameters.
69
194
 
70
- Merge procedure for an API near-duplicate pair — these rules OVERRIDE the generic procedure below on two points: body literals ARE liftable differences (via \`data_override\`), and defaults are REQUIRED (the generic "no defaults" rule applies to Playwright helpers only):
195
+ Merge procedure for an API near-duplicate pair — these rules OVERRIDE the generic procedure below on two points: what the request SENDS — its body and its query — IS a liftable difference, and defaults are REQUIRED for every lifted value except the expected status (the generic "no defaults" rule applies to Playwright helpers only; the expected status is the one API parameter that never has one):
71
196
  - **Name**: method + resource only (\`create_product\`, \`update_order\`) — never a scenario adjective.
72
197
  - **Lift each differing body literal into a parameter applied via \`data_override\`, with the parameter's DEFAULT set to the literal the incumbent version used.** Defaults make the merge additive: every existing call site keeps its behavior without edits; only the other test passes its values explicitly.
73
- - **Union the parameter lists**; a parameter one version lacked gets the default from that version's literal. A differing expected status lifts the same way: \`expected_status\` parameter, default from the incumbent.
198
+ - **Union the parameter lists**; a parameter one version lacked gets the default from that version's literal. The expected status is the exception. ${STATUS_ONCE_RULE.noDefault} Merging two versions this run wrote that expected different statuses means each call site passes its own — and a call site's own status assertion, if it wrote one beside the call, is deleted (${STATUS_ONCE_RULE.notRestated}).
199
+ - **A differing query lifts the same way**: the query map is a parameter, defaulted to the map the incumbent sends — an EMPTY map where it sends none, which is the same request, so a helper that omits the query keeps omitting it for every existing caller. Where both versions send the same keys and only the values differ, one parameter per differing value is enough.
74
200
  - **Assertions**: ${API_ASSERTION_MERGE_LINE}
75
- - Structural differences (different items-array shape, extra request) → NOT near-duplicates; leave them alone.
201
+ - Structural differences (an extra request, a different method or path, an extra step) → NOT near-duplicates; leave them alone. What the request SENDS is not structure, whatever form the difference takes: a body that differs is a body difference, and a query that differs is a query difference. A parameter carries each of them; a second helper carries neither.
202
+
203
+ ${API_BODY_SHAPE_RULE}
76
204
 
77
- Worked example: \`update_order_discount(client, headers, order_id, product_id)\` with \`"discount_percent": 25\` in the body, and \`update_order_50_discount(client, headers, order_id, product_id, quantity)\` with \`"discount_percent": 50\` → ONE helper \`update_order(client, headers, order_id, product_id, discount_percent=25, quantity=2)\` that applies \`discount_percent\` and \`quantity\` via \`data_override\`. ${oneHelperLine(fileName, "method+path")}
205
+ ${API_OPTIONS_SHAPE_RULE}
206
+
207
+ Worked example: \`update_order_discount(client, headers, order_id, product_id)\` with \`"discount_percent": 25\` in the body, and \`update_order_50_discount(client, headers, order_id, product_id, quantity)\` with \`"discount_percent": 50\` → ONE helper \`update_order(client, headers, order_id, product_id, expected_status, discount_percent=25, quantity=2)\` that applies \`discount_percent\` and \`quantity\` via \`data_override\` — the expected status required and declared before the defaulted parameters, per the assertion rule above. ${oneHelperLine(fileName, "method+path")}
78
208
  `,
79
209
  };
80
210
  export const BROWSER_HELPERS = {
81
211
  kind: "browser",
82
212
  sameStep: "the SAME action sequence (same Playwright primitives in the same order, selectors identical)",
83
213
  liftableLiterals: BROWSER_LIFTABLE,
84
- structuralNoise: "`waitForTimeout(...)` lines and the `getValue(playwrightRequestN, ...)` value wrapper around a fill are RECORDER NOISE, not structure — two bodies that differ only by them perform the same step, so merge them; keep the body WITHOUT the `waitForTimeout` lines. A fixed sleep is not a structural wait: it is the one line of the pair that carries no meaning, and in a shared helper every importer pays it on every run. Where a step genuinely needs to wait, wait on the element the next line touches (`toBeVisible`, `toBeEnabled`)",
214
+ structuralNoise: '`waitForTimeout(...)` lines and the `getValue(playwrightRequestN, ...)` value wrapper around a fill are RECORDER NOISE, not structure — two bodies that differ only by them perform the same step, so merge them; keep the body WITHOUT the `waitForTimeout` lines. A fixed sleep is not a structural wait: it is the one line of the pair that carries no meaning, and in a shared helper every importer pays it on every run. Where a step genuinely needs to wait, wait on the element the next line touches (`toBeVisible`, or `waitFor({ state: "visible" })`) — never on its state (`toBeEnabled`), which is a scenario\'s claim and which `click()` and `fill()` already wait for',
85
215
  namingRule: "**NAME** each helper by the user INTENT it performs, shared across tests: `openEditOrderForm`, `applyDiscount`, `submitProductForm`, `removeOrderItem`. Scenario values or adjectives in names are FORBIDDEN (`applyFiftyPercentDiscount`, `editOrder1Discount`, `createExpensiveProduct`) — another test performs the same action with different data, and a shared utils file holds ONE canonical name per action. Scenario data belongs in ARGUMENTS, never in the name.",
86
- assertionRule: `**A SHARED HELPER CONTAINS ACTIONS AND STRUCTURAL WAITS ONLY**: clicks, fills, selects, ${BROWSER_STRUCTURAL_WAITS}. EVERY VALUE ASSERTION (${BROWSER_VALUE_ASSERTIONS}) stays in the test body, placed immediately after the helper call it verifies, with its selector verbatim and its expected value unchanged. ${SHARED_HELPER_WHY}`,
216
+ assertionRule: `**A SHARED HELPER CONTAINS ACTIONS AND STRUCTURAL WAITS ONLY**: clicks, fills, selects, ${BROWSER_STRUCTURAL_WAITS}. Stated once, exactly as the verify pass states it: ${BROWSER_ASSERTION_BOUNDARY}. EVERY VALUE ASSERTION (${BROWSER_VALUE_ASSERTIONS}) stays in the test body, placed immediately after the helper call it verifies, with its selector verbatim and its expected value unchanged. ${SHARED_HELPER_WHY}`,
87
217
  relocationTarget: "the test body, immediately after the helper call, selector verbatim",
88
218
  moveRule: ASSERTION_BOUNDARY_RULE_MOVE,
89
219
  namingExample: "E.g. `applyDiscount`, not `applyTwentyPercentDiscount`.",
@@ -116,6 +246,8 @@ export async function applyDiscount(page: Page, discountPercent: string) {
116
246
  \`\`\`
117
247
 
118
248
  Both test files import and call \`applyDiscount(page, "10")\` / \`applyDiscount(page, "20")\`. A pair whose selectors differ (\`getByTestId("edit-order-submit-btn")\` vs \`getByRole("button", { name: "Save" })\`, or one side carrying \`.first()\`) is NOT a near-duplicate — leave both in place.`,
249
+ bodyShapeRule: BROWSER_BODY_SHAPE_RULE,
250
+ optionsShapeRule: "",
119
251
  // Browser helpers already have the Playwright near-duplicate criteria in the
120
252
  // generic STEP 4b text; what they lack for a shared file is the
121
253
  // defaulted-parameter merge (so an incumbent utils helper can absorb a new
@@ -127,6 +259,8 @@ For this flow the rules below OVERRIDE two points of the generic text above and
127
259
  - **Name**: the INTENT the action sequence performs (\`openEditOrderForm\`, \`applyDiscount\`, \`submitProductForm\`) — never a scenario adjective or value (\`applyFiftyPercentDiscount\`, \`editOrder1Discount\`). ${oneHelperLine(fileName, "intent")}
128
260
  - **Lift each differing literal into a parameter with its DEFAULT set to the literal the incumbent version used** (${BROWSER_LIFTABLE}). Defaults make the merge additive: every existing call site keeps its behavior without edits; only the new test passes its values explicitly. Selectors stay verbatim in the body.
129
261
  - **Assertions**: before merging, apply the assertion rule to both versions — relocate a trailing value assertion to that version's test body immediately after the helper call. ${ASSERTION_BOUNDARY_RULE_MOVE} ${SHARED_HELPER_WHY}
262
+
263
+ ${BROWSER_BODY_SHAPE_RULE}
130
264
  `,
131
265
  };
132
266
  /** Which helper policy a test type's helpers follow. */
@@ -152,7 +152,7 @@ const _adaptPlan = new PromptPlan()
152
152
  .subStep("RECORD_CONTRACT", "Record the run contract in workspace.yml", buildRecordTestContractBody)
153
153
  .step("VERIFY", "Verify", () => "")
154
154
  .subStep("COMMON_ERRORS", "Common SUT errors", () => buildCommonSutErrorsSection())
155
- .subStep("LOCAL_VALIDATION", "Local validation", () => buildLocalValidationSection())
155
+ .subStep("LOCAL_VALIDATION", "Local validation", (args) => buildLocalValidationSection(args))
156
156
  .done();
157
157
  // ── Goal section (static prose above the plan) ────────────────────────────────
158
158
  function buildGoalSection(args) {
@@ -287,7 +287,7 @@ const _composePlan = new PromptPlan()
287
287
  .subStep("APPLY", "Apply the chosen strategy", buildApplyStrategyBody)
288
288
  .step("VERIFY", "Verify", () => "")
289
289
  .subStep("COMMON_ERRORS", "Common SUT errors", () => buildCommonSutErrorsSection())
290
- .subStep("LOCAL_VALIDATION", "Local validation", () => buildLocalValidationSection())
290
+ .subStep("LOCAL_VALIDATION", "Local validation", (args) => buildLocalValidationSection(args))
291
291
  .done();
292
292
  export function getDockerComposePrompt(args) {
293
293
  const composeFile = args.sutSourceDockerComposeFile?.trim();
@@ -10,6 +10,9 @@ export declare enum SutSetupMode {
10
10
  }
11
11
  export interface SutPromptArgs {
12
12
  repositoryPath: string;
13
+ /** `owner/repo` of the checkout at repositoryPath. The canary calls
14
+ * skyramp_run_existing_tests, which names its repository on every call. */
15
+ repository: string;
13
16
  sutSetupMode: string;
14
17
  sutSourceWorkflowFile: string;
15
18
  sutSourceDockerComposeFile: string;
@@ -41,7 +44,7 @@ export declare function buildSeedDataDiscoverySection(): string;
41
44
  * generated `.skyramp/sut/*` files.
42
45
  */
43
46
  export declare function buildWorkspaceInitSection(): string;
44
- export declare function buildLocalValidationSection(): string;
47
+ export declare function buildLocalValidationSection(args: SutPromptArgs): string;
45
48
  /**
46
49
  * Returns the canonical "add to the Testbot workflow" block: every input that
47
50
  * controls the SUT lifecycle, auth, and workflow-level setup, followed by the
@@ -82,7 +82,7 @@ export function buildWorkspaceInitSection() {
82
82
 
83
83
  Later steps in this SUT bootstrap run write \`.skyramp/sut/*\` files alongside the workspace file. If you need to update per-service \`runtimeDetails.serverStartCommand\` to match the new SUT files, call \`skyramp_init_workspace\` again (see its tool description for the edit-mode / \`force\` contract) rather than editing \`.skyramp/workspace.yml\` directly.`;
84
84
  }
85
- export function buildLocalValidationSection() {
85
+ export function buildLocalValidationSection(args) {
86
86
  return `Before reporting success, exercise the adapted workflow locally. Testbot's external fix loop only retries when SUT lifecycle commands are set on the Testbot action. When the SUT is brought up by surrounding GHA steps (skipTargetSetup: 'true'), the fix loop is skipped — so the local check below is the only safety net before the workflow is committed.
87
87
  Run commands one at a time in your shell — individual execution pinpoints failures far faster than running the whole workflow at once. For any setup, build, or lifecycle command, a non-zero exit is a fix-needed signal: adjust the workflow, re-run the failing command, and do not proceed until it passes. (The suite canary in step 4 is the one exception — judge it on whether the test executes, not on its pass/fail result.)
88
88
  1. Validate build scripts and helper programs first — run these before anything else so build and auth failures surface cheaply:
@@ -95,7 +95,7 @@ Run commands one at a time in your shell — individual execution pinpoints fail
95
95
  3. Validate the SUT lifecycle comes up — choose the branch that matches the chosen pattern:
96
96
  a. If lifecycle commands are set on the Testbot action (skipTargetSetup is unset): run \`targetSetupCommand\` (confirm exit 0), then poll \`targetReadyCheckCommand\` until it exits 0 within \`targetReadyCheckTimeout\` seconds.
97
97
  b. If GHA steps wrap the Testbot action (skipTargetSetup: 'true'): the SETUP steps you ran in step 2 already brought the SUT up, so just poll \`targetReadyCheckCommand\` until it exits 0.
98
- 4. Canary the repository's own suite(s) — do this only when a suite was recorded (a \`testSuites\` entry under a service's \`runtimeDetails\` in \`workspace.yml\`); skip it when none was recorded. With the SUT still running from step 3 and before teardown, call **\`skyramp_run_existing_tests\`** with \`workspacePath\` and \`testSelectors\` — one real test FILE per recorded suite. Do NOT canary by running the suite's command in your shell. **Maintenance runs every suite through this tool, so it is the only thing that proves what maintenance will actually be able to do**: a shell command you drove by hand can succeed while the same suite is unrunnable through the tool, and then the failure surfaces on a customer's first PR instead of here. It also resolves each selector to its owning suite via \`pathGlobs\`, so one call checks your routing too, and it appends the reporter flag and selector itself — you do not hand-build those.
98
+ 4. Canary the repository's own suite(s) — do this only when a suite was recorded (a \`testSuites\` entry under a service's \`runtimeDetails\` in \`workspace.yml\`); skip it when none was recorded. With the SUT still running from step 3 and before teardown, call **\`skyramp_run_existing_tests\`** with \`workspacePath\`, \`testSelectors\` — one real test FILE per recorded suite — and \`repository\`: "${args.repository}". Pass no \`stateFile\`: the canary runs before any analysis, so it writes no run state. Do NOT canary by running the suite's command in your shell. **Maintenance runs every suite through this tool, so it is the only thing that proves what maintenance will actually be able to do**: a shell command you drove by hand can succeed while the same suite is unrunnable through the tool, and then the failure surfaces on a customer's first PR instead of here. It also resolves each selector to its owning suite via \`pathGlobs\`, so one call checks your routing too, and it appends the reporter flag and selector itself — you do not hand-build those.
99
99
  - Cover **every** suite in \`runtimeDetails.testSuites\`, not a subset you choose: do not rank them or trim by cost. A suite that spawns its OWN app instances (per-worker containers via its own orchestration) belongs in the set like any other — it depends entirely on your provisioning, so its weight is a reason to run it, never a reason to defer it. HTTP readiness only shows the app answers; one real test per suite is what proves each suite's environment is present — its browser, the built e2e image, dev/test dependencies, and base-URL wiring.
100
100
  - Read the result per suite: \`summary.ran > 0\` is the suite executing. \`environmentHealthy: false\` or \`skipped: true\` means it did not — \`healthDetail\`/\`skipReason\` says why, and that text is what belongs in the suite's \`canaryDetail\`.
101
101
  - A suite that executed and then FAILED its assertions is fine — the environment is runnable, so proceed. A suite that did not execute is the fix-needed signal — the exit criteria below say what you must fix and when you are allowed to stop trying. Never edit, skip, or delete the repo's tests to force a pass; that is out of scope for setup.
@@ -1,10 +1,4 @@
1
- /**
2
- * Prompt language for skyramp_actions output — the LLM_INSTRUCTIONS block
3
- * emitted to the agent that applies UPDATE, REGENERATE, and DELETE actions.
4
- *
5
- * Kept separate from actionsTool.ts so prompt text is co-located with other
6
- * maintenance prompts and can be reviewed/edited without touching tool logic.
7
- */
1
+ import { TestType } from "../../types/TestTypes.js";
8
2
  export interface RenameEntry {
9
3
  oldPath: string;
10
4
  newPath: string;
@@ -14,12 +8,17 @@ export interface RenameEntry {
14
8
  export declare function buildRenameStrategy(): string;
15
9
  /** Strategy string for file renames after path substitution. */
16
10
  export declare function buildFileRenameStrategy(): string;
17
- /** Strategy string for in-place UPDATE edits. */
18
- export declare function buildUpdateStrategy(): string;
11
+ /** Strategy string for in-place UPDATE edits. `withPostEditSteps` is set when at
12
+ * least one update_context entry carries post_edit_steps — the modularize → reuse
13
+ * pair an updated test owes, which skyramp_execute_test refuses the file without. */
14
+ export declare function buildUpdateStrategy(withPostEditSteps?: boolean): string;
19
15
  /** Strategy string for UPDATE entries that refresh visual-snapshot baselines (SKYR-4298). */
20
16
  export declare function buildRebaselineStrategy(): string;
21
- /** Strategy string for REGENERATE — call generation tool to overwrite the file. */
22
- export declare function buildRegenerateStrategy(): string;
17
+ /** Strategy string for REGENERATE — call generation tool to overwrite the file.
18
+ * `withGenerationArgs` is set when at least one regenerate_context entry carries
19
+ * generation_args — the codeReuse options that arm the modularize → reuse chain the
20
+ * regenerated file owes. */
21
+ export declare function buildRegenerateStrategy(withGenerationArgs?: boolean): string;
23
22
  /** Strategy string for DELETE — remove obsolete test files whose covered endpoints/UI no longer exist. */
24
23
  export declare function buildDeleteStrategy(): string;
25
24
  /** Per-file instruction block for a single UPDATE recommendation. */
@@ -31,6 +30,9 @@ export declare function buildUpdateFileInstruction(params: {
31
30
  rationale?: string;
32
31
  /** Visual baselines to refresh at final execution instead of editing (SKYR-4298). */
33
32
  rebaselineSnapshots?: string[];
33
+ /** The modularize → reuse next-steps block for a test that owes the pair; closes
34
+ * the file's instruction so the edit comes first. */
35
+ postEditSteps?: string;
34
36
  }): string;
35
37
  /** Per-file instruction block for a single REGENERATE recommendation. */
36
38
  export declare function buildRegenerateFileInstruction(params: {
@@ -38,4 +40,10 @@ export declare function buildRegenerateFileInstruction(params: {
38
40
  updateInstructions?: string;
39
41
  outputDir: string;
40
42
  outputFile: string;
43
+ /** The recommendation's test type, normalized to the catalog's where the catalog
44
+ * has one, so the clause and regenerate_context[].generation_args agree. */
45
+ testType: TestType;
46
+ /** The cataloged language. Optional because the catalog does not always carry
47
+ * one: an uncataloged but real test file is accepted deliberately. */
48
+ language?: string;
41
49
  }): string;