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,149 @@
1
+ # Data Model: Workshop Phase Extraction & Tool Wiring Fixes
2
+
3
+ **Feature**: 006-workshop-extraction-fixes
4
+ **Date**: 2026-03-04
5
+
6
+ ## New Entities
7
+
8
+ ### SummarizedPhaseContext
9
+
10
+ A compact, deterministic projection of all structured session fields from prior phases. Used to build the system prompt for each new phase, replacing ad-hoc per-handler context injection.
11
+
12
+ | Field | Type | Source | Description |
13
+ | ---------------------- | ---------------------------------- | ---------------------------------------------------------------------------- | --------------------------------------------------------- |
14
+ | `businessSummary` | `string?` | `session.businessContext.businessDescription` | Company/business description from Discover |
15
+ | `challenges` | `string[]?` | `session.businessContext.challenges` | Key challenges from Discover |
16
+ | `topicArea` | `string?` | `session.topic.topicArea` | Chosen workshop focus area |
17
+ | `workflowSteps` | `string[]?` | `session.workflow.activities[].name` | Activity names from the workflow map |
18
+ | `enrichmentHighlights` | `string[]?` | `session.discovery.enrichment.{industryTrends, companyNews, workiqInsights}` | Web search and WorkIQ highlights from Discover enrichment |
19
+ | `ideaSummaries` | `Array<{id, title, description}>?` | `session.ideas[]` | Idea card summaries from Ideate |
20
+ | `evaluationSummary` | `string?` | `session.evaluation` | Evaluation method + idea count from Design |
21
+ | `selectionSummary` | `string?` | `session.selection` | Selected idea ID + rationale from Select |
22
+ | `planMilestones` | `string[]?` | `session.plan.milestones[].title` | Milestone titles from Plan |
23
+ | `architectureNotes` | `string?` | `session.plan.architectureNotes` | Architecture description from Plan |
24
+
25
+ **Relationships**: Pure projection from `WorkshopSession` fields. No persistence — generated on-the-fly at each phase transition.
26
+
27
+ **Validation**: No schema validation needed (it's a rendering utility). Each field is optional; missing fields are omitted from the rendered output.
28
+
29
+ ---
30
+
31
+ ### PhaseSummarizationPrompt
32
+
33
+ The system prompt sent to the LLM during the post-phase summarization call. Phase-specific.
34
+
35
+ | Field | Type | Description |
36
+ | ------------------- | ------------ | -------------------------------------------------------------------------------- |
37
+ | `phase` | `PhaseValue` | Which phase this summarization targets |
38
+ | `systemPrompt` | `string` | Loaded from `src/prompts/summarize/{phase}-summary.md` |
39
+ | `targetSchemaShape` | `string` | JSON schema example embedded in the prompt (matched to Zod schema) |
40
+ | `phaseTranscript` | `string` | Full conversation transcript for the phase (user + assistant turns concatenated) |
41
+
42
+ **Relationships**: One summarization prompt per phase (6 total, though Discover may not need one since `businessContext` extraction already works). The prompt template references the Zod schema from `session.ts`.
43
+
44
+ ---
45
+
46
+ ### McpWorkshopConfig
47
+
48
+ Configuration passed from `workshopCommand.ts` to phase handler factories.
49
+
50
+ | Field | Type | Description |
51
+ | ----------------- | ------------------ | ----------------------------------- |
52
+ | `mcpManager` | `McpManager?` | MCP manager instance for tool calls |
53
+ | `webSearchClient` | `WebSearchClient?` | Foundry web search client |
54
+
55
+ **Relationships**: Extends the existing `PhaseHandlerConfig`. Passed to `createPhaseHandler()` which distributes to individual handler factories.
56
+
57
+ ---
58
+
59
+ ## Modified Entities
60
+
61
+ ### WorkshopSession (existing — no schema changes)
62
+
63
+ No fields are added or modified on the session schema. All 29 FRs operate on **existing** session fields:
64
+
65
+ - `businessContext` (Discover)
66
+ - `workflow` (Discover)
67
+ - `ideas` (Ideate)
68
+ - `evaluation` (Design)
69
+ - `selection` (Select)
70
+ - `plan` (Plan)
71
+ - `poc` (Develop)
72
+ - `turns[]` (all phases)
73
+ - `discovery.enrichment` (Discover enrichment)
74
+
75
+ The only change is that these fields will now be **reliably populated** thanks to the summarization call fallback.
76
+
77
+ ### PhaseHandlerConfig (existing — extended)
78
+
79
+ Currently:
80
+
81
+ ```
82
+ { discover?: DiscoverHandlerConfig }
83
+ ```
84
+
85
+ After:
86
+
87
+ ```
88
+ { discover?: DiscoverHandlerConfig, mcpManager?: McpManager, webSearchClient?: WebSearchClient }
89
+ ```
90
+
91
+ ### ConversationLoopOptions (existing — extended)
92
+
93
+ Added field:
94
+
95
+ - `infiniteSessions?: { enabled?: boolean, backgroundCompactionThreshold?: number, bufferExhaustionThreshold?: number }` — forwarded to the SDK session for context compaction.
96
+
97
+ ---
98
+
99
+ ## State Transitions
100
+
101
+ No new state transitions. The existing phase progression is unchanged:
102
+
103
+ ```
104
+ Discover → Ideate → Design → Select → Plan → Develop → Complete
105
+ ```
106
+
107
+ Each transition now has an additional step between the conversation loop completing and the decision gate:
108
+
109
+ ```
110
+ ConversationLoop exits
111
+ → Post-phase summarization call (if structured fields still null)
112
+ → Session persisted with extracted data
113
+ → Decision gate shown to user
114
+ ```
115
+
116
+ ---
117
+
118
+ ## Data Flow Diagram
119
+
120
+ ```
121
+ ┌─────────────┐ ┌──────────────┐ ┌──────────────────┐
122
+ │ Phase N conv │────▸│ extractResult│────▸│ session field set?│
123
+ │ loop exits │ │ (per-turn) │ │ (e.g. ideas) │
124
+ └──────┬───────┘ └──────────────┘ └────────┬─────────┘
125
+ │ │
126
+ │ yes ───┴─── no
127
+ │ │ │
128
+ │ │ ┌─────▼──────────┐
129
+ │ │ │ Summarization │
130
+ │ │ │ LLM call │
131
+ │ │ │ (new session) │
132
+ │ │ └──────┬─────────┘
133
+ │ │ │
134
+ │ │ ┌──────▼─────────┐
135
+ │ │ │ extractResult │
136
+ │ │ │ on summary │
137
+ │ │ └──────┬─────────┘
138
+ │ │ │
139
+ ▼ ▼ ▼
140
+ ┌──────────────────────────────────────────────────────────┐
141
+ │ Session persisted with data │
142
+ └──────────────────────────────────────────────────────────┘
143
+
144
+
145
+ ┌──────────────┐ ┌───────────────────────┐
146
+ │ Context │────▸│ Phase N+1 starts with │
147
+ │ summarizer │ │ SummarizedPhaseContext │
148
+ └──────────────┘ └───────────────────────┘
149
+ ```
@@ -0,0 +1,123 @@
1
+ # Implementation Plan: Workshop Phase Extraction & Tool Wiring Fixes
2
+
3
+ **Branch**: `006-workshop-extraction-fixes` | **Date**: 2026-03-04 | **Spec**: [spec.md](spec.md)
4
+ **Input**: Feature specification from `/specs/006-workshop-extraction-fixes/spec.md`
5
+
6
+ ## Summary
7
+
8
+ Fix five systemic bugs discovered during the Zava Industries full-session assessment that prevent sofIA from: (1) reliably extracting structured data from LLM responses across all workshop phases, (2) recognizing web search configuration when `.env` is loaded after module import, (3) wiring MCP tools into the workshop flow, (4) managing context window growth across multi-phase sessions, and (5) exporting all phases regardless of structured data availability. The primary technical approach is a post-phase summarization LLM call for extraction, lazy env checking, McpManager/WebSearchClient wiring in workshopCommand, context summarization instead of raw turn injection, and conversation-fallback export generation.
9
+
10
+ ## Technical Context
11
+
12
+ **Language/Version**: TypeScript 5.x on Node.js 22 LTS
13
+ **Primary Dependencies**: `@github/copilot-sdk`, `zod` (schema validation), `marked`/`marked-terminal` (markdown rendering), `pino` (logging), `commander` (CLI), `dotenv` (.env loading)
14
+ **Storage**: Single JSON file per session in `.sofia/sessions/<sessionId>.json`
15
+ **Testing**: Vitest (unit + integration + live); 709 unit tests, 99 integration tests currently passing
16
+ **Target Platform**: Linux/macOS/Windows (Node.js CLI)
17
+ **Project Type**: CLI application
18
+ **Performance Goals**: Phase summarization call must complete within 60 seconds; context summary generation adds <500ms to phase transitions
19
+ **Constraints**: Copilot SDK `sendAndWait()` has a 120s timeout; session JSON files can grow to 100KB+ for multi-phase sessions
20
+ **Scale/Scope**: 6 workshop phases, ~10–15 conversation turns per phase, 29 functional requirements across 6 categories
21
+
22
+ ## Constitution Check
23
+
24
+ _GATE: Must pass before Phase 0 research. Re-check after Phase 1 design._
25
+
26
+ | Gate | Status | Evidence |
27
+ | ------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
28
+ | **Outcome-first discovery** | ✅ PASS | All 5 bugs directly prevent workshop artifacts from reaching users. SC-006 targets 75%+ assessment score (up from 53%). |
29
+ | **Secure-by-default** | ✅ PASS | No new secrets/PII handling. `.env` loading respects existing `override: false` policy. MCP calls follow existing least-privilege patterns. |
30
+ | **Node.js + TypeScript** | ✅ PASS | All changes are TypeScript, aligned with existing Copilot SDK patterns. No new runtime dependencies required. |
31
+ | **MCP-first** | ✅ PASS | FR-011–FR-015 wire existing MCP servers (Context7, Azure, WorkIQ) into workshop phases. No ad-hoc HTTP calls introduced. |
32
+ | **Test-first (NON-NEGOTIABLE)** | ✅ PASS | Each FR group will be implemented via Red→Green→Review. Failing tests written first for: summarization call, lazy env check, export fallback, context summarization, MCP wiring. |
33
+ | **CLI transparency** | ✅ PASS | Summarization call progress surfaced via existing spinner. Export generates files for all phases. Phase boundary prompts improve UX predictability. |
34
+
35
+ ## Project Structure
36
+
37
+ ### Documentation (this feature)
38
+
39
+ ```text
40
+ specs/006-workshop-extraction-fixes/
41
+ ├── plan.md # This file
42
+ ├── research.md # Phase 0 output
43
+ ├── data-model.md # Phase 1 output
44
+ ├── quickstart.md # Phase 1 output
45
+ ├── contracts/ # Phase 1 output
46
+ │ └── summarization-and-export.md
47
+ ├── checklists/
48
+ │ └── requirements.md # Quality checklist
49
+ └── tasks.md # Phase 2 output (NOT created by /speckit.plan)
50
+ ```
51
+
52
+ ### Source Code (files modified or created)
53
+
54
+ ```text
55
+ src/
56
+ ├── cli/
57
+ │ ├── workshopCommand.ts # FR-011,012,012a: wire McpManager + WebSearchClient; FR-010: ensure loadEnvFile runs first
58
+ │ └── developCommand.ts # FR-010: ensure loadEnvFile runs first
59
+ ├── loop/
60
+ │ ├── conversationLoop.ts # FR-001,006: add postPhaseSummarize(); FR-016–018: context summarization; FR-007b,c: phase boundary injection; FR-019a: timeout fallback
61
+ │ └── phaseSummarizer.ts # NEW: summarization LLM call utility (FR-001–005)
62
+ ├── mcp/
63
+ │ └── webSearch.ts # FR-008,009: make isWebSearchConfigured() lazy
64
+ ├── phases/
65
+ │ ├── phaseExtractors.ts # FR-007: multi-JSON-block extraction; FR-007a: Mermaid extraction
66
+ │ ├── phaseHandlers.ts # FR-013,014: Design/Plan accept MCP config; FR-007b: phase boundary in buildSystemPrompt
67
+ │ └── contextSummarizer.ts # NEW: build SummarizedPhaseContext from session fields (FR-016–018)
68
+ ├── sessions/
69
+ │ └── exportWriter.ts # FR-020–024: conversation fallback export, summary.json enhancements
70
+ └── prompts/
71
+ └── summarize/ # NEW: per-phase summarization prompts (FR-002)
72
+ ├── ideate-summary.md
73
+ ├── design-summary.md
74
+ ├── select-summary.md
75
+ ├── plan-summary.md
76
+ └── develop-summary.md
77
+
78
+ tests/
79
+ ├── unit/
80
+ │ ├── loop/
81
+ │ │ ├── phaseSummarizer.spec.ts # Tests for summarization call
82
+ │ │ └── contextSummarizer.spec.ts # Tests for context summarization
83
+ │ ├── mcp/
84
+ │ │ └── webSearch.spec.ts # Tests for lazy isWebSearchConfigured
85
+ │ ├── phases/
86
+ │ │ ├── phaseExtractors.spec.ts # Tests for multi-block extraction + Mermaid
87
+ │ │ └── phaseHandlers.spec.ts # Tests for phase boundary injection, MCP config
88
+ │ └── sessions/
89
+ │ └── exportWriter.spec.ts # Tests for conversation fallback export
90
+ ├── integration/
91
+ │ ├── summarizationFlow.spec.ts # Integration test: full summarize pipeline
92
+ │ └── exportFallbackFlow.spec.ts # Integration test: export with null structured data
93
+ └── live/
94
+ └── zavaFullWorkshop.spec.ts # Updated Zava assessment test (regression)
95
+ ```
96
+
97
+ **Structure Decision**: Single-project CLI structure preserved. Two new modules (`phaseSummarizer.ts`, `contextSummarizer.ts`) are extracted to avoid bloating `conversationLoop.ts`. New summarization prompts are placed under `src/prompts/summarize/` following the existing prompt organization pattern.
98
+
99
+ ## Complexity Tracking
100
+
101
+ > No constitution violations. All gates pass.
102
+
103
+ ## Constitution Re-Check (Post-Design)
104
+
105
+ | Gate | Status | Evidence |
106
+ | ------------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
107
+ | **Outcome-first discovery** | ✅ PASS | Summarization call directly enables structured artifact extraction → export → `sofia dev` → user value. All changes tie to the 53%→75% assessment improvement goal. |
108
+ | **Secure-by-default** | ✅ PASS | Summarization call sends only conversation turns to the LLM (same data already in the system). No new secrets, PII, or external data paths introduced. MCP wiring uses existing least-privilege patterns. |
109
+ | **Node.js + TypeScript** | ✅ PASS | Two new TypeScript modules (`phaseSummarizer.ts`, `contextSummarizer.ts`), 5 new prompt markdown files. All follow existing patterns. |
110
+ | **MCP-first** | ✅ PASS | Design/Plan phases wired to use Context7 and Azure MCP via existing `McpManager`. No ad-hoc HTTP calls. |
111
+ | **Test-first (NON-NEGOTIABLE)** | ✅ PASS | Each FR group has a dedicated test file. Failing tests written before implementation. Zava assessment test serves as regression gate. |
112
+ | **CLI transparency** | ✅ PASS | Summarization call uses existing spinner (`Thinking...`). Phase boundary prompt prevents confusing phase drift. Export includes all phases so users see full workshop output. |
113
+
114
+ ## Generated Artifacts
115
+
116
+ | Artifact | Path | Description |
117
+ | ----------------- | --------------------------------------------------------------------------- | --------------------------------------------------------- |
118
+ | Plan | `specs/006-workshop-extraction-fixes/plan.md` | This file |
119
+ | Research | `specs/006-workshop-extraction-fixes/research.md` | 7 research topics with decisions, rationale, alternatives |
120
+ | Data Model | `specs/006-workshop-extraction-fixes/data-model.md` | 3 new entities, 0 schema changes, data flow diagram |
121
+ | Contracts | `specs/006-workshop-extraction-fixes/contracts/summarization-and-export.md` | Summarization call interface + export fallback contract |
122
+ | Quickstart | `specs/006-workshop-extraction-fixes/quickstart.md` | Development setup, file map, TDD workflow, verification |
123
+ | Quality Checklist | `specs/006-workshop-extraction-fixes/checklists/requirements.md` | Bug traceability + cross-spec gap coverage |
@@ -0,0 +1,101 @@
1
+ # Quickstart: Workshop Phase Extraction & Tool Wiring Fixes
2
+
3
+ **Feature**: 006-workshop-extraction-fixes
4
+ **Date**: 2026-03-04
5
+
6
+ ## Prerequisites
7
+
8
+ - Node.js 22 LTS
9
+ - GitHub Copilot CLI authenticated (`copilot auth login`)
10
+ - `.env` with `FOUNDRY_PROJECT_ENDPOINT` + `FOUNDRY_MODEL_DEPLOYMENT_NAME` (for web search)
11
+ - `.vscode/mcp.json` with MCP server configurations (for Context7, Azure, WorkIQ)
12
+
13
+ ## Development Setup
14
+
15
+ ```bash
16
+ git checkout 006-workshop-extraction-fixes
17
+ npm install
18
+ npm run build
19
+ ```
20
+
21
+ ## Key Files to Modify
22
+
23
+ ### Phase 1: Lazy Web Search Config (BUG-001)
24
+
25
+ ```
26
+ src/mcp/webSearch.ts # isWebSearchConfigured() — already lazy, verify no caching
27
+ src/cli/workshopCommand.ts # Ensure loadEnvFile() called at entry point
28
+ src/cli/developCommand.ts # Same
29
+ ```
30
+
31
+ ### Phase 2: Phase Extraction Hardening (BUG-002)
32
+
33
+ ```
34
+ src/loop/phaseSummarizer.ts # NEW — post-phase summarization utility
35
+ src/phases/phaseExtractors.ts # extractAllJsonBlocks(), extractJsonBlockForSchema()
36
+ src/prompts/summarize/*.md # NEW — per-phase summarization prompts (5 files)
37
+ src/loop/conversationLoop.ts # Hook phaseSummarize() after while loop
38
+ ```
39
+
40
+ ### Phase 3: Context Window Management (BUG-003)
41
+
42
+ ```
43
+ src/phases/contextSummarizer.ts # NEW — buildSummarizedContext(), renderSummarizedContext()
44
+ src/phases/phaseHandlers.ts # Replace ad-hoc context blocks with contextSummarizer
45
+ src/loop/conversationLoop.ts # Add infiniteSessions + phase boundary injection
46
+ ```
47
+
48
+ ### Phase 4: MCP Tool Wiring (BUG-005)
49
+
50
+ ```
51
+ src/cli/workshopCommand.ts # Create McpManager, WebSearchClient; pass to handlers
52
+ src/phases/phaseHandlers.ts # Extend PhaseHandlerConfig; Design/Plan accept MCP config
53
+ ```
54
+
55
+ ### Phase 5: Export Completeness (BUG-004)
56
+
57
+ ```
58
+ src/sessions/exportWriter.ts # Remove early-return guards, add conversation fallback
59
+ ```
60
+
61
+ ## Running Tests
62
+
63
+ ```bash
64
+ # Unit tests (fast, ~10s)
65
+ npm run test:unit
66
+
67
+ # Integration tests (~15s)
68
+ npm run test:integration
69
+
70
+ # Live Zava assessment test (~13min, requires Copilot auth)
71
+ npm run test:live -- tests/live/zavaFullWorkshop.spec.ts
72
+
73
+ # Full suite
74
+ npm test
75
+ ```
76
+
77
+ ## TDD Workflow (per phase)
78
+
79
+ 1. **Red**: Write failing tests in `tests/unit/` for the target FR group
80
+ 2. **Green**: Implement minimum code to pass
81
+ 3. **Review**: Run full suite (`npm test`), check `npm run typecheck` and `npm run lint`
82
+ 4. Repeat for next FR group
83
+
84
+ ## Verification
85
+
86
+ After all changes, run the Zava assessment test:
87
+
88
+ ```bash
89
+ npm run test:live -- tests/live/zavaFullWorkshop.spec.ts
90
+ ```
91
+
92
+ Expected improvement: assessment score from 53% → 75%+ (SC-006).
93
+
94
+ Key checks:
95
+
96
+ - `session.ideas` populated after Ideate (was null)
97
+ - `session.evaluation` populated after Design (was null)
98
+ - `session.selection` populated after Select (was null + timeout)
99
+ - `session.plan` populated after Plan (was null)
100
+ - Export produces 6 markdown files (was 1)
101
+ - Web search called during Discover (was skipped)
@@ -0,0 +1,143 @@
1
+ # Research: Workshop Phase Extraction & Tool Wiring Fixes
2
+
3
+ **Feature**: 006-workshop-extraction-fixes
4
+ **Date**: 2026-03-04
5
+
6
+ ## Topic 1: Post-Phase Summarization LLM Call (FR-001–FR-007)
7
+
8
+ ### Decision: Dedicated summarization call with a new ConversationSession
9
+
10
+ ### Rationale
11
+
12
+ The LLM produces rich conversational content but inconsistently includes structured JSON blocks matching the Zod schemas. Rather than building brittle prose parsers, a dedicated "one-shot" LLM call at phase end sends the full conversation transcript with explicit extraction instructions. This leverages the LLM's own ability to restructure its output.
13
+
14
+ ### Alternatives Considered
15
+
16
+ 1. **NLP-based prose extraction** — Rejected: fragile regex/heuristic parsers for markdown tables, bullet lists, and prose. High maintenance, low accuracy.
17
+ 2. **Instruct LLM to always output JSON inline** — Rejected: makes conversation unnatural, degrades facilitator UX, and the LLM still drifts.
18
+ 3. **Post-process each turn** — Current approach (already implemented). Retained as primary path; summarization is the fallback.
19
+
20
+ ### Implementation Details
21
+
22
+ - **Insertion point**: After the `while` loop in `ConversationLoop.run()` (~line 193), before `return this.session`.
23
+ - **Session strategy**: Create a **new** `ConversationSession` (not reuse the existing one) — avoids polluting conversation context and growing the already-long history. `CopilotClient.createSession()` is lightweight (SDK client is a singleton; only the session is new).
24
+ - **Prompt structure**: Phase-specific system prompt with the exact Zod schema shape, plus the full phase transcript as the user message.
25
+ - **Existing pattern**: Same as `ConversationLoop.streamResponse()` → `extractJsonBlock()` pipeline. Also mirrors the `postExtract` fire-once hook pattern from the Discover enricher.
26
+
27
+ ### Multi-Block Extraction (FR-007)
28
+
29
+ - Current `extractJsonBlock()` uses non-global regexes → only finds first match.
30
+ - New `extractAllJsonBlocks()` uses `/g` flag for fenced blocks and a bracket-depth counter for raw JSON.
31
+ - New `extractJsonBlockForSchema<T>(response, schema)` tries each block with `safeParse()`, returns first valid match.
32
+
33
+ ---
34
+
35
+ ## Topic 2: Lazy Web Search Configuration (FR-008–FR-010)
36
+
37
+ ### Decision: `isWebSearchConfigured()` already checks `process.env` at call time — but `.env` must be loaded first
38
+
39
+ ### Rationale
40
+
41
+ The function itself is stateless: `return Boolean(process.env.FOUNDRY_PROJECT_ENDPOINT && ...)`. The bug is **import ordering**: the test/CLI path may call it before `loadEnvFile()` runs. Fix: ensure `loadEnvFile()` is called at the top of `workshopCommand()` and `developCommand()` entry points.
42
+
43
+ ### Alternatives Considered
44
+
45
+ 1. **Cache the result lazily on first call** — Rejected: caching means if `.env` is loaded after the first check, the cached value is stale.
46
+ 2. **Module-level initialization** — Rejected: module load order is non-deterministic across import graphs.
47
+
48
+ ---
49
+
50
+ ## Topic 3: Context Window Management (FR-016–FR-019)
51
+
52
+ ### Decision: Deterministic `SummarizedPhaseContext` from structured session fields — no LLM call needed
53
+
54
+ ### Rationale
55
+
56
+ Context summarization doesn't require an LLM call. Structured session fields (`businessContext`, `ideas`, `evaluation`, `selection`, `plan`) are already compact data. A `buildSummarizedContext()` function projects them into a ~200-line markdown block. This is deterministic, fast (<1ms), and testable.
57
+
58
+ ### Alternatives Considered
59
+
60
+ 1. **LLM summarization of prior turns** — Rejected for context building: adds latency (30s+), costs an API call per phase, and is non-deterministic.
61
+ 2. **Truncate raw turns** — Rejected: arbitrary truncation loses coherence.
62
+ 3. **SDK `infiniteSessions`** — Adopted as a supplementary measure, not the primary fix. Forward the same config used by Ralph Loop (`backgroundCompactionThreshold: 0.7`, `bufferExhaustionThreshold: 0.9`).
63
+
64
+ ### Current Problem
65
+
66
+ Each phase handler builds ad-hoc context from only the immediately preceding phase's structured fields. If extraction failed, the next phase gets **no context at all**. The new `contextSummarizer.ts` replaces all ad-hoc context blocks with a unified, comprehensive summary that degrades gracefully when fields are null.
67
+
68
+ ---
69
+
70
+ ## Topic 4: MCP Tool Wiring in Workshop Flow (FR-011–FR-015)
71
+
72
+ ### Decision: Create McpManager + WebSearchClient in `workshopCommandInner()`, extend `PhaseHandlerConfig`
73
+
74
+ ### Rationale
75
+
76
+ The `loadMcpConfig()` and `McpManager` infrastructure already exists (Feature 003). The gap is purely wiring: `workshopCommand.ts` never creates an McpManager. The Design and Plan handlers need an optional MCP config parameter passed through `PhaseHandlerConfig`.
77
+
78
+ ### Implementation Details
79
+
80
+ - `McpManager` created from `.vscode/mcp.json` via existing `loadMcpConfig()`.
81
+ - `WebSearchClient` created from Foundry env vars via `createWebSearchClient()` (already exists).
82
+ - `PhaseHandlerConfig` extended with `mcpManager?: McpManager` and `webSearchClient?: WebSearchClient`.
83
+ - Design handler: adds `postExtract` hook that queries Context7 for libraries referenced in `session.ideas`.
84
+ - Plan handler: adds `postExtract` hook that queries Azure MCP for services referenced in `session.plan.architectureNotes`.
85
+ - All calls wrap in try/catch for graceful degradation.
86
+
87
+ ---
88
+
89
+ ## Topic 5: Export Completeness (FR-020–FR-024)
90
+
91
+ ### Decision: Remove early `return null` guards, add conversation-turn fallback to all 5 phase generators
92
+
93
+ ### Rationale
94
+
95
+ The Discover generator already has conversation-turn fallback code. The same pattern is applied to Ideate, Design, Select, Plan, and Develop generators: wrap structured rendering in an `if` guard, always include conversation turns if they exist.
96
+
97
+ ### Changes per generator
98
+
99
+ | Generator | Current guard | Change |
100
+ | --------- | ---------------------------------------------------- | ---------------------------------------------------------- |
101
+ | Ideate | `if (!session.ideas?.length) return null` | Remove; wrap idea rendering in `if`; add turn section |
102
+ | Design | `if (!session.evaluation) return null` | Remove; wrap eval rendering in `if`; add turn section |
103
+ | Select | `if (!session.selection) return null` | Remove; wrap selection rendering in `if`; add turn section |
104
+ | Plan | `if (!session.plan?.milestones?.length) return null` | Remove; wrap milestone rendering in `if`; add turn section |
105
+ | Develop | `if (!session.poc) return null` | Remove; wrap poc rendering in `if`; add turn section |
106
+
107
+ ---
108
+
109
+ ## Topic 6: Phase Boundary Enforcement (FR-007b, FR-007c)
110
+
111
+ ### Decision: Inject boundary instruction in `ConversationLoop` system prompt builder
112
+
113
+ ### Rationale
114
+
115
+ The LLM drifted between phases during the assessment (Ideate → Design, Plan → Develop). A system prompt instruction prevents this without changing phase prompts individually.
116
+
117
+ ### Implementation
118
+
119
+ In `ConversationLoop.run()`, after building the system prompt, append:
120
+
121
+ ```
122
+ You are in the {phase} phase. Do NOT introduce or transition to the next phase. The user will be offered a decision gate when this phase is complete.
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Topic 7: Select Timeout Fallback (FR-019a)
128
+
129
+ ### Decision: Minimal-context retry, then user-directed selection
130
+
131
+ ### Rationale
132
+
133
+ If context summarization (FR-016–018) doesn't prevent the Select timeout, a secondary fallback retries with only structured session fields (no conversation turns at all). If that also fails, the system presents the top-ranked idea from Design and asks the user to confirm manually.
134
+
135
+ ### Implementation
136
+
137
+ In `ConversationLoop.run()`, wrap the initial `streamResponse()` in a try/catch. On timeout:
138
+
139
+ 1. Log the timeout.
140
+ 2. Create a new session with minimal context (just structured fields from `SummarizedPhaseContext`).
141
+ 3. Retry the initial message.
142
+ 4. If retry also fails, emit a user-facing message asking for manual selection:
143
+ "The AI could not process the selection. Based on the Design phase evaluation, the top-ranked idea is [X]. Would you like to confirm this selection? (y/N)"