@skyramp/mcp 0.3.2-rc.pom-3 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (289) hide show
  1. package/build/commands/commandLibrary.d.ts +1 -0
  2. package/build/commands/commandLibrary.js +19 -13
  3. package/build/commands/localDevTestChangesCommand.d.ts +15 -0
  4. package/build/commands/localDevTestChangesCommand.js +201 -0
  5. package/build/index.js +80 -6
  6. package/build/prompts/code-reuse.js +3 -0
  7. package/build/prompts/enhance-assertions/sharedAssertionRules.d.ts +1 -0
  8. package/build/prompts/enhance-assertions/sharedAssertionRules.js +17 -0
  9. package/build/prompts/initialize-workspace/initializeWorkspacePrompt.js +11 -9
  10. package/build/prompts/local-dev/local-dev-plan.d.ts +35 -0
  11. package/build/prompts/local-dev/local-dev-plan.js +429 -0
  12. package/build/prompts/local-dev/local-dev-prompts.d.ts +4 -0
  13. package/build/prompts/local-dev/local-dev-prompts.js +190 -0
  14. package/build/prompts/pom-aware-code-reuse.js +12 -0
  15. package/build/prompts/prompt-utils.d.ts +8 -0
  16. package/build/prompts/prompt-utils.js +33 -0
  17. package/build/prompts/sut-setup/modes/adaptWorkflowPrompt.js +37 -14
  18. package/build/prompts/sut-setup/shared.js +16 -12
  19. package/build/prompts/test-recommendation/analysisOutputPrompt.js +21 -29
  20. package/build/prompts/test-recommendation/scopeAssessment.d.ts +24 -7
  21. package/build/prompts/test-recommendation/scopeAssessment.js +111 -12
  22. package/build/prompts/test-recommendation/test-recommendation-prompt.js +41 -4
  23. package/build/prompts/testbot/testbot-prompts.d.ts +0 -5
  24. package/build/prompts/testbot/testbot-prompts.js +32 -52
  25. package/build/recommendation/planRanker.d.ts +15 -2
  26. package/build/recommendation/planRanker.js +76 -5
  27. package/build/resources/testbotResource.js +2 -1
  28. package/build/services/AnalyticsService.d.ts +1 -1
  29. package/build/services/TestExecutionService.d.ts +2 -1
  30. package/build/services/TestExecutionService.js +8 -3
  31. package/build/services/TestGenerationService.d.ts +2 -2
  32. package/build/services/TestGenerationService.js +39 -21
  33. package/build/services/containerEnv.js +3 -1
  34. package/build/tool-phases.js +6 -0
  35. package/build/tools/code-refactor/codeReuseTool.js +43 -4
  36. package/build/tools/code-refactor/enhanceAssertionsTool.js +68 -18
  37. package/build/tools/code-refactor/reuse-outcome.d.ts +109 -0
  38. package/build/tools/code-refactor/reuse-outcome.js +158 -0
  39. package/build/tools/code-refactor/reuse-state.d.ts +45 -0
  40. package/build/tools/code-refactor/reuse-state.js +140 -0
  41. package/build/tools/enrichTestWithMocksTool.d.ts +28 -0
  42. package/build/tools/enrichTestWithMocksTool.js +726 -0
  43. package/build/tools/executeSkyrampTestTool.d.ts +11 -0
  44. package/build/tools/executeSkyrampTestTool.js +62 -21
  45. package/build/tools/generate-tests/batchMockGenerationTool.d.ts +106 -0
  46. package/build/tools/generate-tests/batchMockGenerationTool.js +545 -0
  47. package/build/tools/generate-tests/generateBatchScenarioRestTool.js +25 -23
  48. package/build/tools/generate-tests/generateContractRestTool.js +2 -2
  49. package/build/tools/generate-tests/generateE2ERestTool.d.ts +1 -1
  50. package/build/tools/generate-tests/generateE2ERestTool.js +1 -1
  51. package/build/tools/generate-tests/generateLoadRestTool.d.ts +1 -1
  52. package/build/tools/generate-tests/generateLoadRestTool.js +1 -1
  53. package/build/tools/generate-tests/generateMockRestTool.d.ts +179 -6
  54. package/build/tools/generate-tests/generateMockRestTool.js +391 -22
  55. package/build/tools/generate-tests/loadTestSchema.d.ts +1 -1
  56. package/build/tools/generate-tests/planGuard.js +2 -22
  57. package/build/tools/generateEnrichedIntegrationTestTool.d.ts +25 -0
  58. package/build/tools/generateEnrichedIntegrationTestTool.js +235 -0
  59. package/build/tools/localDevWorkerComposeTool.d.ts +24 -0
  60. package/build/tools/localDevWorkerComposeTool.js +264 -0
  61. package/build/tools/one-click/oneClickTool.d.ts +13 -0
  62. package/build/tools/one-click/oneClickTool.js +195 -24
  63. package/build/tools/preflightMockCheckTool.d.ts +2 -0
  64. package/build/tools/preflightMockCheckTool.js +96 -0
  65. package/build/tools/queryProxyMocksTool.d.ts +70 -0
  66. package/build/tools/queryProxyMocksTool.js +522 -0
  67. package/build/tools/runExistingTestsTool.d.ts +31 -0
  68. package/build/tools/runExistingTestsTool.js +214 -13
  69. package/build/tools/submitReportTool.js +38 -3
  70. package/build/tools/test-management/analyzeChangesTool.d.ts +2 -1
  71. package/build/tools/test-management/analyzeChangesTool.js +63 -40
  72. package/build/tools/test-management/registerTestPlanTool.js +55 -7
  73. package/build/tools/trace/startTraceCollectionTool.js +3 -3
  74. package/build/types/FrontendIntegration.d.ts +3 -0
  75. package/build/types/FrontendIntegration.js +3 -0
  76. package/build/types/OneClickCommands.d.ts +1 -1
  77. package/build/types/Recommendation.d.ts +20 -0
  78. package/build/types/Recommendation.js +32 -6
  79. package/build/types/RepositoryAnalysis.d.ts +131 -14
  80. package/build/types/RepositoryAnalysis.js +16 -2
  81. package/build/types/ReuseOutcome.d.ts +63 -0
  82. package/build/types/ReuseOutcome.js +33 -0
  83. package/build/types/TestExecution.d.ts +1 -0
  84. package/build/types/TestTypes.d.ts +25 -7
  85. package/build/types/TestTypes.js +22 -6
  86. package/build/types/TestbotReport.d.ts +7 -0
  87. package/build/types/index.d.ts +2 -0
  88. package/build/types/index.js +1 -0
  89. package/build/utils/AnalysisStateManager.d.ts +26 -0
  90. package/build/utils/AnalysisStateManager.js +31 -1
  91. package/build/utils/analyze-openapi.js +18 -1
  92. package/build/utils/branchDiff.d.ts +17 -1
  93. package/build/utils/branchDiff.js +99 -14
  94. package/build/utils/featureFlags.d.ts +31 -0
  95. package/build/utils/featureFlags.js +37 -0
  96. package/build/utils/frontendIntegration.js +8 -1
  97. package/build/utils/grpcMockValidation.d.ts +1 -0
  98. package/build/utils/grpcMockValidation.js +49 -0
  99. package/build/utils/httpMethodValidation.d.ts +4 -0
  100. package/build/utils/httpMethodValidation.js +15 -0
  101. package/build/utils/logger.js +1 -1
  102. package/build/utils/mockCompatibility.d.ts +49 -0
  103. package/build/utils/mockCompatibility.js +82 -0
  104. package/build/utils/pom-scope/pom-files.js +7 -0
  105. package/build/utils/pom-verify/bindings.js +11 -1
  106. package/build/utils/pom-verify/re-exports.d.ts +10 -0
  107. package/build/utils/pom-verify/re-exports.js +61 -0
  108. package/build/utils/pom-verify/resolve.d.ts +4 -1
  109. package/build/utils/pom-verify/resolve.js +7 -4
  110. package/build/utils/pom-verify/verify.d.ts +5 -0
  111. package/build/utils/pom-verify/verify.js +25 -3
  112. package/build/utils/progress.js +10 -5
  113. package/build/utils/proxy-terminal.js +3 -3
  114. package/build/utils/routeParsers.d.ts +3 -9
  115. package/build/utils/routeParsers.js +79 -4
  116. package/build/utils/utils.js +2 -2
  117. package/build/utils/versions.d.ts +4 -3
  118. package/build/utils/versions.js +3 -1
  119. package/build/utils/workspaceAuth.d.ts +46 -0
  120. package/build/utils/workspaceAuth.js +156 -1
  121. package/build/workspace/testSuites.d.ts +2 -1
  122. package/build/workspace/testSuites.js +1 -1
  123. package/build/workspace/workspace.d.ts +108 -32
  124. package/build/workspace/workspace.js +32 -4
  125. package/package.json +5 -2
  126. package/build/adapters/jestAdapter.test.d.ts +0 -1
  127. package/build/adapters/jestAdapter.test.js +0 -93
  128. package/build/adapters/mochaAdapter.test.d.ts +0 -1
  129. package/build/adapters/mochaAdapter.test.js +0 -63
  130. package/build/adapters/playwrightAdapter.test.d.ts +0 -1
  131. package/build/adapters/playwrightAdapter.test.js +0 -169
  132. package/build/adapters/pytestAdapter.test.d.ts +0 -1
  133. package/build/adapters/pytestAdapter.test.js +0 -90
  134. package/build/prompts/code-reuse.test.d.ts +0 -1
  135. package/build/prompts/code-reuse.test.js +0 -62
  136. package/build/prompts/pom-aware-code-reuse.test.d.ts +0 -1
  137. package/build/prompts/pom-aware-code-reuse.test.js +0 -11
  138. package/build/prompts/test-maintenance/drift-analysis-prompt.test.d.ts +0 -1
  139. package/build/prompts/test-maintenance/drift-analysis-prompt.test.js +0 -51
  140. package/build/prompts/test-recommendation/analysisOutputPrompt.test.d.ts +0 -1
  141. package/build/prompts/test-recommendation/analysisOutputPrompt.test.js +0 -264
  142. package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.d.ts +0 -1
  143. package/build/prompts/test-recommendation/mergeEnrichedScenarios.test.js +0 -126
  144. package/build/prompts/test-recommendation/promptPlan.test.d.ts +0 -1
  145. package/build/prompts/test-recommendation/promptPlan.test.js +0 -336
  146. package/build/prompts/test-recommendation/scopeAssessment.test.d.ts +0 -1
  147. package/build/prompts/test-recommendation/scopeAssessment.test.js +0 -371
  148. package/build/prompts/test-recommendation/test-recommendation-prompt.test.d.ts +0 -1
  149. package/build/prompts/test-recommendation/test-recommendation-prompt.test.js +0 -1925
  150. package/build/prompts/testbot/testbot-prompts.test.d.ts +0 -1
  151. package/build/prompts/testbot/testbot-prompts.test.js +0 -451
  152. package/build/recommendation/budgeters/diversityBalancedBudgeter.test.d.ts +0 -1
  153. package/build/recommendation/budgeters/diversityBalancedBudgeter.test.js +0 -138
  154. package/build/recommendation/budgeters/fixedNBudgeter.test.d.ts +0 -1
  155. package/build/recommendation/budgeters/fixedNBudgeter.test.js +0 -66
  156. package/build/recommendation/discriminators.test.d.ts +0 -1
  157. package/build/recommendation/discriminators.test.js +0 -324
  158. package/build/recommendation/diversity.test.d.ts +0 -1
  159. package/build/recommendation/diversity.test.js +0 -77
  160. package/build/recommendation/planRanker.test.d.ts +0 -1
  161. package/build/recommendation/planRanker.test.js +0 -110
  162. package/build/resources/testbotResource.test.d.ts +0 -1
  163. package/build/resources/testbotResource.test.js +0 -44
  164. package/build/services/AnalyticsService.test.d.ts +0 -1
  165. package/build/services/AnalyticsService.test.js +0 -86
  166. package/build/services/ScenarioGenerationService.integration.test.d.ts +0 -1
  167. package/build/services/ScenarioGenerationService.integration.test.js +0 -162
  168. package/build/services/ScenarioGenerationService.test.d.ts +0 -1
  169. package/build/services/ScenarioGenerationService.test.js +0 -414
  170. package/build/services/TestDiscoveryService.test.d.ts +0 -1
  171. package/build/services/TestDiscoveryService.test.js +0 -983
  172. package/build/services/TestExecutionService.test.d.ts +0 -1
  173. package/build/services/TestExecutionService.test.js +0 -1032
  174. package/build/services/TestGenerationService.test.d.ts +0 -1
  175. package/build/services/TestGenerationService.test.js +0 -578
  176. package/build/tool-phase-coverage.test.d.ts +0 -1
  177. package/build/tool-phase-coverage.test.js +0 -49
  178. package/build/tools/code-refactor/codeReuseTool.test.d.ts +0 -1
  179. package/build/tools/code-refactor/codeReuseTool.test.js +0 -572
  180. package/build/tools/generate-tests/generateBatchScenarioRestTool.test.d.ts +0 -1
  181. package/build/tools/generate-tests/generateBatchScenarioRestTool.test.js +0 -433
  182. package/build/tools/generate-tests/generateContractRestTool.test.d.ts +0 -1
  183. package/build/tools/generate-tests/generateContractRestTool.test.js +0 -142
  184. package/build/tools/generate-tests/generateIntegrationRestTool.test.d.ts +0 -1
  185. package/build/tools/generate-tests/generateIntegrationRestTool.test.js +0 -159
  186. package/build/tools/generate-tests/generateLoadRestTool.test.d.ts +0 -1
  187. package/build/tools/generate-tests/generateLoadRestTool.test.js +0 -169
  188. package/build/tools/generate-tests/generateUIRestTool.test.d.ts +0 -1
  189. package/build/tools/generate-tests/generateUIRestTool.test.js +0 -32
  190. package/build/tools/generate-tests/planGuard.test.d.ts +0 -1
  191. package/build/tools/generate-tests/planGuard.test.js +0 -185
  192. package/build/tools/generate-tests/scenarioLint.test.d.ts +0 -1
  193. package/build/tools/generate-tests/scenarioLint.test.js +0 -100
  194. package/build/tools/runExistingTestsTool.test.d.ts +0 -1
  195. package/build/tools/runExistingTestsTool.test.js +0 -379
  196. package/build/tools/submitReportTool.test.d.ts +0 -1
  197. package/build/tools/submitReportTool.test.js +0 -1428
  198. package/build/tools/test-management/actionsTool.test.d.ts +0 -1
  199. package/build/tools/test-management/actionsTool.test.js +0 -436
  200. package/build/tools/test-management/analyzeChangesTool.test.d.ts +0 -1
  201. package/build/tools/test-management/analyzeChangesTool.test.js +0 -522
  202. package/build/tools/test-management/analyzeTestHealthTool.test.d.ts +0 -1
  203. package/build/tools/test-management/analyzeTestHealthTool.test.js +0 -385
  204. package/build/tools/test-management/registerTestPlanTool.test.d.ts +0 -1
  205. package/build/tools/test-management/registerTestPlanTool.test.js +0 -296
  206. package/build/tools/trace/resolveSaveStoragePath.test.d.ts +0 -1
  207. package/build/tools/trace/resolveSaveStoragePath.test.js +0 -17
  208. package/build/tools/trace/resolveSessionPaths.test.d.ts +0 -1
  209. package/build/tools/trace/resolveSessionPaths.test.js +0 -104
  210. package/build/tools/trace/sessionState.test.d.ts +0 -1
  211. package/build/tools/trace/sessionState.test.js +0 -17
  212. package/build/tools/workspace/initializeWorkspaceTool.test.d.ts +0 -1
  213. package/build/tools/workspace/initializeWorkspaceTool.test.js +0 -139
  214. package/build/tools/workspace/serviceUpsert.test.d.ts +0 -1
  215. package/build/tools/workspace/serviceUpsert.test.js +0 -50
  216. package/build/utils/AnalysisStateManager.test.d.ts +0 -1
  217. package/build/utils/AnalysisStateManager.test.js +0 -134
  218. package/build/utils/dartRouteExtractor.test.d.ts +0 -1
  219. package/build/utils/dartRouteExtractor.test.js +0 -307
  220. package/build/utils/docker.test.d.ts +0 -1
  221. package/build/utils/docker.test.js +0 -114
  222. package/build/utils/featureFlags.test.d.ts +0 -1
  223. package/build/utils/featureFlags.test.js +0 -81
  224. package/build/utils/fileWalk.test.d.ts +0 -1
  225. package/build/utils/fileWalk.test.js +0 -252
  226. package/build/utils/frontendIntegration.test.d.ts +0 -1
  227. package/build/utils/frontendIntegration.test.js +0 -229
  228. package/build/utils/frontendSelectors.test.d.ts +0 -1
  229. package/build/utils/frontendSelectors.test.js +0 -118
  230. package/build/utils/gitStaging.test.d.ts +0 -1
  231. package/build/utils/gitStaging.test.js +0 -111
  232. package/build/utils/httpDefaults.test.d.ts +0 -1
  233. package/build/utils/httpDefaults.test.js +0 -21
  234. package/build/utils/importerHop.test.d.ts +0 -1
  235. package/build/utils/importerHop.test.js +0 -469
  236. package/build/utils/pathAffinityClassification.test.d.ts +0 -1
  237. package/build/utils/pathAffinityClassification.test.js +0 -208
  238. package/build/utils/planMatchKeys.test.d.ts +0 -1
  239. package/build/utils/planMatchKeys.test.js +0 -123
  240. package/build/utils/pom-scope/index.test.d.ts +0 -1
  241. package/build/utils/pom-scope/index.test.js +0 -278
  242. package/build/utils/pom-scope/pom-files.test.d.ts +0 -1
  243. package/build/utils/pom-scope/pom-files.test.js +0 -29
  244. package/build/utils/pom-scope/scoring.test.d.ts +0 -1
  245. package/build/utils/pom-scope/scoring.test.js +0 -39
  246. package/build/utils/pom-scope/selector-extractor.test.d.ts +0 -1
  247. package/build/utils/pom-scope/selector-extractor.test.js +0 -67
  248. package/build/utils/pom-verify/bindings.test.d.ts +0 -1
  249. package/build/utils/pom-verify/bindings.test.js +0 -164
  250. package/build/utils/pom-verify/calls.test.d.ts +0 -1
  251. package/build/utils/pom-verify/calls.test.js +0 -61
  252. package/build/utils/pom-verify/resolve.test.d.ts +0 -1
  253. package/build/utils/pom-verify/resolve.test.js +0 -114
  254. package/build/utils/pom-verify/verify.test.d.ts +0 -1
  255. package/build/utils/pom-verify/verify.test.js +0 -374
  256. package/build/utils/pr-comment-parser.test.d.ts +0 -1
  257. package/build/utils/pr-comment-parser.test.js +0 -428
  258. package/build/utils/progress.test.d.ts +0 -1
  259. package/build/utils/progress.test.js +0 -37
  260. package/build/utils/projectMetadata.test.d.ts +0 -1
  261. package/build/utils/projectMetadata.test.js +0 -172
  262. package/build/utils/pythonMountPrefixes.test.d.ts +0 -1
  263. package/build/utils/pythonMountPrefixes.test.js +0 -113
  264. package/build/utils/repoScanner.test.d.ts +0 -1
  265. package/build/utils/repoScanner.test.js +0 -190
  266. package/build/utils/reportVerification.test.d.ts +0 -1
  267. package/build/utils/reportVerification.test.js +0 -185
  268. package/build/utils/routeParsers.test.d.ts +0 -1
  269. package/build/utils/routeParsers.test.js +0 -1011
  270. package/build/utils/scenarioDrafting.test.d.ts +0 -1
  271. package/build/utils/scenarioDrafting.test.js +0 -876
  272. package/build/utils/sourceRouteExtractor.test.d.ts +0 -1
  273. package/build/utils/sourceRouteExtractor.test.js +0 -738
  274. package/build/utils/telemetry.test.d.ts +0 -1
  275. package/build/utils/telemetry.test.js +0 -70
  276. package/build/utils/trace-parser.test.d.ts +0 -6
  277. package/build/utils/trace-parser.test.js +0 -140
  278. package/build/utils/uiPageEnumerator.test.d.ts +0 -1
  279. package/build/utils/uiPageEnumerator.test.js +0 -824
  280. package/build/utils/utils.test.d.ts +0 -1
  281. package/build/utils/utils.test.js +0 -103
  282. package/build/utils/walkerCharacterization.test.d.ts +0 -1
  283. package/build/utils/walkerCharacterization.test.js +0 -233
  284. package/build/utils/workspaceAuth.test.d.ts +0 -1
  285. package/build/utils/workspaceAuth.test.js +0 -260
  286. package/build/workspace/testSuites.test.d.ts +0 -1
  287. package/build/workspace/testSuites.test.js +0 -23
  288. package/build/workspace/workspace.test.d.ts +0 -1
  289. package/build/workspace/workspace.test.js +0 -264
@@ -1,336 +0,0 @@
1
- import { PromptPlan } from "./promptPlan.js";
2
- // ---------------------------------------------------------------------------
3
- // Core numbering invariants
4
- // ---------------------------------------------------------------------------
5
- describe("PromptPlan — main step numbering", () => {
6
- it("generates sequential main-step labels starting at 1", () => {
7
- const plan = new PromptPlan()
8
- .addPhase("p", "Phase")
9
- .step("A", "Step A", () => "body-a")
10
- .step("B", "Step B", () => "body-b")
11
- .step("C", "Step C", () => "body-c")
12
- .done();
13
- expect(plan.labels.A).toBe("1");
14
- expect(plan.labels.B).toBe("2");
15
- expect(plan.labels.C).toBe("3");
16
- });
17
- it("supports startFrom: 0 for execution-plan style (Step 0, Step 1, …)", () => {
18
- const plan = new PromptPlan({ startFrom: 0 })
19
- .addPhase("p", "Phase")
20
- .step("COVERAGE", "Coverage", () => "")
21
- .step("ENRICH", "Enrich", () => "")
22
- .step("DIVERSITY", "Diversity", () => "")
23
- .step("EXECUTE", "Execute", () => "")
24
- .done();
25
- expect(plan.labels.COVERAGE).toBe("0");
26
- expect(plan.labels.ENRICH).toBe("1");
27
- expect(plan.labels.DIVERSITY).toBe("2");
28
- expect(plan.labels.EXECUTE).toBe("3");
29
- });
30
- it("main step labels are compile-time stable — identical to labelFor() with any params", () => {
31
- const plan = new PromptPlan()
32
- .addPhase("p", "Phase")
33
- .step("X", "X", () => "")
34
- .step("Y", "Y", () => "")
35
- .done();
36
- const params = { flag: true };
37
- expect(plan.labels.X).toBe(plan.labelFor("X", params));
38
- expect(plan.labels.Y).toBe(plan.labelFor("Y", params));
39
- });
40
- it("auto-renumbers when a step is inserted — key contract of the abstraction", () => {
41
- const plan = new PromptPlan()
42
- .addPhase("p", "Phase")
43
- .step("FIRST", "First", () => "")
44
- .step("NEW", "Newly inserted", () => "") // inserted before what was "2"
45
- .step("SECOND", "Second", () => "")
46
- .done();
47
- expect(plan.labels.FIRST).toBe("1");
48
- expect(plan.labels.NEW).toBe("2");
49
- expect(plan.labels.SECOND).toBe("3"); // auto-renumbered from "2" to "3"
50
- });
51
- });
52
- // ---------------------------------------------------------------------------
53
- // Sub-step numbering
54
- // ---------------------------------------------------------------------------
55
- describe("PromptPlan — sub-step numbering", () => {
56
- it("assigns sequential sub-step labels within their parent (1.1, 1.2, 2.1, …)", () => {
57
- const plan = new PromptPlan()
58
- .addPhase("p", "Phase")
59
- .step("READ", "Read", () => "")
60
- .subStep("PATHS", "Paths", () => "")
61
- .step("EXTRACT", "Extract", () => "")
62
- .subStep("TRACE", "Trace", () => "", { when: (p) => p.flag })
63
- .done();
64
- expect(plan.labels.READ).toBe("1");
65
- expect(plan.labels.PATHS).toBe("1.1");
66
- expect(plan.labels.EXTRACT).toBe("2");
67
- // TRACE is conditional — NOT in labels map
68
- expect(plan.labels.TRACE).toBeUndefined();
69
- });
70
- it("sub() does not advance the main counter", () => {
71
- const plan = new PromptPlan()
72
- .addPhase("p", "Phase")
73
- .step("A", "A", () => "")
74
- .subStep("A1", "A1", () => "")
75
- .subStep("A2", "A2", () => "")
76
- .step("B", "B", () => "")
77
- .done();
78
- expect(plan.labels.A).toBe("1");
79
- expect(plan.labels.A1).toBe("1.1");
80
- expect(plan.labels.A2).toBe("1.2");
81
- expect(plan.labels.B).toBe("2");
82
- });
83
- it("conditional sub-step is absent from static labels map", () => {
84
- const plan = new PromptPlan()
85
- .addPhase("p", "Phase")
86
- .step("A", "A", () => "")
87
- .subStep("COND", "Conditional", () => "", { when: (p) => p.flag })
88
- .done();
89
- expect(plan.labels.A).toBe("1");
90
- expect(plan.labels.COND).toBeUndefined();
91
- });
92
- });
93
- // ---------------------------------------------------------------------------
94
- // labelFor() — dynamic labels
95
- // ---------------------------------------------------------------------------
96
- describe("PromptPlan — labelFor()", () => {
97
- const plan = new PromptPlan()
98
- .addPhase("p", "Phase")
99
- .step("READ", "Read", () => "")
100
- .subStep("PATHS", "Paths", () => "")
101
- .step("EXTRACT", "Extract", () => "")
102
- .subStep("TRACE", "Trace", () => "", { when: (p) => p.flag })
103
- .step("DRAFT", "Draft", () => "")
104
- .done();
105
- it("returns the static label for always-present main steps", () => {
106
- const p = { flag: true };
107
- expect(plan.labelFor("READ", p)).toBe("1");
108
- expect(plan.labelFor("EXTRACT", p)).toBe("2");
109
- expect(plan.labelFor("DRAFT", p)).toBe("3");
110
- });
111
- it("returns the static label for always-present sub-steps", () => {
112
- expect(plan.labelFor("PATHS", { flag: false })).toBe("1.1");
113
- });
114
- it("returns '2.1' for the conditional sub-step when condition is true", () => {
115
- expect(plan.labelFor("TRACE", { flag: true })).toBe("2.1");
116
- });
117
- it("returns null for the conditional sub-step when condition is false", () => {
118
- expect(plan.labelFor("TRACE", { flag: false })).toBeNull();
119
- });
120
- it("throws for an unknown key", () => {
121
- expect(() => plan.labelFor("UNKNOWN", { flag: true })).toThrow('PromptPlan: unknown step key "UNKNOWN"');
122
- });
123
- });
124
- // ---------------------------------------------------------------------------
125
- // Conditional sub-step: re-numbering when sibling is absent
126
- // ---------------------------------------------------------------------------
127
- describe("PromptPlan — conditional sub-step re-numbering", () => {
128
- const plan = new PromptPlan()
129
- .addPhase("p", "Phase")
130
- .step("A", "A", () => "")
131
- .subStep("A_COND", "Conditional A", () => "", { when: (p) => p.flag })
132
- .subStep("A_ALWAYS", "Always present", () => "always")
133
- .done();
134
- it("when condition is true, A_COND=1.1 and A_ALWAYS=1.2", () => {
135
- expect(plan.labelFor("A_COND", { flag: true })).toBe("1.1");
136
- expect(plan.labelFor("A_ALWAYS", { flag: true })).toBe("1.2");
137
- });
138
- it("when condition is false, A_COND=null and A_ALWAYS re-numbers to 1.1", () => {
139
- expect(plan.labelFor("A_COND", { flag: false })).toBeNull();
140
- expect(plan.labelFor("A_ALWAYS", { flag: false })).toBe("1.1");
141
- });
142
- });
143
- // ---------------------------------------------------------------------------
144
- // render() — output format
145
- // ---------------------------------------------------------------------------
146
- describe("PromptPlan — render()", () => {
147
- it("emits ### Step N: Title headers for hash format", () => {
148
- const plan = new PromptPlan()
149
- .addPhase("p", "Phase", { stepFormat: "hash" })
150
- .step("A", "Do something", () => "body text")
151
- .done();
152
- const output = plan.render({ flag: true });
153
- expect(output).toContain("### Step 1: Do something");
154
- expect(output).toContain("body text");
155
- });
156
- it("emits **Step N — Title** headers for bold format", () => {
157
- const plan = new PromptPlan({ startFrom: 0 })
158
- .addPhase("p", "Phase", { stepFormat: "bold" })
159
- .step("A", "Coverage", () => "coverage body")
160
- .done();
161
- const output = plan.render({ flag: true });
162
- expect(output).toContain("**Step 0 — Coverage**");
163
- expect(output).toContain("coverage body");
164
- });
165
- it("emits the phase header when headerLevel is not hidden", () => {
166
- const plan = new PromptPlan()
167
- .addPhase("p", "My Phase Title", { headerLevel: "##" })
168
- .step("A", "Step A", () => "")
169
- .done();
170
- expect(plan.render({ flag: true })).toContain("## My Phase Title");
171
- });
172
- it("does NOT emit a phase header when headerLevel is hidden", () => {
173
- const plan = new PromptPlan()
174
- .addPhase("p", "Hidden Phase", { headerLevel: "hidden" })
175
- .step("A", "Step A", () => "")
176
- .done();
177
- expect(plan.render({ flag: true })).not.toContain("Hidden Phase");
178
- });
179
- it("omits a conditional sub-step when condition is false", () => {
180
- const plan = new PromptPlan()
181
- .addPhase("p", "Phase")
182
- .step("A", "A", () => "step-a-body")
183
- .subStep("COND", "Conditional", () => "cond-body", { when: (p) => p.flag })
184
- .done();
185
- const withFlag = plan.render({ flag: true });
186
- const withoutFlag = plan.render({ flag: false });
187
- expect(withFlag).toContain("cond-body");
188
- expect(withoutFlag).not.toContain("cond-body");
189
- expect(withoutFlag).not.toContain("Conditional");
190
- });
191
- it("re-numbers remaining sub-steps when a conditional one is absent", () => {
192
- const plan = new PromptPlan()
193
- .addPhase("p", "Phase")
194
- .step("A", "A", () => "")
195
- .subStep("COND", "Conditional", () => "cond", { when: (p) => p.flag })
196
- .subStep("ALWAYS", "Always", () => "always")
197
- .done();
198
- // With flag: 1.1 = Conditional, 1.2 = Always
199
- expect(plan.render({ flag: true })).toContain("### Step 1.1: Conditional");
200
- expect(plan.render({ flag: true })).toContain("### Step 1.2: Always");
201
- // Without flag: conditional absent, Always re-numbers to 1.1
202
- expect(plan.render({ flag: false })).not.toContain("Conditional");
203
- expect(plan.render({ flag: false })).toContain("### Step 1.1: Always");
204
- });
205
- it("supports dynamic step titles via title functions", () => {
206
- const plan = new PromptPlan()
207
- .addPhase("p", "Phase")
208
- .step("A", (p) => p.flag ? "Flag is on" : "Flag is off", () => "body")
209
- .done();
210
- expect(plan.render({ flag: true })).toContain("### Step 1: Flag is on");
211
- expect(plan.render({ flag: false })).toContain("### Step 1: Flag is off");
212
- });
213
- it("sections are separated by exactly one blank line", () => {
214
- const plan = new PromptPlan()
215
- .addPhase("p", "Phase", { headerLevel: "##" })
216
- .step("A", "Step A", () => "body-a")
217
- .step("B", "Step B", () => "body-b")
218
- .done();
219
- const output = plan.render({ flag: true });
220
- // Each pair of sections should have \n\n (exactly one blank line) between them
221
- expect(output).toContain("## Phase\n\n### Step 1");
222
- expect(output).toContain("body-a\n\n### Step 2");
223
- });
224
- it("reproduces the analysis-output step sequence", () => {
225
- const plan = new PromptPlan()
226
- .addPhase("analysis", "Your Task", { headerLevel: "##", stepFormat: "hash" })
227
- .step("READ", "Read the changed files", () => "read body")
228
- .subStep("PATHS", "Resolve endpoint paths", () => "paths body")
229
- .step("EXTRACT", "Extract endpoints", () => "extract body")
230
- .subStep("TRACE", "Trace callers", () => "trace body", { when: (p) => p.flag })
231
- .step("DRAFT", "Draft scenarios", () => "draft body")
232
- .step("CALL", "Call the tool", () => "call body")
233
- .done();
234
- expect(plan.labels.READ).toBe("1");
235
- expect(plan.labels.PATHS).toBe("1.1");
236
- expect(plan.labels.EXTRACT).toBe("2");
237
- expect(plan.labels.DRAFT).toBe("3");
238
- expect(plan.labels.CALL).toBe("4");
239
- // With flag: trace appears as 2.1
240
- const withTrace = plan.render({ flag: true });
241
- expect(withTrace).toContain("### Step 1: Read the changed files");
242
- expect(withTrace).toContain("### Step 1.1: Resolve endpoint paths");
243
- expect(withTrace).toContain("### Step 2: Extract endpoints");
244
- expect(withTrace).toContain("### Step 2.1: Trace callers");
245
- expect(withTrace).toContain("### Step 3: Draft scenarios");
246
- expect(withTrace).toContain("### Step 4: Call the tool");
247
- // Without flag: no trace step, sequence has no gap
248
- const noTrace = plan.render({ flag: false });
249
- expect(noTrace).not.toContain("trace body");
250
- expect(noTrace).not.toContain("Step 2.1");
251
- expect(noTrace).toContain("### Step 3: Draft scenarios");
252
- });
253
- });
254
- // ---------------------------------------------------------------------------
255
- // preview() — developer review
256
- // ---------------------------------------------------------------------------
257
- describe("PromptPlan — preview()", () => {
258
- const plan = new PromptPlan()
259
- .addPhase("analysis", "Analysis Phase", { headerLevel: "##" })
260
- .step("READ", "Read", () => "")
261
- .subStep("PATHS", "Paths", () => "")
262
- .step("EXTRACT", "Extract", () => "")
263
- .subStep("TRACE", "Trace", () => "", {
264
- when: (p) => p.flag,
265
- whenDesc: "backend unmatched files present",
266
- })
267
- .step("DRAFT", "Draft", () => "")
268
- .done();
269
- it("reports correct activeStepCount and totalStepCount", () => {
270
- const withFlag = plan.preview({ flag: true });
271
- const withoutFlag = plan.preview({ flag: false });
272
- expect(withFlag.totalStepCount).toBe(5); // 3 main + 2 subs = 5
273
- expect(withFlag.activeStepCount).toBe(5); // all active
274
- expect(withoutFlag.totalStepCount).toBe(5);
275
- expect(withoutFlag.activeStepCount).toBe(4); // TRACE absent
276
- });
277
- it("marks the conditional sub-step inactive when condition is false", () => {
278
- const pv = plan.preview({ flag: false });
279
- const extractStep = pv.phases[0].steps.find(s => s.key === "EXTRACT");
280
- const traceSub = extractStep.subSteps.find(s => s.key === "TRACE");
281
- expect(traceSub.active).toBe(false);
282
- expect(traceSub.label).toBe("2.?");
283
- expect(traceSub.conditionDesc).toBe("backend unmatched files present");
284
- });
285
- it("marks the conditional sub-step active with correct label when condition is true", () => {
286
- const pv = plan.preview({ flag: true });
287
- const extractStep = pv.phases[0].steps.find(s => s.key === "EXTRACT");
288
- const traceSub = extractStep.subSteps.find(s => s.key === "TRACE");
289
- expect(traceSub.active).toBe(true);
290
- expect(traceSub.label).toBe("2.1");
291
- });
292
- it("includes all phase / step keys in the preview output", () => {
293
- const pv = plan.preview({ flag: true });
294
- expect(pv.phases).toHaveLength(1);
295
- expect(pv.phases[0].key).toBe("analysis");
296
- const stepKeys = pv.phases[0].steps.map(s => s.key);
297
- expect(stepKeys).toEqual(["READ", "EXTRACT", "DRAFT"]);
298
- });
299
- });
300
- // ---------------------------------------------------------------------------
301
- // PhaseBuilder guard
302
- // ---------------------------------------------------------------------------
303
- describe("PhaseBuilder — error handling", () => {
304
- it("throws when subStep() is called before any step()", () => {
305
- expect(() => {
306
- new PromptPlan()
307
- .addPhase("p", "Phase")
308
- .subStep("ORPHAN", "Orphan", () => "");
309
- }).toThrow('subStep("ORPHAN") must follow a step() call in the same phase');
310
- });
311
- it("throws on duplicate step keys", () => {
312
- expect(() => {
313
- new PromptPlan()
314
- .addPhase("p", "Phase")
315
- .step("DUP", "First", () => "")
316
- .step("DUP", "Second", () => "");
317
- }).toThrow('PromptPlan: duplicate step key "DUP"');
318
- });
319
- it("throws on duplicate sub-step keys", () => {
320
- expect(() => {
321
- new PromptPlan()
322
- .addPhase("p", "Phase")
323
- .step("A", "A", () => "")
324
- .subStep("DUP", "First sub", () => "")
325
- .subStep("DUP", "Second sub", () => "");
326
- }).toThrow('PromptPlan: duplicate step key "DUP"');
327
- });
328
- it("throws when a sub-step key conflicts with a main step key", () => {
329
- expect(() => {
330
- new PromptPlan()
331
- .addPhase("p", "Phase")
332
- .step("SHARED", "Main", () => "")
333
- .subStep("SHARED", "Sub", () => "");
334
- }).toThrow('PromptPlan: duplicate step key "SHARED"');
335
- });
336
- });