@skyramp/mcp 0.3.8 → 0.4.0-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 (229) hide show
  1. package/build/commands/commandLibrary.d.ts +1 -1
  2. package/build/commands/commandLibrary.js +3 -3
  3. package/build/commands/recommendTestsAndExecuteCommand.d.ts +1 -1
  4. package/build/commands/recommendTestsAndExecuteCommand.js +35 -20
  5. package/build/commands/testThisEndpointCommand.js +35 -19
  6. package/build/index.js +9 -3
  7. package/build/playwright/blueprintDigest.d.ts +15 -0
  8. package/build/playwright/blueprintDigest.js +152 -0
  9. package/build/playwright/blueprintDigestStore.d.ts +31 -0
  10. package/build/playwright/blueprintDigestStore.js +117 -0
  11. package/build/playwright/registerPlaywrightTools.js +60 -12
  12. package/build/playwright/traceRecordingPrompt.js +8 -7
  13. package/build/prompts/enhance-assertions/sharedAssertionRules.js +9 -8
  14. package/build/prompts/enhance-assertions/uiAssertionsPrompt.js +24 -2
  15. package/build/prompts/promptAssets.d.ts +20 -0
  16. package/build/prompts/promptAssets.js +55 -0
  17. package/build/prompts/sut-setup/modes/dockerComposePrompt.js +19 -5
  18. package/build/prompts/test-maintenance/actionsInstructions.d.ts +4 -0
  19. package/build/prompts/test-maintenance/actionsInstructions.js +14 -2
  20. package/build/prompts/test-maintenance/drift-analysis-prompt.d.ts +0 -10
  21. package/build/prompts/test-maintenance/drift-analysis-prompt.js +2 -11
  22. package/build/prompts/test-maintenance/uiDriftAnalysisSections.js +8 -4
  23. package/build/prompts/test-recommendation/diffExecutionPlan.d.ts +5 -22
  24. package/build/prompts/test-recommendation/diffExecutionPlan.js +37 -465
  25. package/build/prompts/test-recommendation/recommendationSections.d.ts +7 -17
  26. package/build/prompts/test-recommendation/recommendationSections.js +67 -309
  27. package/build/prompts/test-recommendation/recommendationShared.d.ts +19 -47
  28. package/build/prompts/test-recommendation/recommendationShared.js +49 -155
  29. package/build/prompts/test-recommendation/registerRecommendTestsPrompt.d.ts +0 -5
  30. package/build/prompts/test-recommendation/registerRecommendTestsPrompt.js +10 -153
  31. package/build/prompts/test-recommendation/test-recommendation-prompt.d.ts +2 -29
  32. package/build/prompts/test-recommendation/test-recommendation-prompt.js +32 -457
  33. package/build/prompts/testbot/planDeclarations.d.ts +6 -0
  34. package/build/prompts/testbot/planDeclarations.js +9 -0
  35. package/build/prompts/testbot/testbot-prompts.d.ts +8 -0
  36. package/build/prompts/testbot/testbot-prompts.js +256 -381
  37. package/build/recommendation/answers.d.ts +35 -0
  38. package/build/recommendation/answers.js +96 -0
  39. package/build/recommendation/registerPlan.d.ts +49 -0
  40. package/build/recommendation/registerPlan.js +117 -0
  41. package/build/recommendation/runVerifiers.d.ts +10 -0
  42. package/build/recommendation/runVerifiers.js +49 -0
  43. package/build/recommendation/subjectStep.d.ts +42 -0
  44. package/build/recommendation/subjectStep.js +86 -0
  45. package/build/recommendation/types.d.ts +163 -0
  46. package/build/recommendation/types.js +20 -0
  47. package/build/recommendation/verifierContracts.d.ts +382 -0
  48. package/build/recommendation/verifierContracts.js +263 -0
  49. package/build/recommendation/verifiers/changedFile.d.ts +2 -0
  50. package/build/recommendation/verifiers/changedFile.js +82 -0
  51. package/build/recommendation/verifiers/citedPath.d.ts +12 -0
  52. package/build/recommendation/verifiers/citedPath.js +35 -0
  53. package/build/recommendation/verifiers/coverage.d.ts +7 -0
  54. package/build/recommendation/verifiers/coverage.js +617 -0
  55. package/build/recommendation/verifiers/deliveredMatchesPlan.d.ts +11 -0
  56. package/build/recommendation/verifiers/deliveredMatchesPlan.js +33 -0
  57. package/build/recommendation/verifiers/endpointGrounded.d.ts +17 -0
  58. package/build/recommendation/verifiers/endpointGrounded.js +128 -0
  59. package/build/recommendation/verifiers/existingCoverage.d.ts +6 -0
  60. package/build/recommendation/verifiers/existingCoverage.js +51 -0
  61. package/build/recommendation/verifiers/expectedOutcome.d.ts +31 -0
  62. package/build/recommendation/verifiers/expectedOutcome.js +105 -0
  63. package/build/recommendation/verifiers/removedElementGuarded.d.ts +2 -0
  64. package/build/recommendation/verifiers/removedElementGuarded.js +57 -0
  65. package/build/recommendation/verifiers/reportedCategory.d.ts +26 -0
  66. package/build/recommendation/verifiers/reportedCategory.js +84 -0
  67. package/build/recommendation/verifiers/screenRoute.d.ts +10 -0
  68. package/build/recommendation/verifiers/screenRoute.js +118 -0
  69. package/build/recommendation/verifiers/statedDifference.d.ts +6 -0
  70. package/build/recommendation/verifiers/statedDifference.js +140 -0
  71. package/build/recommendation/verifiers/uiElementGrounded.d.ts +7 -0
  72. package/build/recommendation/verifiers/uiElementGrounded.js +318 -0
  73. package/build/resources/analysisResources.js +1 -114
  74. package/build/resources/testbotResource.js +23 -13
  75. package/build/services/ModularizationService.js +2 -1
  76. package/build/services/TestDiscoveryService.d.ts +3 -72
  77. package/build/services/TestDiscoveryService.js +10 -303
  78. package/build/services/containerEnv.d.ts +1 -1
  79. package/build/services/containerEnv.js +12 -0
  80. package/build/skills/fixTestImportErrorsSkill.d.ts +13 -0
  81. package/build/skills/fixTestImportErrorsSkill.js +20 -0
  82. package/build/toolNames.d.ts +1 -0
  83. package/build/toolNames.js +1 -0
  84. package/build/tools/code-refactor/enhanceAssertionsTool.js +3 -3
  85. package/build/tools/code-refactor/modularizationTool.js +2 -1
  86. package/build/tools/executeSkyrampTestTool.d.ts +80 -0
  87. package/build/tools/executeSkyrampTestTool.js +246 -19
  88. package/build/tools/generate-tests/generateBatchScenarioRestTool.js +6 -0
  89. package/build/tools/generate-tests/generateContractRestTool.js +3 -3
  90. package/build/tools/generate-tests/planGuard.d.ts +2 -2
  91. package/build/tools/generate-tests/planGuard.js +78 -18
  92. package/build/tools/one-click/oneClickTool.d.ts +0 -1
  93. package/build/tools/one-click/oneClickTool.js +0 -5
  94. package/build/tools/submitReportTool.d.ts +48 -42
  95. package/build/tools/submitReportTool.js +576 -193
  96. package/build/tools/test-management/actionsTool.js +72 -4
  97. package/build/tools/test-management/analyzeChangesTool.d.ts +144 -48
  98. package/build/tools/test-management/analyzeChangesTool.js +212 -1219
  99. package/build/tools/test-management/analyzeTestHealthTool.js +13 -24
  100. package/build/tools/test-management/index.d.ts +1 -0
  101. package/build/tools/test-management/index.js +1 -0
  102. package/build/tools/test-management/registerTestPlanTool.d.ts +795 -172
  103. package/build/tools/test-management/registerTestPlanTool.js +609 -542
  104. package/build/tools/test-management/resolveScreenTool.d.ts +75 -0
  105. package/build/tools/test-management/resolveScreenTool.js +289 -0
  106. package/build/types/BlueprintDigest.d.ts +34 -0
  107. package/build/types/BlueprintDigest.js +1 -0
  108. package/build/types/RepositoryAnalysis.d.ts +20 -1559
  109. package/build/types/RepositoryAnalysis.js +2 -58
  110. package/build/types/StepMethod.d.ts +40 -0
  111. package/build/types/StepMethod.js +77 -0
  112. package/build/types/TestAnalysis.d.ts +12 -0
  113. package/build/types/TestExecution.d.ts +4 -0
  114. package/build/types/TestRecommendation.d.ts +24 -24
  115. package/build/types/TestRecommendation.js +91 -89
  116. package/build/types/TestbotPromptOptions.d.ts +0 -4
  117. package/build/types/TestbotReport.d.ts +64 -2
  118. package/build/utils/AnalysisStateManager.d.ts +79 -113
  119. package/build/utils/AnalysisStateManager.js +147 -57
  120. package/build/utils/assertion-verify/api-shared-lints.js +1 -1
  121. package/build/utils/assertion-verify/metrics.js +85 -36
  122. package/build/utils/assertion-verify/ui-lints.d.ts +0 -5
  123. package/build/utils/assertion-verify/ui-lints.js +32 -0
  124. package/build/utils/branchDiff.d.ts +63 -31
  125. package/build/utils/branchDiff.js +242 -94
  126. package/build/utils/containedPath.d.ts +18 -0
  127. package/build/utils/containedPath.js +73 -0
  128. package/build/utils/dartRouteExtractor.d.ts +18 -34
  129. package/build/utils/dartRouteExtractor.js +101 -173
  130. package/build/utils/featureFlags.d.ts +12 -0
  131. package/build/utils/featureFlags.js +14 -0
  132. package/build/utils/frontendSelectors.d.ts +48 -27
  133. package/build/utils/frontendSelectors.js +241 -80
  134. package/build/utils/pathMatching.d.ts +2 -4
  135. package/build/utils/pathMatching.js +2 -4
  136. package/build/utils/planMatchKeys.d.ts +38 -47
  137. package/build/utils/planMatchKeys.js +143 -81
  138. package/build/utils/rebaselineSnapshots.d.ts +24 -0
  139. package/build/utils/rebaselineSnapshots.js +65 -0
  140. package/build/utils/removedUiElements.d.ts +22 -0
  141. package/build/utils/removedUiElements.js +106 -0
  142. package/build/utils/reportVerification.d.ts +2 -6
  143. package/build/utils/reportVerification.js +61 -2
  144. package/build/utils/screenRoutes.d.ts +66 -0
  145. package/build/utils/screenRoutes.js +727 -0
  146. package/build/utils/sourceRouteExtractor.js +320 -112
  147. package/build/utils/testFileClassification.d.ts +11 -2
  148. package/build/utils/testFileClassification.js +44 -2
  149. package/build/utils/testFixtures.d.ts +5 -0
  150. package/build/utils/testFixtures.js +13 -0
  151. package/build/utils/utils.d.ts +0 -1
  152. package/build/utils/utils.js +0 -11
  153. package/build/utils/versions.d.ts +3 -3
  154. package/build/utils/versions.js +1 -1
  155. package/build/workspace/workspace.d.ts +12 -12
  156. package/node_modules/playwright/lib/mcp/skyramp/assertHiddenTool.js +56 -0
  157. package/node_modules/playwright/lib/mcp/skyramp/assertTool.js +2 -1
  158. package/node_modules/playwright/lib/mcp/skyramp/loadTraceTool.js +10 -0
  159. package/node_modules/playwright/lib/mcp/skyramp/skyRampImport.js +4 -1
  160. package/node_modules/playwright/lib/mcp/skyramp/traceRecordingBackend.js +160 -1
  161. package/node_modules/playwright/lib/mcp/test/skyRampExport.js +4 -2
  162. package/node_modules/playwright/node_modules/playwright-core/lib/server/codegen/skyramp/jsonlReader.js +1 -0
  163. package/node_modules/playwright/node_modules/playwright-core/lib/server/recorder/recorderSignalProcessor.js +2 -0
  164. package/node_modules/playwright/node_modules/playwright-core/lib/server/recorder.js +5 -1
  165. package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/{index.-Id052Lr.js → index.B7KbSQcC.js} +1 -1
  166. package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/index.html +1 -1
  167. package/node_modules/playwright/node_modules/playwright-core/package.json +1 -1
  168. package/node_modules/playwright/node_modules/playwright-core/src/server/codegen/skyramp/jsonlReader.ts +1 -1
  169. package/node_modules/playwright/node_modules/playwright-core/src/server/recorder/recorderSignalProcessor.ts +7 -0
  170. package/node_modules/playwright/node_modules/playwright-core/src/server/recorder.ts +6 -1
  171. package/node_modules/playwright/package.json +1 -1
  172. package/package.json +4 -3
  173. package/plugin/.claude-plugin/plugin.json +8 -0
  174. package/plugin/plugin.json +6 -0
  175. package/plugin/prompts/declaring-a-plan.md +20 -0
  176. package/plugin/prompts/generate-tests/context-fetching.md +4 -0
  177. package/plugin/prompts/generate-tests/execution-plan.md +63 -0
  178. package/plugin/prompts/generate-tests/generation.md +108 -0
  179. package/plugin/prompts/generate-tests/path-parameters.md +1 -0
  180. package/plugin/prompts/generate-tests/reasoning-protocol.md +17 -0
  181. package/plugin/prompts/generate-tests/tool-workflow-variants.md +61 -0
  182. package/plugin/prompts/generate-tests/tool-workflows.md +65 -0
  183. package/plugin/prompts/plan-tests.md +42 -0
  184. package/plugin/prompts/testbot-task1.md +82 -0
  185. package/plugin/skills/fix-test-import-errors/SKILL.md +98 -0
  186. package/build/prompts/test-recommendation/analysisOutputPrompt.d.ts +0 -84
  187. package/build/prompts/test-recommendation/analysisOutputPrompt.js +0 -369
  188. package/build/prompts/test-recommendation/fullRepoCatalog.d.ts +0 -7
  189. package/build/prompts/test-recommendation/fullRepoCatalog.js +0 -283
  190. package/build/prompts/test-recommendation/scopeAssessment.d.ts +0 -81
  191. package/build/prompts/test-recommendation/scopeAssessment.js +0 -359
  192. package/build/recommendation/budgeters/diversityBalancedBudgeter.d.ts +0 -7
  193. package/build/recommendation/budgeters/diversityBalancedBudgeter.js +0 -105
  194. package/build/recommendation/budgeters/fixedNBudgeter.d.ts +0 -7
  195. package/build/recommendation/budgeters/fixedNBudgeter.js +0 -11
  196. package/build/recommendation/budgeters/shared.d.ts +0 -32
  197. package/build/recommendation/budgeters/shared.js +0 -246
  198. package/build/recommendation/discriminators.d.ts +0 -37
  199. package/build/recommendation/discriminators.js +0 -379
  200. package/build/recommendation/diversity.d.ts +0 -47
  201. package/build/recommendation/diversity.js +0 -101
  202. package/build/recommendation/planRanker.d.ts +0 -65
  203. package/build/recommendation/planRanker.js +0 -83
  204. package/build/recommendation/testFixtures.d.ts +0 -25
  205. package/build/recommendation/testFixtures.js +0 -45
  206. package/build/types/FrontendIntegration.d.ts +0 -28
  207. package/build/types/FrontendIntegration.js +0 -22
  208. package/build/types/Recommendation.d.ts +0 -146
  209. package/build/types/Recommendation.js +0 -74
  210. package/build/utils/changedRoutes.d.ts +0 -29
  211. package/build/utils/changedRoutes.js +0 -87
  212. package/build/utils/frontendIntegration.d.ts +0 -9
  213. package/build/utils/frontendIntegration.js +0 -243
  214. package/build/utils/importerHop.d.ts +0 -135
  215. package/build/utils/importerHop.js +0 -489
  216. package/build/utils/pathAffinityClassification.d.ts +0 -49
  217. package/build/utils/pathAffinityClassification.js +0 -180
  218. package/build/utils/pythonMountPrefixes.d.ts +0 -25
  219. package/build/utils/pythonMountPrefixes.js +0 -347
  220. package/build/utils/repoScanner.d.ts +0 -34
  221. package/build/utils/repoScanner.js +0 -300
  222. package/build/utils/routeParsers.d.ts +0 -95
  223. package/build/utils/routeParsers.js +0 -951
  224. package/build/utils/scenarioDrafting.d.ts +0 -92
  225. package/build/utils/scenarioDrafting.js +0 -951
  226. package/build/utils/subjectEndpoints.d.ts +0 -19
  227. package/build/utils/subjectEndpoints.js +0 -98
  228. package/build/utils/uiPageEnumerator.d.ts +0 -172
  229. package/build/utils/uiPageEnumerator.js +0 -474
@@ -1,19 +0,0 @@
1
- import { DraftedScenario, SubjectEndpoint } from "../types/RepositoryAnalysis.js";
2
- import { ChangedRoute } from "./changedRoutes.js";
3
- export type { SubjectEndpoint };
4
- /**
5
- * The endpoints a scenario tests, in step order.
6
- *
7
- * 1. Every step on a changed diff line that names a resource. A test written
8
- * for a pull request is about what the pull request changed, and a
9
- * scenario can exercise more than one changed endpoint.
10
- * 2. If no step matches: the last mutating step that is not a teardown step.
11
- * Earlier mutations are usually setup (POST /products before PATCH /orders).
12
- * 3. If no mutating step remains: the last step.
13
- *
14
- * Returns an empty list only for a scenario with no steps. Every caller must
15
- * treat an empty list as "no information", never as "covered".
16
- */
17
- export declare function resolveSubjectEndpoints(scenario: DraftedScenario, opts: {
18
- changedRoutes?: ChangedRoute[];
19
- }): SubjectEndpoint[];
@@ -1,98 +0,0 @@
1
- import { findStepOnChangedRoute } from "./changedRoutes.js";
2
- import { extractResourceFromPath, isParamSegment } from "./routeParsers.js";
3
- const MUTATING_METHODS = new Set(["POST", "PUT", "PATCH", "DELETE"]);
4
- /**
5
- * A final-position DELETE that removes a resource an earlier POST created is
6
- * cleanup, not the subject. SKYR-4214 measured the cost of counting it: the
7
- * same fixture keyed as POST::flows on one run and DELETE::flows on the next,
8
- * decided only by whether the model appended a cleanup step.
9
- *
10
- * The step count matters. A two-step POST-then-DELETE has no room for a
11
- * verification step, so the DELETE is what the test is about; the cleanup shape
12
- * always has a step between the create and the delete. A scenario that asserts
13
- * the delete worked (…DELETE, then GET 404) leaves the DELETE off the final
14
- * position, so it is not excluded either.
15
- */
16
- function isTeardownStep(steps, index) {
17
- const step = steps[index];
18
- if (index !== steps.length - 1)
19
- return false;
20
- if ((step.method ?? "").toUpperCase() !== "DELETE")
21
- return false;
22
- if (steps.length < 3)
23
- return false;
24
- const resource = extractResourceFromPath(step.path ?? "");
25
- // "unknown" is the sentinel for a path that names no resource, so comparing
26
- // it by equality makes any two unidentifiable paths look like the same
27
- // resource: `POST /` … `DELETE /{id}` read as create-then-cleanup and the
28
- // DELETE — the real subject — got skipped. Only a named resource can pair.
29
- if (resource === "unknown")
30
- return false;
31
- return steps.slice(0, index).some((earlier) => (earlier.method ?? "").toUpperCase() === "POST" &&
32
- extractResourceFromPath(earlier.path ?? "") === resource);
33
- }
34
- /**
35
- * A route declaration made only of parameter segments (or none at all, e.g.
36
- * "/" or "") names no resource, so it cannot tell one endpoint from another —
37
- * every step's path ends in the same param segment. SKYR-4214: a changed
38
- * `@router.delete("/{id}")` line matched a step's trailing DELETE cleanup
39
- * step just as well as the step it was actually meant to catch, which
40
- * reinstated the bug this file exists to fix. Rule 1 only accepts a route
41
- * that contributes at least one non-parameter segment.
42
- */
43
- function routeIdentifiesResource(routePath) {
44
- return routePath.split("/").filter(Boolean).some((segment) => !isParamSegment(segment));
45
- }
46
- /**
47
- * The endpoints a scenario tests, in step order.
48
- *
49
- * 1. Every step on a changed diff line that names a resource. A test written
50
- * for a pull request is about what the pull request changed, and a
51
- * scenario can exercise more than one changed endpoint.
52
- * 2. If no step matches: the last mutating step that is not a teardown step.
53
- * Earlier mutations are usually setup (POST /products before PATCH /orders).
54
- * 3. If no mutating step remains: the last step.
55
- *
56
- * Returns an empty list only for a scenario with no steps. Every caller must
57
- * treat an empty list as "no information", never as "covered".
58
- */
59
- export function resolveSubjectEndpoints(scenario, opts) {
60
- const steps = scenario.steps ?? [];
61
- if (steps.length === 0)
62
- return [];
63
- const changedRoutes = (opts.changedRoutes ?? []).filter((route) => routeIdentifiesResource(route.path));
64
- if (changedRoutes.length > 0) {
65
- // Attribute PER ROUTE, not per step. A diff-extracted route is local to its
66
- // own router declaration — the mount prefix lives in another file, so a bare
67
- // `POST /items` suffix-matches a step on `/orders/{id}/items` and one on
68
- // `/products/{id}/items` equally. Recording both would invent a subject the
69
- // diff does not name, and dedup then needs every unrelated key covered
70
- // before the candidate can be removed.
71
- //
72
- // A route matching exactly one step names that step. A route matching
73
- // several names none of them: there is no evidence for choosing, and a
74
- // guess is worse than an omission. Other routes still contribute, so a
75
- // scenario that genuinely tests two changed endpoints keeps both subjects.
76
- const attributed = [];
77
- for (const route of changedRoutes) {
78
- const matches = steps.filter((step) => findStepOnChangedRoute([step], [route]));
79
- const distinct = new Map(matches.map((step) => [`${step.method} ${step.path}`, step]));
80
- if (distinct.size === 1)
81
- attributed.push([...distinct.values()][0]);
82
- }
83
- // Keep step order and drop the duplicates two routes can both name.
84
- const onChanged = steps.filter((step) => attributed.includes(step));
85
- if (onChanged.length > 0) {
86
- return onChanged.map((step) => ({ method: step.method, path: step.path }));
87
- }
88
- }
89
- for (let i = steps.length - 1; i >= 0; i--) {
90
- if (!MUTATING_METHODS.has((steps[i].method ?? "").toUpperCase()))
91
- continue;
92
- if (isTeardownStep(steps, i))
93
- continue;
94
- return [{ method: steps[i].method, path: steps[i].path }];
95
- }
96
- const last = steps[steps.length - 1];
97
- return [{ method: last.method, path: last.path }];
98
- }
@@ -1,172 +0,0 @@
1
- /**
2
- * Programmatic UI page enumeration — translates "which frontend files changed"
3
- * into "which URLs should the agent capture blueprints for."
4
- *
5
- * Replaces the prose-driven Task 0 strategy ladder in the testbot prompt with
6
- * deterministic code so the candidate page list lives in the stateFile and is
7
- * reusable across analyze_changes consumers (testbot, analyze_test_health,
8
- * future blueprint-grounded recommenders).
9
- *
10
- * Strategies, tried in order:
11
- *
12
- * Strategy 1 — Framework route grep
13
- * Translate file-system-routed component paths directly to URLs. Covers
14
- * Next.js (app/ and pages/), Nuxt / Vue Router file-based, and SvelteKit.
15
- * Gated on detection of a framework config file in the repo.
16
- *
17
- * Strategy 1b — Import graph
18
- * For a changed file that is not itself a route (a component, a constants
19
- * module), map the production files that import it through the same
20
- * filesystem-route mapper. Uses the importer list the production-importer integration
21
- * check already computed. Merged with strategy 1 rather than tried after it.
22
- *
23
- * Strategy 2 — Source-grounded routes
24
- * Walks router/App files with the TS Compiler API for code-defined
25
- * route declarations like `<Route path="/cart" element={<Cart/>}>`.
26
- * Matches each route's component file OR declaration file against the
27
- * changed-file list (so router rewrites surface their routes even when
28
- * the component itself is unchanged). Handles React Router string-literal
29
- * paths, cross-file constant resolution, Vue Router object literals,
30
- * and Directus `defineModule` aggregation. See `sourceRouteExtractor.ts`.
31
- *
32
- * Strategy 3 — Root fallback
33
- * Read the workspace's frontend baseUrl and treat it as the single
34
- * candidate page. Always available when a frontend service is configured.
35
- *
36
- * When no frontend baseUrl can be resolved, strategies 1/1b still run and their
37
- * results are returned as bare URL paths (`baseUrlResolved: false`) so the agent
38
- * can prefix the base URL it discovers; strategies 2–3 need a host and are skipped.
39
- */
40
- import type { FrontendFileIntegration } from "../types/FrontendIntegration.js";
41
- export type CandidateUiPageStrategy = "framework-route-grep" | "import-graph" | "source-grounded-routes" | "dart-go-router" | "root-fallback";
42
- export interface CandidateUiPage {
43
- /**
44
- * Fully qualified URL (workspace baseUrl + framework-derived path), or a bare
45
- * URL path when `baseUrlResolved` is false.
46
- */
47
- url: string;
48
- /** Source files that suggested this page (for traceability). */
49
- sourcedFrom: string[];
50
- /** Which strategy enumerated it. */
51
- strategy: CandidateUiPageStrategy;
52
- /**
53
- * Present (false) only when no frontend baseUrl could be resolved and `url`
54
- * is a bare path the agent must prefix. Absent means `url` is complete.
55
- */
56
- baseUrlResolved?: false;
57
- /** import-graph only: the route files that import `sourcedFrom` and produced this path. */
58
- via?: string[];
59
- }
60
- /**
61
- * Upper bound on candidate pages. Strategy 1b is bounded by changed files ×
62
- * importers, and every candidate costs the agent a navigate + a capture, so the
63
- * list is cut here — direct route matches first, then import-graph pages that
64
- * render the most changed files.
65
- */
66
- export declare const MAX_CANDIDATE_PAGES = 10;
67
- /**
68
- * File-system → URL mapping for filesystem-routed frameworks.
69
- *
70
- * Returns the URL path (no host) when the file is a route entrypoint, or
71
- * null when the file isn't a route in any recognized convention.
72
- *
73
- * The `null` cases include component files used by routes (e.g. shared
74
- * widgets in `components/`), API handlers (e.g. Next.js `pages/api/*`),
75
- * and arbitrary `.ts`/`.js` modules under frontend directories. These
76
- * are picked up by strategy 2 (import-graph walk, future) or by strategy
77
- * 3 (root fallback).
78
- */
79
- export declare function frameworkFileToUrlPath(filePath: string): string | null;
80
- /**
81
- * Detect whether the repository is configured for filesystem-based routing.
82
- *
83
- * Strategy 1 maps file paths to URLs based on conventions (Next.js Pages
84
- * Router, Nuxt, SvelteKit). Without a positive signal that the framework
85
- * is actually configured, a repo that just *happens* to have a `pages/`
86
- * directory (e.g. React with conventional layout, Vue with route-config
87
- * code) produces false-positive URLs. This guard suppresses strategy 1
88
- * for those repos so they fall through to root-fallback.
89
- *
90
- * Looks for framework config files in the repo root, common subdirectories,
91
- * and the `frontendFiles[]`-derived candidate frontend roots.
92
- */
93
- export declare function detectsFilesystemRouting(repositoryPath: string): boolean;
94
- /** Strategy 1 only (no import graph), joined to `baseUrl`. */
95
- export declare function findCandidatePagesByFrameworkRoute(frontendFiles: string[], baseUrl: string, repositoryPath?: string): CandidateUiPage[];
96
- /**
97
- * Strategy 2 implementation. Walks router/App files with the TS Compiler API
98
- * to find route declarations (`<Route path="/cart" element={<Cart/>}>`),
99
- * matches each declaration's component file against the changed-file list,
100
- * and emits one CandidateUiPage per matching route.
101
- *
102
- * Slice 3a covers string-literal `path` attributes only — `path={CONST}` and
103
- * Vue Router object literals are deferred to slice 3b.
104
- *
105
- * Returns empty when no route declarations match the changed files (which is
106
- * also the right answer for SPAs without client-side routing — they fall
107
- * through to root-fallback).
108
- */
109
- export declare function findCandidatePagesBySourceRoute(frontendFiles: string[], baseUrl: string, repositoryPath: string): CandidateUiPage[];
110
- /**
111
- * Strategy 2.5: walk the repo's Dart files for GoRoute(path: '...') calls.
112
- * Gated on `hasFlutterSdkDep(repoPath)` so non-Flutter Dart projects (e.g.
113
- * shelf_router servers) don't accidentally emit URLs.
114
- *
115
- * Diff-matching: each GoRoute references its screen widget via
116
- * `builder:`/`pageBuilder:` (e.g. `AuthorsScreen`). The extractor resolves
117
- * those identifiers through the route file's imports to absolute screen
118
- * file paths. We surface only routes whose screen file appears in the
119
- * changed-file list. Falls back to all-routes when no route's screen
120
- * file matches — preserves coverage for "router untouched, screen edited"
121
- * cases when the import-resolution heuristic doesn't find a match.
122
- *
123
- * Filters applied:
124
- * 1. Drop redirect-only routes (`redirect:` with no `builder:`/`pageBuilder:`).
125
- * These have no UI to render — navigating there is wasted work.
126
- * 2. Drop nested relative children (paths that don't start with `/`).
127
- * Without parent-path composition the URL is meaningless.
128
- *
129
- * Returns empty when the repo isn't Flutter or no GoRoute calls are
130
- * found — caller falls through to root-fallback.
131
- */
132
- export declare function findCandidatePagesByDartRoute(repositoryPath: string, baseUrl: string, frontendFiles: string[]): CandidateUiPage[];
133
- /**
134
- * Strategy 3: when strategies 1+2 yield nothing, fall back to the workspace's
135
- * frontend baseUrl as the single candidate page. The agent's downstream
136
- * explore-and-discover step can then surface gated UI from the root.
137
- *
138
- * Returns null when the workspace has no recognizable frontend service.
139
- */
140
- export declare function findRootFallbackPage(repositoryPath: string): Promise<CandidateUiPage | null>;
141
- /**
142
- * Resolves the frontend service's baseUrl from the workspace config.
143
- *
144
- * Returns the baseUrl string with environment variable override precedence:
145
- * 1. Per-service override: `SKYRAMP_TEST_SERVICE_URL_<NAME>` (where <NAME>
146
- * is the picked frontend service's serviceName, sanitized via
147
- * `sanitizeServiceName`)
148
- * 2. Global override: `SKYRAMP_TEST_BASE_URL` (single service or all
149
- * services share one URL). Also honored when the workspace declares no
150
- * services at all — the action can know the URL without a workspace entry.
151
- * 3. Static workspace.yml value: `api.baseUrl` from the picked frontend
152
- * service
153
- *
154
- * Returns null when neither the environment nor any service has a usable URL.
155
- *
156
- * Exported (vs private) so analyze_changes and future tools can reuse the
157
- * same selection without re-implementing it.
158
- */
159
- export declare function pickFrontendBaseUrl(repositoryPath: string): Promise<string | null>;
160
- /**
161
- * Run the strategy ladder: framework route grep + import graph (1/1b) →
162
- * source-grounded routes (2) → Dart GoRouter (2.5) → root fallback (3). Each
163
- * later strategy is consulted only if the earlier ones produced no candidates.
164
- *
165
- * `integration` is the production-importer check for the same files; when given,
166
- * changed non-route files resolve to the pages that import them.
167
- *
168
- * Without a resolvable frontend baseUrl only strategies 1/1b can run; their
169
- * paths are returned with `baseUrlResolved: false` for the agent to prefix.
170
- * Returns empty only when nothing resolves at all.
171
- */
172
- export declare function enumerateCandidateUiPages(repositoryPath: string, frontendFiles: string[], integration?: FrontendFileIntegration[]): Promise<CandidateUiPage[]>;