sofia-cli 0.1.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 (435) hide show
  1. package/.github/agents/copilot-instructions.md +39 -0
  2. package/.github/agents/speckit.analyze.agent.md +184 -0
  3. package/.github/agents/speckit.checklist.agent.md +294 -0
  4. package/.github/agents/speckit.clarify.agent.md +181 -0
  5. package/.github/agents/speckit.constitution.agent.md +84 -0
  6. package/.github/agents/speckit.implement.agent.md +135 -0
  7. package/.github/agents/speckit.plan.agent.md +90 -0
  8. package/.github/agents/speckit.specify.agent.md +258 -0
  9. package/.github/agents/speckit.tasks.agent.md +137 -0
  10. package/.github/agents/speckit.taskstoissues.agent.md +30 -0
  11. package/.github/copilot-instructions.md +257 -0
  12. package/.github/prompts/speckit.analyze.prompt.md +3 -0
  13. package/.github/prompts/speckit.checklist.prompt.md +3 -0
  14. package/.github/prompts/speckit.clarify.prompt.md +3 -0
  15. package/.github/prompts/speckit.constitution.prompt.md +3 -0
  16. package/.github/prompts/speckit.implement.prompt.md +3 -0
  17. package/.github/prompts/speckit.plan.prompt.md +3 -0
  18. package/.github/prompts/speckit.specify.prompt.md +3 -0
  19. package/.github/prompts/speckit.tasks.prompt.md +3 -0
  20. package/.github/prompts/speckit.taskstoissues.prompt.md +3 -0
  21. package/.github/workflows/ci.yml +38 -0
  22. package/.prettierrc +6 -0
  23. package/.specify/memory/constitution.md +181 -0
  24. package/.specify/scripts/bash/check-prerequisites.sh +166 -0
  25. package/.specify/scripts/bash/common.sh +156 -0
  26. package/.specify/scripts/bash/create-new-feature.sh +297 -0
  27. package/.specify/scripts/bash/setup-plan.sh +61 -0
  28. package/.specify/scripts/bash/update-agent-context.sh +810 -0
  29. package/.specify/templates/agent-file-template.md +28 -0
  30. package/.specify/templates/checklist-template.md +40 -0
  31. package/.specify/templates/constitution-template.md +50 -0
  32. package/.specify/templates/plan-template.md +113 -0
  33. package/.specify/templates/spec-template.md +115 -0
  34. package/.specify/templates/tasks-template.md +251 -0
  35. package/.vscode/mcp.json +42 -0
  36. package/.vscode/settings.json +19 -0
  37. package/CODE_OF_CONDUCT.md +128 -0
  38. package/LICENSE +21 -0
  39. package/README.md +213 -0
  40. package/dist/src/cli/developCommand.js +240 -0
  41. package/dist/src/cli/directCommands.js +143 -0
  42. package/dist/src/cli/envLoader.js +16 -0
  43. package/dist/src/cli/exportCommand.js +53 -0
  44. package/dist/src/cli/index.js +203 -0
  45. package/dist/src/cli/ioContext.js +109 -0
  46. package/dist/src/cli/preflight.js +57 -0
  47. package/dist/src/cli/statusCommand.js +110 -0
  48. package/dist/src/cli/workshopCommand.js +400 -0
  49. package/dist/src/develop/checkpointState.js +86 -0
  50. package/dist/src/develop/codeGenerator.js +319 -0
  51. package/dist/src/develop/dynamicScaffolder.js +226 -0
  52. package/dist/src/develop/githubMcpAdapter.js +122 -0
  53. package/dist/src/develop/index.js +15 -0
  54. package/dist/src/develop/mcpContextEnricher.js +195 -0
  55. package/dist/src/develop/pocScaffolder.js +542 -0
  56. package/dist/src/develop/ralphLoop.js +659 -0
  57. package/dist/src/develop/templateRegistry.js +364 -0
  58. package/dist/src/develop/testRunner.js +202 -0
  59. package/dist/src/logging/logger.js +58 -0
  60. package/dist/src/loop/conversationLoop.js +227 -0
  61. package/dist/src/loop/phaseSummarizer.js +87 -0
  62. package/dist/src/mcp/mcpManager.js +267 -0
  63. package/dist/src/mcp/mcpTransport.js +391 -0
  64. package/dist/src/mcp/retryPolicy.js +47 -0
  65. package/dist/src/mcp/webSearch.js +254 -0
  66. package/dist/src/phases/contextSummarizer.js +101 -0
  67. package/dist/src/phases/discoveryEnricher.js +156 -0
  68. package/dist/src/phases/phaseExtractors.js +222 -0
  69. package/dist/src/phases/phaseHandlers.js +328 -0
  70. package/dist/src/prompts/design.md +51 -0
  71. package/dist/src/prompts/develop-boundary.md +51 -0
  72. package/dist/src/prompts/develop.md +111 -0
  73. package/dist/src/prompts/discover.md +58 -0
  74. package/dist/src/prompts/ideate.md +56 -0
  75. package/dist/src/prompts/plan.md +51 -0
  76. package/dist/src/prompts/promptLoader.js +167 -0
  77. package/dist/src/prompts/promptLoader.ts +198 -0
  78. package/dist/src/prompts/select.md +47 -0
  79. package/dist/src/prompts/summarize/README.md +8 -0
  80. package/dist/src/prompts/summarize/design-summary.md +37 -0
  81. package/dist/src/prompts/summarize/develop-summary.md +25 -0
  82. package/dist/src/prompts/summarize/ideate-summary.md +27 -0
  83. package/dist/src/prompts/summarize/plan-summary.md +27 -0
  84. package/dist/src/prompts/summarize/select-summary.md +21 -0
  85. package/dist/src/prompts/system.md +28 -0
  86. package/dist/src/sessions/exportPaths.js +22 -0
  87. package/dist/src/sessions/exportWriter.js +406 -0
  88. package/dist/src/sessions/sessionManager.js +81 -0
  89. package/dist/src/sessions/sessionStore.js +65 -0
  90. package/dist/src/shared/activitySpinner.js +91 -0
  91. package/dist/src/shared/copilotClient.js +129 -0
  92. package/dist/src/shared/data/cards.json +1249 -0
  93. package/dist/src/shared/data/cardsLoader.js +51 -0
  94. package/dist/src/shared/errorClassifier.js +120 -0
  95. package/dist/src/shared/events.js +28 -0
  96. package/dist/src/shared/markdownRenderer.js +34 -0
  97. package/dist/src/shared/schemas/session.js +265 -0
  98. package/dist/src/shared/tableRenderer.js +20 -0
  99. package/dist/src/vendor/chalk.js +2 -0
  100. package/dist/src/vendor/cli-table3.js +3 -0
  101. package/dist/src/vendor/commander.js +2 -0
  102. package/dist/src/vendor/marked-terminal.js +3 -0
  103. package/dist/src/vendor/marked.js +2 -0
  104. package/dist/src/vendor/ora.js +2 -0
  105. package/dist/src/vendor/pino.js +2 -0
  106. package/dist/src/vendor/zod.js +2 -0
  107. package/dist/tests/e2e/developE2e.spec.js +126 -0
  108. package/dist/tests/e2e/developFailureE2e.spec.js +247 -0
  109. package/dist/tests/e2e/developPty.spec.js +75 -0
  110. package/dist/tests/e2e/discoveryWebSearchRelevance.spec.js +84 -0
  111. package/dist/tests/e2e/harness.spec.js +83 -0
  112. package/dist/tests/e2e/mcpLive.spec.js +120 -0
  113. package/dist/tests/e2e/newSession.e2e.spec.js +177 -0
  114. package/dist/tests/e2e/ralphLoopEnrichmentComparison.spec.js +62 -0
  115. package/dist/tests/e2e/workiqEnrichment.spec.js +56 -0
  116. package/dist/tests/e2e/zavaSimulation.spec.js +452 -0
  117. package/dist/tests/fixtures/test-fixture-project/src/add.js +3 -0
  118. package/dist/tests/fixtures/test-fixture-project/tests/failing.test.js +6 -0
  119. package/dist/tests/fixtures/test-fixture-project/tests/hanging.test.js +8 -0
  120. package/dist/tests/fixtures/test-fixture-project/tests/passing.test.js +10 -0
  121. package/dist/tests/fixtures/test-fixture-project/vitest.config.js +6 -0
  122. package/dist/tests/integration/autoStartConversation.spec.js +138 -0
  123. package/dist/tests/integration/defaultCommand.spec.js +147 -0
  124. package/dist/tests/integration/directCommandNonTty.spec.js +224 -0
  125. package/dist/tests/integration/directCommandTty.spec.js +151 -0
  126. package/dist/tests/integration/discoveryEnrichmentFlow.spec.js +175 -0
  127. package/dist/tests/integration/exportArtifacts.spec.js +202 -0
  128. package/dist/tests/integration/exportFallbackFlow.spec.js +99 -0
  129. package/dist/tests/integration/mcpDegradationFlow.spec.js +190 -0
  130. package/dist/tests/integration/mcpTransportFlow.spec.js +139 -0
  131. package/dist/tests/integration/newSessionFlow.spec.js +343 -0
  132. package/dist/tests/integration/pocGithubMcp.spec.js +186 -0
  133. package/dist/tests/integration/pocLocalFallback.spec.js +171 -0
  134. package/dist/tests/integration/pocScaffold.spec.js +163 -0
  135. package/dist/tests/integration/ralphLoopFlow.spec.js +359 -0
  136. package/dist/tests/integration/ralphLoopPartial.spec.js +368 -0
  137. package/dist/tests/integration/resumeAndBacktrack.spec.js +247 -0
  138. package/dist/tests/integration/spinnerLifecycle.spec.js +220 -0
  139. package/dist/tests/integration/summarizationFlow.spec.js +115 -0
  140. package/dist/tests/integration/testRunnerReal.spec.js +52 -0
  141. package/dist/tests/integration/webSearchAgent.spec.js +128 -0
  142. package/dist/tests/live/copilotSdkLive.spec.js +107 -0
  143. package/dist/tests/live/zavaFullWorkshop.spec.js +392 -0
  144. package/dist/tests/setup/loadEnv.js +3 -0
  145. package/dist/tests/unit/cli/developCommand.spec.js +567 -0
  146. package/dist/tests/unit/cli/directCommands.spec.js +279 -0
  147. package/dist/tests/unit/cli/envLoader.spec.js +58 -0
  148. package/dist/tests/unit/cli/ioContext.spec.js +119 -0
  149. package/dist/tests/unit/cli/preflight.spec.js +108 -0
  150. package/dist/tests/unit/cli/statusCommand.spec.js +111 -0
  151. package/dist/tests/unit/cli/workshopClientFallback.spec.js +80 -0
  152. package/dist/tests/unit/cli/workshopCommand.spec.js +329 -0
  153. package/dist/tests/unit/config/vitestEnvSetup.spec.js +13 -0
  154. package/dist/tests/unit/develop/checkpointState.spec.js +315 -0
  155. package/dist/tests/unit/develop/codeGenerator.spec.js +355 -0
  156. package/dist/tests/unit/develop/githubMcpAdapter.spec.js +231 -0
  157. package/dist/tests/unit/develop/mcpContextEnricher.spec.js +433 -0
  158. package/dist/tests/unit/develop/outputValidator.spec.js +119 -0
  159. package/dist/tests/unit/develop/pocScaffolder.spec.js +353 -0
  160. package/dist/tests/unit/develop/ralphLoop.spec.js +1248 -0
  161. package/dist/tests/unit/develop/templateRegistry.spec.js +85 -0
  162. package/dist/tests/unit/develop/testRunner.spec.js +249 -0
  163. package/dist/tests/unit/infraBicep.spec.js +92 -0
  164. package/dist/tests/unit/infraDeploy.spec.js +82 -0
  165. package/dist/tests/unit/infraTeardown.spec.js +63 -0
  166. package/dist/tests/unit/logging/logger.spec.js +43 -0
  167. package/dist/tests/unit/loop/conversationLoop.spec.js +592 -0
  168. package/dist/tests/unit/loop/phaseSummarizer.spec.js +141 -0
  169. package/dist/tests/unit/loop/streamingMarkdown.spec.js +147 -0
  170. package/dist/tests/unit/mcp/mcpManager.spec.js +279 -0
  171. package/dist/tests/unit/mcp/mcpTransport.spec.js +529 -0
  172. package/dist/tests/unit/mcp/retryPolicy.spec.js +218 -0
  173. package/dist/tests/unit/mcp/timeoutValidation.spec.js +46 -0
  174. package/dist/tests/unit/mcp/webSearch.spec.js +567 -0
  175. package/dist/tests/unit/phases/contextSummarizer.spec.js +140 -0
  176. package/dist/tests/unit/phases/discoveryEnricher.repeatCalls.spec.js +93 -0
  177. package/dist/tests/unit/phases/discoveryEnricher.spec.js +411 -0
  178. package/dist/tests/unit/phases/phaseExtractors.spec.js +352 -0
  179. package/dist/tests/unit/phases/phaseHandlers.spec.js +425 -0
  180. package/dist/tests/unit/prompts/promptLoader.spec.js +118 -0
  181. package/dist/tests/unit/schemas/pocSchemas.spec.js +412 -0
  182. package/dist/tests/unit/schemas/session.spec.js +257 -0
  183. package/dist/tests/unit/sessions/exportPaths.spec.js +31 -0
  184. package/dist/tests/unit/sessions/exportWriter.spec.js +655 -0
  185. package/dist/tests/unit/sessions/sessionManager.spec.js +151 -0
  186. package/dist/tests/unit/sessions/sessionStore.spec.js +116 -0
  187. package/dist/tests/unit/shared/activitySpinner.spec.js +175 -0
  188. package/dist/tests/unit/shared/cardsLoader.spec.js +76 -0
  189. package/dist/tests/unit/shared/copilotClient.spec.js +155 -0
  190. package/dist/tests/unit/shared/errorClassifier.spec.js +131 -0
  191. package/dist/tests/unit/shared/events.spec.js +55 -0
  192. package/dist/tests/unit/shared/markdownRenderer.spec.js +35 -0
  193. package/dist/tests/unit/shared/markdownRendererChunks.spec.js +70 -0
  194. package/dist/tests/unit/shared/tableRenderer.spec.js +34 -0
  195. package/dist/vitest.config.js +14 -0
  196. package/dist/vitest.live.config.js +18 -0
  197. package/docs/README.md +35 -0
  198. package/docs/architecture.md +169 -0
  199. package/docs/cli-usage.md +207 -0
  200. package/docs/environment.md +66 -0
  201. package/docs/export-format.md +146 -0
  202. package/docs/session-model.md +113 -0
  203. package/eslint.config.js +35 -0
  204. package/infra/deploy.sh +193 -0
  205. package/infra/gather-env.sh +211 -0
  206. package/infra/main.bicep +90 -0
  207. package/infra/main.bicepparam +18 -0
  208. package/infra/resources.bicep +134 -0
  209. package/infra/teardown.sh +114 -0
  210. package/package.json +63 -0
  211. package/specs/001-cli-workshop-rebuild/checklists/requirements.md +35 -0
  212. package/specs/001-cli-workshop-rebuild/contracts/cli.md +59 -0
  213. package/specs/001-cli-workshop-rebuild/contracts/export-summary-json.md +23 -0
  214. package/specs/001-cli-workshop-rebuild/contracts/session-json.md +30 -0
  215. package/specs/001-cli-workshop-rebuild/data-model.md +210 -0
  216. package/specs/001-cli-workshop-rebuild/plan.md +361 -0
  217. package/specs/001-cli-workshop-rebuild/quickstart.md +83 -0
  218. package/specs/001-cli-workshop-rebuild/research.md +116 -0
  219. package/specs/001-cli-workshop-rebuild/spec.md +240 -0
  220. package/specs/001-cli-workshop-rebuild/tasks.md +476 -0
  221. package/specs/002-poc-generation/contracts/poc-output.md +172 -0
  222. package/specs/002-poc-generation/contracts/ralph-loop.md +113 -0
  223. package/specs/002-poc-generation/data-model.md +172 -0
  224. package/specs/002-poc-generation/plan.md +109 -0
  225. package/specs/002-poc-generation/quickstart.md +97 -0
  226. package/specs/002-poc-generation/research.md +786 -0
  227. package/specs/002-poc-generation/spec.md +81 -0
  228. package/specs/002-poc-generation/tasks-fix.md +198 -0
  229. package/specs/002-poc-generation/tasks.md +252 -0
  230. package/specs/003-mcp-transport-integration/checklists/requirements.md +37 -0
  231. package/specs/003-mcp-transport-integration/contracts/context-enricher.md +220 -0
  232. package/specs/003-mcp-transport-integration/contracts/discovery-enricher.md +267 -0
  233. package/specs/003-mcp-transport-integration/contracts/github-adapter.md +149 -0
  234. package/specs/003-mcp-transport-integration/contracts/mcp-transport.md +288 -0
  235. package/specs/003-mcp-transport-integration/data-model.md +326 -0
  236. package/specs/003-mcp-transport-integration/plan.md +114 -0
  237. package/specs/003-mcp-transport-integration/quickstart.md +311 -0
  238. package/specs/003-mcp-transport-integration/research.md +395 -0
  239. package/specs/003-mcp-transport-integration/spec.md +234 -0
  240. package/specs/003-mcp-transport-integration/tasks.md +324 -0
  241. package/specs/003-next-spec-gaps.md +150 -0
  242. package/specs/004-dev-resume-hardening/checklists/requirements.md +37 -0
  243. package/specs/004-dev-resume-hardening/contracts/cli.md +160 -0
  244. package/specs/004-dev-resume-hardening/data-model.md +321 -0
  245. package/specs/004-dev-resume-hardening/plan.md +107 -0
  246. package/specs/004-dev-resume-hardening/quickstart.md +115 -0
  247. package/specs/004-dev-resume-hardening/research.md +142 -0
  248. package/specs/004-dev-resume-hardening/spec.md +221 -0
  249. package/specs/004-dev-resume-hardening/tasks.md +333 -0
  250. package/specs/005-ai-search-deploy/checklists/requirements.md +39 -0
  251. package/specs/005-ai-search-deploy/contracts/web-search-tool.md +241 -0
  252. package/specs/005-ai-search-deploy/data-model.md +130 -0
  253. package/specs/005-ai-search-deploy/plan.md +93 -0
  254. package/specs/005-ai-search-deploy/quickstart.md +96 -0
  255. package/specs/005-ai-search-deploy/research.md +187 -0
  256. package/specs/005-ai-search-deploy/spec.md +143 -0
  257. package/specs/005-ai-search-deploy/tasks.md +284 -0
  258. package/specs/006-workshop-extraction-fixes/checklists/requirements.md +61 -0
  259. package/specs/006-workshop-extraction-fixes/contracts/summarization-and-export.md +131 -0
  260. package/specs/006-workshop-extraction-fixes/data-model.md +149 -0
  261. package/specs/006-workshop-extraction-fixes/plan.md +123 -0
  262. package/specs/006-workshop-extraction-fixes/quickstart.md +101 -0
  263. package/specs/006-workshop-extraction-fixes/research.md +143 -0
  264. package/specs/006-workshop-extraction-fixes/spec.md +210 -0
  265. package/specs/006-workshop-extraction-fixes/tasks.md +316 -0
  266. package/src/cli/developCommand.ts +308 -0
  267. package/src/cli/directCommands.ts +195 -0
  268. package/src/cli/envLoader.ts +17 -0
  269. package/src/cli/exportCommand.ts +65 -0
  270. package/src/cli/index.ts +249 -0
  271. package/src/cli/ioContext.ts +139 -0
  272. package/src/cli/preflight.ts +86 -0
  273. package/src/cli/statusCommand.ts +118 -0
  274. package/src/cli/workshopCommand.ts +496 -0
  275. package/src/develop/checkpointState.ts +121 -0
  276. package/src/develop/codeGenerator.ts +402 -0
  277. package/src/develop/dynamicScaffolder.ts +284 -0
  278. package/src/develop/githubMcpAdapter.ts +199 -0
  279. package/src/develop/index.ts +34 -0
  280. package/src/develop/mcpContextEnricher.ts +279 -0
  281. package/src/develop/pocScaffolder.ts +646 -0
  282. package/src/develop/ralphLoop.ts +1044 -0
  283. package/src/develop/templateRegistry.ts +427 -0
  284. package/src/develop/testRunner.ts +276 -0
  285. package/src/logging/logger.ts +73 -0
  286. package/src/loop/conversationLoop.ts +355 -0
  287. package/src/loop/phaseSummarizer.ts +114 -0
  288. package/src/mcp/mcpManager.ts +365 -0
  289. package/src/mcp/mcpTransport.ts +562 -0
  290. package/src/mcp/retryPolicy.ts +87 -0
  291. package/src/mcp/webSearch.ts +388 -0
  292. package/src/originalPrompts/design_thinking.md +178 -0
  293. package/src/originalPrompts/design_thinking_persona.md +76 -0
  294. package/src/originalPrompts/document_generator_example.md +77 -0
  295. package/src/originalPrompts/document_generator_persona.md +47 -0
  296. package/src/originalPrompts/facilitator_persona.md +125 -0
  297. package/src/originalPrompts/guardrails.md +47 -0
  298. package/src/phases/contextSummarizer.ts +154 -0
  299. package/src/phases/discoveryEnricher.ts +223 -0
  300. package/src/phases/phaseExtractors.ts +247 -0
  301. package/src/phases/phaseHandlers.ts +450 -0
  302. package/src/prompts/design.md +51 -0
  303. package/src/prompts/develop-boundary.md +51 -0
  304. package/src/prompts/develop.md +111 -0
  305. package/src/prompts/discover.md +58 -0
  306. package/src/prompts/ideate.md +56 -0
  307. package/src/prompts/plan.md +51 -0
  308. package/src/prompts/promptLoader.ts +198 -0
  309. package/src/prompts/select.md +47 -0
  310. package/src/prompts/summarize/README.md +8 -0
  311. package/src/prompts/summarize/design-summary.md +37 -0
  312. package/src/prompts/summarize/develop-summary.md +25 -0
  313. package/src/prompts/summarize/ideate-summary.md +27 -0
  314. package/src/prompts/summarize/plan-summary.md +27 -0
  315. package/src/prompts/summarize/select-summary.md +21 -0
  316. package/src/prompts/system.md +28 -0
  317. package/src/sessions/exportPaths.ts +28 -0
  318. package/src/sessions/exportWriter.ts +490 -0
  319. package/src/sessions/sessionManager.ts +119 -0
  320. package/src/sessions/sessionStore.ts +69 -0
  321. package/src/shared/activitySpinner.ts +108 -0
  322. package/src/shared/copilotClient.ts +291 -0
  323. package/src/shared/data/cards.json +1249 -0
  324. package/src/shared/data/cardsLoader.ts +70 -0
  325. package/src/shared/errorClassifier.ts +160 -0
  326. package/src/shared/events.ts +103 -0
  327. package/src/shared/markdownRenderer.ts +44 -0
  328. package/src/shared/schemas/session.ts +346 -0
  329. package/src/shared/tableRenderer.ts +28 -0
  330. package/src/types/marked-terminal.d.ts +5 -0
  331. package/src/vendor/chalk.ts +2 -0
  332. package/src/vendor/cli-table3.ts +3 -0
  333. package/src/vendor/commander.ts +2 -0
  334. package/src/vendor/marked-terminal.ts +3 -0
  335. package/src/vendor/marked.ts +2 -0
  336. package/src/vendor/ora.ts +2 -0
  337. package/src/vendor/pino.ts +3 -0
  338. package/src/vendor/zod.ts +3 -0
  339. package/tests/e2e/developE2e.spec.ts +152 -0
  340. package/tests/e2e/developFailureE2e.spec.ts +289 -0
  341. package/tests/e2e/developPty.spec.ts +86 -0
  342. package/tests/e2e/discoveryWebSearchRelevance.spec.ts +103 -0
  343. package/tests/e2e/harness.spec.ts +104 -0
  344. package/tests/e2e/mcpLive.spec.ts +149 -0
  345. package/tests/e2e/newSession.e2e.spec.ts +245 -0
  346. package/tests/e2e/ralphLoopEnrichmentComparison.spec.ts +70 -0
  347. package/tests/e2e/workiqEnrichment.spec.ts +72 -0
  348. package/tests/e2e/zava-assessment/agent-interaction-script.md +258 -0
  349. package/tests/e2e/zava-assessment/company-profile.md +98 -0
  350. package/tests/e2e/zava-assessment/expected-results-checklist.md +454 -0
  351. package/tests/e2e/zavaSimulation.spec.ts +511 -0
  352. package/tests/fixtures/completedSession.json +141 -0
  353. package/tests/fixtures/test-fixture-project/package-lock.json +1585 -0
  354. package/tests/fixtures/test-fixture-project/package.json +12 -0
  355. package/tests/fixtures/test-fixture-project/src/add.ts +3 -0
  356. package/tests/fixtures/test-fixture-project/tests/failing.test.ts +7 -0
  357. package/tests/fixtures/test-fixture-project/tests/hanging.test.ts +9 -0
  358. package/tests/fixtures/test-fixture-project/tests/passing.test.ts +13 -0
  359. package/tests/fixtures/test-fixture-project/vitest.config.ts +7 -0
  360. package/tests/integration/autoStartConversation.spec.ts +168 -0
  361. package/tests/integration/defaultCommand.spec.ts +179 -0
  362. package/tests/integration/directCommandNonTty.spec.ts +260 -0
  363. package/tests/integration/directCommandTty.spec.ts +185 -0
  364. package/tests/integration/discoveryEnrichmentFlow.spec.ts +209 -0
  365. package/tests/integration/exportArtifacts.spec.ts +232 -0
  366. package/tests/integration/exportFallbackFlow.spec.ts +115 -0
  367. package/tests/integration/mcpDegradationFlow.spec.ts +231 -0
  368. package/tests/integration/mcpTransportFlow.spec.ts +178 -0
  369. package/tests/integration/newSessionFlow.spec.ts +406 -0
  370. package/tests/integration/pocGithubMcp.spec.ts +224 -0
  371. package/tests/integration/pocLocalFallback.spec.ts +205 -0
  372. package/tests/integration/pocScaffold.spec.ts +220 -0
  373. package/tests/integration/ralphLoopFlow.spec.ts +430 -0
  374. package/tests/integration/ralphLoopPartial.spec.ts +416 -0
  375. package/tests/integration/resumeAndBacktrack.spec.ts +278 -0
  376. package/tests/integration/spinnerLifecycle.spec.ts +270 -0
  377. package/tests/integration/summarizationFlow.spec.ts +135 -0
  378. package/tests/integration/testRunnerReal.spec.ts +63 -0
  379. package/tests/integration/webSearchAgent.spec.ts +155 -0
  380. package/tests/live/copilotSdkLive.spec.ts +149 -0
  381. package/tests/live/zavaFullWorkshop.spec.ts +515 -0
  382. package/tests/setup/loadEnv.ts +5 -0
  383. package/tests/unit/cli/developCommand.spec.ts +679 -0
  384. package/tests/unit/cli/directCommands.spec.ts +325 -0
  385. package/tests/unit/cli/envLoader.spec.ts +73 -0
  386. package/tests/unit/cli/ioContext.spec.ts +148 -0
  387. package/tests/unit/cli/preflight.spec.ts +125 -0
  388. package/tests/unit/cli/statusCommand.spec.ts +134 -0
  389. package/tests/unit/cli/workshopClientFallback.spec.ts +100 -0
  390. package/tests/unit/cli/workshopCommand.spec.ts +378 -0
  391. package/tests/unit/config/vitestEnvSetup.spec.ts +24 -0
  392. package/tests/unit/develop/checkpointState.spec.ts +378 -0
  393. package/tests/unit/develop/codeGenerator.spec.ts +447 -0
  394. package/tests/unit/develop/githubMcpAdapter.spec.ts +283 -0
  395. package/tests/unit/develop/mcpContextEnricher.spec.ts +564 -0
  396. package/tests/unit/develop/outputValidator.spec.ts +134 -0
  397. package/tests/unit/develop/pocScaffolder.spec.ts +451 -0
  398. package/tests/unit/develop/ralphLoop.spec.ts +1439 -0
  399. package/tests/unit/develop/templateRegistry.spec.ts +106 -0
  400. package/tests/unit/develop/testRunner.spec.ts +294 -0
  401. package/tests/unit/infraBicep.spec.ts +116 -0
  402. package/tests/unit/infraDeploy.spec.ts +102 -0
  403. package/tests/unit/infraTeardown.spec.ts +77 -0
  404. package/tests/unit/logging/logger.spec.ts +50 -0
  405. package/tests/unit/loop/conversationLoop.spec.ts +719 -0
  406. package/tests/unit/loop/phaseSummarizer.spec.ts +169 -0
  407. package/tests/unit/loop/streamingMarkdown.spec.ts +180 -0
  408. package/tests/unit/mcp/mcpManager.spec.ts +336 -0
  409. package/tests/unit/mcp/mcpTransport.spec.ts +689 -0
  410. package/tests/unit/mcp/retryPolicy.spec.ts +278 -0
  411. package/tests/unit/mcp/timeoutValidation.spec.ts +55 -0
  412. package/tests/unit/mcp/webSearch.spec.ts +718 -0
  413. package/tests/unit/phases/contextSummarizer.spec.ts +158 -0
  414. package/tests/unit/phases/discoveryEnricher.repeatCalls.spec.ts +125 -0
  415. package/tests/unit/phases/discoveryEnricher.spec.ts +512 -0
  416. package/tests/unit/phases/phaseExtractors.spec.ts +406 -0
  417. package/tests/unit/phases/phaseHandlers.spec.ts +483 -0
  418. package/tests/unit/prompts/promptLoader.spec.ts +144 -0
  419. package/tests/unit/schemas/pocSchemas.spec.ts +457 -0
  420. package/tests/unit/schemas/session.spec.ts +328 -0
  421. package/tests/unit/sessions/exportPaths.spec.ts +38 -0
  422. package/tests/unit/sessions/exportWriter.spec.ts +737 -0
  423. package/tests/unit/sessions/sessionManager.spec.ts +174 -0
  424. package/tests/unit/sessions/sessionStore.spec.ts +136 -0
  425. package/tests/unit/shared/activitySpinner.spec.ts +211 -0
  426. package/tests/unit/shared/cardsLoader.spec.ts +89 -0
  427. package/tests/unit/shared/copilotClient.spec.ts +185 -0
  428. package/tests/unit/shared/errorClassifier.spec.ts +152 -0
  429. package/tests/unit/shared/events.spec.ts +71 -0
  430. package/tests/unit/shared/markdownRenderer.spec.ts +42 -0
  431. package/tests/unit/shared/markdownRendererChunks.spec.ts +83 -0
  432. package/tests/unit/shared/tableRenderer.spec.ts +38 -0
  433. package/tsconfig.json +20 -0
  434. package/vitest.config.ts +15 -0
  435. package/vitest.live.config.ts +19 -0
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Unit tests for workshopCommand client creation — silent mock fallback bug.
3
+ *
4
+ * Verifies:
5
+ * - When createCopilotClient() throws, the error is logged (not swallowed)
6
+ * - The fake client is never silently substituted in production mode
7
+ * - The user receives a clear error message when the SDK is unavailable
8
+ */
9
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
10
+ // Mock copilotClient module so createCopilotClient always rejects
11
+ vi.mock('../../../src/shared/copilotClient.js', async (importOriginal) => {
12
+ const orig = await importOriginal();
13
+ return {
14
+ ...orig,
15
+ createCopilotClient: vi.fn().mockRejectedValue(new Error('SDK not available')),
16
+ };
17
+ });
18
+ // Mock the logger so we can assert error logging
19
+ vi.mock('../../../src/logging/logger.js', () => {
20
+ const fakeLogger = {
21
+ error: vi.fn(),
22
+ warn: vi.fn(),
23
+ info: vi.fn(),
24
+ debug: vi.fn(),
25
+ fatal: vi.fn(),
26
+ child: vi.fn().mockReturnThis(),
27
+ };
28
+ return {
29
+ getLogger: vi.fn(() => fakeLogger),
30
+ createLogger: vi.fn(() => fakeLogger),
31
+ initGlobalLogger: vi.fn(() => fakeLogger),
32
+ };
33
+ });
34
+ import { workshopCommand } from '../../../src/cli/workshopCommand.js';
35
+ import { getLogger } from '../../../src/logging/logger.js';
36
+ describe('workshopCommand — client creation failure', () => {
37
+ let exitCodeBefore;
38
+ beforeEach(() => {
39
+ exitCodeBefore = process.exitCode;
40
+ process.exitCode = undefined;
41
+ });
42
+ afterEach(() => {
43
+ process.exitCode = exitCodeBefore;
44
+ vi.restoreAllMocks();
45
+ });
46
+ it('logs the error when createCopilotClient fails', async () => {
47
+ // Run with --new-session --non-interactive so no menus block
48
+ await workshopCommand({
49
+ newSession: true,
50
+ nonInteractive: true,
51
+ json: true,
52
+ });
53
+ const logger = getLogger();
54
+ expect(logger.error).toHaveBeenCalledWith(expect.objectContaining({ err: expect.any(Error) }), expect.stringContaining('Copilot'));
55
+ });
56
+ it('sets non-zero exit code when SDK is unavailable', async () => {
57
+ await workshopCommand({
58
+ newSession: true,
59
+ nonInteractive: true,
60
+ json: true,
61
+ });
62
+ expect(process.exitCode).not.toBe(0);
63
+ expect(process.exitCode).toBeDefined();
64
+ });
65
+ it('does not silently fall back to fake client', async () => {
66
+ // Capture stdout to check there is no fake "Welcome" response
67
+ const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
68
+ await workshopCommand({
69
+ newSession: true,
70
+ nonInteractive: true,
71
+ json: true,
72
+ });
73
+ const allOutput = writeSpy.mock.calls.map(c => String(c[0])).join('');
74
+ // Should NOT contain the canned fake response
75
+ expect(allOutput).not.toContain('Welcome to the AI Discovery Workshop');
76
+ // Should contain an error indication
77
+ expect(allOutput).toContain('error');
78
+ writeSpy.mockRestore();
79
+ });
80
+ });
@@ -0,0 +1,329 @@
1
+ /**
2
+ * Unit tests for workshopCommand — session name display, Plan→Develop
3
+ * transition guidance (T052), and auto-transition prompt (T053).
4
+ */
5
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
6
+ // ── Mocks ───────────────────────────────────────────────────────────────────
7
+ const mockStore = {
8
+ load: vi.fn(),
9
+ save: vi.fn().mockResolvedValue(undefined),
10
+ exists: vi.fn(),
11
+ list: vi.fn(),
12
+ };
13
+ vi.mock('../../../src/sessions/sessionStore.js', () => ({
14
+ createDefaultStore: () => mockStore,
15
+ SessionStore: vi.fn(),
16
+ }));
17
+ // Minimal fake CopilotClient
18
+ const fakeClient = {
19
+ async createSession() {
20
+ return {
21
+ send: async function* () {
22
+ yield { type: 'TextDelta', text: 'Hello!', timestamp: new Date().toISOString() };
23
+ },
24
+ getHistory: () => [],
25
+ };
26
+ },
27
+ };
28
+ vi.mock('../../../src/shared/copilotClient.js', async (importOriginal) => {
29
+ const orig = await importOriginal();
30
+ return {
31
+ ...orig,
32
+ createCopilotClient: vi.fn().mockResolvedValue(fakeClient),
33
+ };
34
+ });
35
+ vi.mock('../../../src/logging/logger.js', () => {
36
+ const fakeLogger = {
37
+ error: vi.fn(),
38
+ warn: vi.fn(),
39
+ info: vi.fn(),
40
+ debug: vi.fn(),
41
+ fatal: vi.fn(),
42
+ child: vi.fn().mockReturnThis(),
43
+ };
44
+ return {
45
+ getLogger: vi.fn(() => fakeLogger),
46
+ createLogger: vi.fn(() => fakeLogger),
47
+ initGlobalLogger: vi.fn(() => fakeLogger),
48
+ };
49
+ });
50
+ // Track LoopIO writes — decision gate is configurable per test
51
+ let ioWrites = [];
52
+ let ioReadResponses = [];
53
+ let ioReadIndex = 0;
54
+ let ioReadInputPrompts = [];
55
+ let decisionGateResponses = [];
56
+ let decisionGateIndex = 0;
57
+ vi.mock('../../../src/cli/ioContext.js', () => ({
58
+ createLoopIO: () => ({
59
+ write: (text) => {
60
+ ioWrites.push(text);
61
+ },
62
+ writeActivity: () => { },
63
+ readInput: async (prompt) => {
64
+ if (prompt)
65
+ ioReadInputPrompts.push(prompt);
66
+ if (ioReadIndex >= ioReadResponses.length)
67
+ return null;
68
+ return ioReadResponses[ioReadIndex++];
69
+ },
70
+ showDecisionGate: async () => {
71
+ if (decisionGateIndex < decisionGateResponses.length) {
72
+ return decisionGateResponses[decisionGateIndex++];
73
+ }
74
+ return { choice: 'exit' };
75
+ },
76
+ isJsonMode: false,
77
+ isTTY: true,
78
+ }),
79
+ }));
80
+ // Mock phaseHandlers to avoid loading prompts
81
+ vi.mock('../../../src/phases/phaseHandlers.js', async (importOriginal) => {
82
+ const orig = await importOriginal();
83
+ return {
84
+ ...orig,
85
+ createPhaseHandler: () => ({
86
+ phase: 'Discover',
87
+ buildSystemPrompt: () => 'system prompt',
88
+ getReferences: () => [],
89
+ extractResult: () => ({}),
90
+ isComplete: () => false,
91
+ _preload: async () => { },
92
+ }),
93
+ };
94
+ });
95
+ describe('workshopCommand session name display (T064b)', () => {
96
+ beforeEach(() => {
97
+ ioWrites = [];
98
+ ioReadResponses = [];
99
+ ioReadIndex = 0;
100
+ ioReadInputPrompts = [];
101
+ decisionGateResponses = [];
102
+ decisionGateIndex = 0;
103
+ vi.clearAllMocks();
104
+ process.exitCode = undefined;
105
+ });
106
+ afterEach(() => {
107
+ process.exitCode = undefined;
108
+ });
109
+ it('displays session name on new session creation message', async () => {
110
+ // Simulate: main menu → choose "new" (option 1) → session starts → exit
111
+ ioReadResponses = ['1']; // Pick new session
112
+ mockStore.list.mockResolvedValue([]);
113
+ const { workshopCommand } = await import('../../../src/cli/workshopCommand.js');
114
+ await workshopCommand({});
115
+ const allOutput = ioWrites.join(' ');
116
+ // New session should show session ID (timestamp format)
117
+ expect(allOutput).toContain('New session');
118
+ });
119
+ it('displays session name when resuming a named session', async () => {
120
+ const session = {
121
+ sessionId: '2026-01-01_120000',
122
+ schemaVersion: '1.0.0',
123
+ createdAt: '2026-01-01T12:00:00Z',
124
+ updatedAt: '2026-01-01T12:30:00Z',
125
+ phase: 'Discover',
126
+ status: 'Active',
127
+ participants: [],
128
+ artifacts: { generatedFiles: [] },
129
+ turns: [],
130
+ name: 'Logistics AI Workshop',
131
+ };
132
+ mockStore.exists.mockResolvedValue(true);
133
+ mockStore.load.mockResolvedValue(session);
134
+ const { workshopCommand } = await import('../../../src/cli/workshopCommand.js');
135
+ await workshopCommand({ session: '2026-01-01_120000' });
136
+ // The session name should appear in the output somewhere
137
+ const allOutput = ioWrites.join(' ');
138
+ expect(allOutput).toContain('Logistics AI Workshop');
139
+ });
140
+ it('displays session name in pause message when session has a name', async () => {
141
+ const session = {
142
+ sessionId: '2026-01-01_120000',
143
+ schemaVersion: '1.0.0',
144
+ createdAt: '2026-01-01T12:00:00Z',
145
+ updatedAt: '2026-01-01T12:30:00Z',
146
+ phase: 'Discover',
147
+ status: 'Active',
148
+ participants: [],
149
+ artifacts: { generatedFiles: [] },
150
+ turns: [],
151
+ name: 'Retail Insights',
152
+ };
153
+ mockStore.exists.mockResolvedValue(true);
154
+ mockStore.load.mockResolvedValue(session);
155
+ const { workshopCommand } = await import('../../../src/cli/workshopCommand.js');
156
+ // Direct session mode triggers run → decision gate returns exit → pauses
157
+ await workshopCommand({ session: '2026-01-01_120000' });
158
+ const allOutput = ioWrites.join(' ');
159
+ expect(allOutput).toContain('Retail Insights');
160
+ });
161
+ it('shows only session ID when no name is set', async () => {
162
+ const session = {
163
+ sessionId: '2026-01-01_120000',
164
+ schemaVersion: '1.0.0',
165
+ createdAt: '2026-01-01T12:00:00Z',
166
+ updatedAt: '2026-01-01T12:30:00Z',
167
+ phase: 'Discover',
168
+ status: 'Active',
169
+ participants: [],
170
+ artifacts: { generatedFiles: [] },
171
+ turns: [],
172
+ };
173
+ mockStore.exists.mockResolvedValue(true);
174
+ mockStore.load.mockResolvedValue(session);
175
+ const { workshopCommand } = await import('../../../src/cli/workshopCommand.js');
176
+ await workshopCommand({ session: '2026-01-01_120000' });
177
+ const allOutput = ioWrites.join(' ');
178
+ expect(allOutput).toContain('2026-01-01_120000');
179
+ });
180
+ it('shows only named sessions in the resume list', async () => {
181
+ const namedSession = {
182
+ sessionId: '2026-02-28_165120',
183
+ schemaVersion: '1.0.0',
184
+ createdAt: '2026-02-28T16:51:20Z',
185
+ updatedAt: '2026-02-28T16:55:00Z',
186
+ phase: 'Discover',
187
+ status: 'Active',
188
+ participants: [],
189
+ artifacts: { generatedFiles: [] },
190
+ turns: [],
191
+ name: 'Inventory Insights',
192
+ };
193
+ const unnamedSession = {
194
+ sessionId: '2026-02-28_170457',
195
+ schemaVersion: '1.0.0',
196
+ createdAt: '2026-02-28T17:04:57Z',
197
+ updatedAt: '2026-02-28T17:05:00Z',
198
+ phase: 'Discover',
199
+ status: 'Active',
200
+ participants: [],
201
+ artifacts: { generatedFiles: [] },
202
+ turns: [],
203
+ };
204
+ ioReadResponses = ['2', '1']; // Resume flow, choose first session
205
+ mockStore.list.mockResolvedValue([namedSession.sessionId, unnamedSession.sessionId]);
206
+ mockStore.load.mockImplementation(async (id) => {
207
+ if (id === namedSession.sessionId)
208
+ return namedSession;
209
+ if (id === unnamedSession.sessionId)
210
+ return unnamedSession;
211
+ throw new Error('Unknown session');
212
+ });
213
+ const { workshopCommand } = await import('../../../src/cli/workshopCommand.js');
214
+ await workshopCommand({});
215
+ const allOutput = ioWrites.join(' ');
216
+ expect(allOutput).toContain('Available sessions');
217
+ // Named session appears in the list
218
+ expect(allOutput).toContain('Inventory Insights');
219
+ expect(allOutput).toContain('2026-02-28_165120');
220
+ // Unnamed session is filtered out
221
+ expect(allOutput).not.toContain('2026-02-28_170457');
222
+ });
223
+ });
224
+ // ── T052: Plan→Develop transition displays "sofia dev --session {id}" ─────
225
+ describe('workshopCommand Plan→Develop transition (T052)', () => {
226
+ beforeEach(() => {
227
+ ioWrites = [];
228
+ ioReadResponses = [];
229
+ ioReadIndex = 0;
230
+ ioReadInputPrompts = [];
231
+ decisionGateResponses = [];
232
+ decisionGateIndex = 0;
233
+ vi.clearAllMocks();
234
+ process.exitCode = undefined;
235
+ });
236
+ afterEach(() => {
237
+ process.exitCode = undefined;
238
+ });
239
+ it('displays "sofia dev --session {id}" after Plan phase completes (FR-020)', async () => {
240
+ const session = {
241
+ sessionId: 'plan-test-001',
242
+ schemaVersion: '1.0.0',
243
+ createdAt: '2026-01-01T12:00:00Z',
244
+ updatedAt: '2026-01-01T12:30:00Z',
245
+ phase: 'Plan',
246
+ status: 'Active',
247
+ participants: [],
248
+ artifacts: { generatedFiles: [] },
249
+ turns: [],
250
+ };
251
+ mockStore.exists.mockResolvedValue(true);
252
+ mockStore.load.mockResolvedValue(session);
253
+ // First gate (Plan): continue → triggers transition to Develop
254
+ // Second gate (Develop): exit → stops the loop
255
+ decisionGateResponses = [{ choice: 'continue' }, { choice: 'exit' }];
256
+ const { workshopCommand } = await import('../../../src/cli/workshopCommand.js');
257
+ await workshopCommand({ session: 'plan-test-001' });
258
+ const allOutput = ioWrites.join(' ');
259
+ expect(allOutput).toContain('sofia dev --session plan-test-001');
260
+ expect(allOutput).toContain('Ready for PoC Generation');
261
+ });
262
+ });
263
+ // ── T053: Workshop offers auto-transition prompt in interactive mode ──────
264
+ describe('workshopCommand auto-transition prompt (T053)', () => {
265
+ beforeEach(() => {
266
+ ioWrites = [];
267
+ ioReadResponses = [];
268
+ ioReadIndex = 0;
269
+ ioReadInputPrompts = [];
270
+ decisionGateResponses = [];
271
+ decisionGateIndex = 0;
272
+ vi.clearAllMocks();
273
+ process.exitCode = undefined;
274
+ });
275
+ afterEach(() => {
276
+ process.exitCode = undefined;
277
+ });
278
+ it('offers auto-transition prompt in interactive mode after Plan phase (FR-021)', async () => {
279
+ const session = {
280
+ sessionId: 'transition-test-001',
281
+ schemaVersion: '1.0.0',
282
+ createdAt: '2026-01-01T12:00:00Z',
283
+ updatedAt: '2026-01-01T12:30:00Z',
284
+ phase: 'Plan',
285
+ status: 'Active',
286
+ participants: [],
287
+ artifacts: { generatedFiles: [] },
288
+ turns: [],
289
+ };
290
+ mockStore.exists.mockResolvedValue(true);
291
+ mockStore.load.mockResolvedValue(session);
292
+ // Continue from Plan → Develop, then exit
293
+ decisionGateResponses = [{ choice: 'continue' }, { choice: 'exit' }];
294
+ const { workshopCommand } = await import('../../../src/cli/workshopCommand.js');
295
+ await workshopCommand({ session: 'transition-test-001' });
296
+ const allOutput = ioWrites.join(' ');
297
+ // FR-021: The transition message includes tech stack info and scaffolding description
298
+ expect(allOutput).toContain('scaffold a project');
299
+ expect(allOutput).toContain('technology stack');
300
+ expect(allOutput).toContain('install dependencies');
301
+ // FR-021: readInput was called with the auto-transition prompt
302
+ expect(ioReadInputPrompts.some((p) => p.includes('Would you like to start PoC development'))).toBe(true);
303
+ });
304
+ it('exits workshop when user accepts auto-transition prompt (FR-021)', async () => {
305
+ const session = {
306
+ sessionId: 'auto-transition-001',
307
+ schemaVersion: '1.0.0',
308
+ createdAt: '2026-01-01T12:00:00Z',
309
+ updatedAt: '2026-01-01T12:30:00Z',
310
+ phase: 'Plan',
311
+ status: 'Active',
312
+ participants: [],
313
+ artifacts: { generatedFiles: [] },
314
+ turns: [],
315
+ };
316
+ mockStore.exists.mockResolvedValue(true);
317
+ mockStore.load.mockResolvedValue(session);
318
+ // Continue from Plan → user answers 'y' to auto-transition
319
+ decisionGateResponses = [{ choice: 'continue' }];
320
+ // First null exits the conversation loop; 'y' answers the auto-transition prompt
321
+ ioReadResponses = [null, 'y'];
322
+ const { workshopCommand } = await import('../../../src/cli/workshopCommand.js');
323
+ await workshopCommand({ session: 'auto-transition-001' });
324
+ const allOutput = ioWrites.join(' ');
325
+ // Workshop should show transition message and exit (returning early)
326
+ expect(allOutput).toContain('Starting PoC development');
327
+ expect(allOutput).toContain('sofia dev --session auto-transition-001');
328
+ });
329
+ });
@@ -0,0 +1,13 @@
1
+ import { describe, expect, it } from 'vitest';
2
+ import liveConfig from '../../../vitest.live.config';
3
+ import defaultConfig from '../../../vitest.config';
4
+ describe('Vitest env setup', () => {
5
+ it('declares a setup file for default tests', () => {
6
+ const config = defaultConfig;
7
+ expect(config.test?.setupFiles).toContain('tests/setup/loadEnv.ts');
8
+ });
9
+ it('declares a setup file for live tests', () => {
10
+ const config = liveConfig;
11
+ expect(config.test?.setupFiles).toContain('tests/setup/loadEnv.ts');
12
+ });
13
+ });