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,193 @@
1
+ #!/usr/bin/env bash
2
+ # ──────────────────────────────────────────────────────────────────────────────
3
+ # deploy.sh — One-command Azure AI Foundry deployment for sofIA
4
+ #
5
+ # Provisions:
6
+ # - Resource group (auto-created)
7
+ # - AI Services account with Foundry project
8
+ # - Model deployment (gpt-4.1-mini by default)
9
+ # - Agent Service capability hosts
10
+ #
11
+ # Usage:
12
+ # ./infra/deploy.sh --resource-group <name> [options]
13
+ #
14
+ # Exit codes:
15
+ # 0 — Deployment succeeded
16
+ # 1 — Prerequisite check failed
17
+ # 2 — Deployment failed
18
+ # ──────────────────────────────────────────────────────────────────────────────
19
+ set -euo pipefail
20
+
21
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
22
+
23
+ # ── Defaults ──────────────────────────────────────────────────────────────────
24
+
25
+ SUBSCRIPTION=""
26
+ RESOURCE_GROUP=""
27
+ LOCATION="swedencentral"
28
+ ACCOUNT_NAME="sofia-foundry"
29
+ MODEL="gpt-4.1-mini"
30
+
31
+ # ── Parameter parsing ─────────────────────────────────────────────────────────
32
+
33
+ usage() {
34
+ cat <<EOF
35
+ Usage: $(basename "$0") [options]
36
+
37
+ Required:
38
+ -g, --resource-group <name> Resource group name (created if missing)
39
+
40
+ Optional:
41
+ -s, --subscription <id> Azure subscription ID (default: current az CLI subscription)
42
+ -l, --location <region> Azure region (default: swedencentral)
43
+ -n, --account-name <name> Foundry account name (default: sofia-foundry)
44
+ -m, --model <name> Model deployment name (default: gpt-4.1-mini)
45
+ -h, --help Show this help message
46
+ EOF
47
+ }
48
+
49
+ while [[ $# -gt 0 ]]; do
50
+ case "$1" in
51
+ -s|--subscription)
52
+ SUBSCRIPTION="$2"; shift 2 ;;
53
+ -g|--resource-group)
54
+ RESOURCE_GROUP="$2"; shift 2 ;;
55
+ -l|--location)
56
+ LOCATION="$2"; shift 2 ;;
57
+ -n|--account-name)
58
+ ACCOUNT_NAME="$2"; shift 2 ;;
59
+ -m|--model)
60
+ MODEL="$2"; shift 2 ;;
61
+ -h|--help)
62
+ usage; exit 0 ;;
63
+ *)
64
+ echo "❌ Unknown option: $1" >&2
65
+ usage >&2
66
+ exit 1 ;;
67
+ esac
68
+ done
69
+
70
+ # ── Validate required parameters ─────────────────────────────────────────────
71
+
72
+ if [[ -z "$RESOURCE_GROUP" ]]; then
73
+ echo "❌ Missing required parameter: --resource-group (-g)" >&2
74
+ usage >&2
75
+ exit 1
76
+ fi
77
+
78
+ # ── Prerequisite checks ──────────────────────────────────────────────────────
79
+
80
+ echo "🔍 Checking prerequisites..."
81
+
82
+ # Check az CLI is installed
83
+ if ! command -v az &>/dev/null; then
84
+ echo "❌ Azure CLI (az) is not installed." >&2
85
+ echo " Install: https://learn.microsoft.com/en-us/cli/azure/install-azure-cli" >&2
86
+ exit 1
87
+ fi
88
+
89
+ # Check user is logged in
90
+ if ! az account show &>/dev/null; then
91
+ echo "❌ Not logged in to Azure. Run 'az login' first." >&2
92
+ exit 1
93
+ fi
94
+
95
+ # Optionally set subscription
96
+ if [[ -n "$SUBSCRIPTION" ]]; then
97
+ echo "📋 Setting subscription to: $SUBSCRIPTION"
98
+ if ! az account set --subscription "$SUBSCRIPTION" 2>/dev/null; then
99
+ echo "❌ Could not set subscription '$SUBSCRIPTION'." >&2
100
+ echo " Check the subscription ID and your permissions." >&2
101
+ exit 1
102
+ fi
103
+ fi
104
+
105
+ echo "✅ Prerequisites passed"
106
+
107
+ # ── Resolve current user's principal (object) ID for RBAC ─────────────────────
108
+
109
+ echo "🔑 Resolving current user's principal ID..."
110
+ USER_PRINCIPAL_ID=$(az ad signed-in-user show --query id -o tsv 2>/dev/null || true)
111
+ if [[ -z "$USER_PRINCIPAL_ID" ]]; then
112
+ echo "⚠️ Could not resolve user principal ID. Role assignment will be skipped." >&2
113
+ echo " You may need to manually assign the 'Azure AI Developer' role." >&2
114
+ else
115
+ echo " Principal ID: $USER_PRINCIPAL_ID"
116
+ fi
117
+
118
+ # ── Deploy ────────────────────────────────────────────────────────────────────
119
+
120
+ echo ""
121
+ echo "🚀 Deploying Azure AI Foundry infrastructure..."
122
+ echo " Resource Group: $RESOURCE_GROUP"
123
+ echo " Location: $LOCATION"
124
+ echo " Account: $ACCOUNT_NAME"
125
+ echo " Model: $MODEL"
126
+ echo ""
127
+
128
+ DEPLOYMENT_NAME="sofia-foundry-$(date +%Y%m%d%H%M%S)"
129
+
130
+ if ! az deployment sub create \
131
+ --location "$LOCATION" \
132
+ --name "$DEPLOYMENT_NAME" \
133
+ --template-file "$SCRIPT_DIR/main.bicep" \
134
+ --parameters "$SCRIPT_DIR/main.bicepparam" \
135
+ --parameters \
136
+ resourceGroupName="$RESOURCE_GROUP" \
137
+ location="$LOCATION" \
138
+ accountName="$ACCOUNT_NAME" \
139
+ modelDeploymentName="$MODEL" \
140
+ modelName="$MODEL" \
141
+ userPrincipalId="$USER_PRINCIPAL_ID" \
142
+ --output json; then
143
+ echo "" >&2
144
+ echo "❌ Deployment failed." >&2
145
+ echo " Check the error above for details." >&2
146
+ echo " Common issues:" >&2
147
+ echo " - Insufficient permissions (need Owner or Contributor)" >&2
148
+ echo " - Region doesn't support AI Foundry Agent Service" >&2
149
+ echo " - Resource name conflict (try a different --account-name)" >&2
150
+ exit 2
151
+ fi
152
+
153
+ # ── Query outputs ─────────────────────────────────────────────────────────────
154
+
155
+ PROJECT_ENDPOINT=$(az deployment sub show \
156
+ --name "$DEPLOYMENT_NAME" \
157
+ --query "properties.outputs.projectEndpoint.value" \
158
+ --output tsv 2>/dev/null || echo "")
159
+
160
+ MODEL_DEPLOYMENT_NAME=$(az deployment sub show \
161
+ --name "$DEPLOYMENT_NAME" \
162
+ --query "properties.outputs.modelDeploymentName.value" \
163
+ --output tsv 2>/dev/null || echo "$MODEL")
164
+
165
+ # ── Write .env file ───────────────────────────────────────────────────────────
166
+
167
+ ENV_FILE="$SCRIPT_DIR/../.env"
168
+
169
+ # Helper: set or update a KEY=VALUE in the .env file
170
+ set_env_var() {
171
+ local key="$1" value="$2"
172
+ if [[ -f "$ENV_FILE" ]] && grep -q "^${key}=" "$ENV_FILE"; then
173
+ # Update existing entry (portable sed -i)
174
+ sed -i "s|^${key}=.*|${key}=\"${value}\"|" "$ENV_FILE"
175
+ else
176
+ echo "${key}=\"${value}\"" >> "$ENV_FILE"
177
+ fi
178
+ }
179
+
180
+ set_env_var "FOUNDRY_PROJECT_ENDPOINT" "$PROJECT_ENDPOINT"
181
+ set_env_var "FOUNDRY_MODEL_DEPLOYMENT_NAME" "$MODEL_DEPLOYMENT_NAME"
182
+
183
+ # ── Output ────────────────────────────────────────────────────────────────────
184
+
185
+ echo ""
186
+ echo "✅ Deployment complete!"
187
+ echo ""
188
+ echo "Environment variables written to $(realpath "$ENV_FILE"):"
189
+ echo ""
190
+ echo " FOUNDRY_PROJECT_ENDPOINT=\"$PROJECT_ENDPOINT\""
191
+ echo " FOUNDRY_MODEL_DEPLOYMENT_NAME=\"$MODEL_DEPLOYMENT_NAME\""
192
+ echo ""
193
+ echo "To tear down: ./infra/teardown.sh --resource-group $RESOURCE_GROUP"
@@ -0,0 +1,211 @@
1
+ #!/usr/bin/env bash
2
+ # ──────────────────────────────────────────────────────────────────────────────
3
+ # gather-env.sh — Fetch environment values from an existing Azure AI Foundry
4
+ # resource group without redeploying.
5
+ #
6
+ # Queries the AI Services account and project already provisioned by deploy.sh,
7
+ # then writes (or updates) the .env file with the same variables.
8
+ #
9
+ # Usage:
10
+ # ./infra/gather-env.sh --resource-group <name> [options]
11
+ #
12
+ # Exit codes:
13
+ # 0 — Values gathered and written successfully
14
+ # 1 — Prerequisite / parameter check failed
15
+ # 2 — Resource query failed
16
+ # ──────────────────────────────────────────────────────────────────────────────
17
+ set -euo pipefail
18
+
19
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
20
+
21
+ # ── Defaults ──────────────────────────────────────────────────────────────────
22
+
23
+ SUBSCRIPTION=""
24
+ RESOURCE_GROUP=""
25
+ ACCOUNT_NAME="sofia-foundry"
26
+ MODEL=""
27
+
28
+ # ── Parameter parsing ─────────────────────────────────────────────────────────
29
+
30
+ usage() {
31
+ cat <<EOF
32
+ Usage: $(basename "$0") [options]
33
+
34
+ Required:
35
+ -g, --resource-group <name> Resource group containing the Foundry resources
36
+
37
+ Optional:
38
+ -s, --subscription <id> Azure subscription ID (default: current az CLI subscription)
39
+ -n, --account-name <name> AI Services account name (default: sofia-foundry)
40
+ -m, --model <name> Override model deployment name (default: auto-detected)
41
+ -h, --help Show this help message
42
+ EOF
43
+ }
44
+
45
+ while [[ $# -gt 0 ]]; do
46
+ case "$1" in
47
+ -s|--subscription)
48
+ SUBSCRIPTION="$2"; shift 2 ;;
49
+ -g|--resource-group)
50
+ RESOURCE_GROUP="$2"; shift 2 ;;
51
+ -n|--account-name)
52
+ ACCOUNT_NAME="$2"; shift 2 ;;
53
+ -m|--model)
54
+ MODEL="$2"; shift 2 ;;
55
+ -h|--help)
56
+ usage; exit 0 ;;
57
+ *)
58
+ echo "❌ Unknown option: $1" >&2
59
+ usage >&2
60
+ exit 1 ;;
61
+ esac
62
+ done
63
+
64
+ # ── Validate required parameters ─────────────────────────────────────────────
65
+
66
+ if [[ -z "$RESOURCE_GROUP" ]]; then
67
+ echo "❌ Missing required parameter: --resource-group (-g)" >&2
68
+ usage >&2
69
+ exit 1
70
+ fi
71
+
72
+ # ── Prerequisite checks ──────────────────────────────────────────────────────
73
+
74
+ echo "🔍 Checking prerequisites..."
75
+
76
+ if ! command -v az &>/dev/null; then
77
+ echo "❌ Azure CLI (az) is not installed." >&2
78
+ echo " Install: https://learn.microsoft.com/en-us/cli/azure/install-azure-cli" >&2
79
+ exit 1
80
+ fi
81
+
82
+ if ! az account show &>/dev/null; then
83
+ echo "❌ Not logged in to Azure. Run 'az login' first." >&2
84
+ exit 1
85
+ fi
86
+
87
+ if [[ -n "$SUBSCRIPTION" ]]; then
88
+ echo "📋 Setting subscription to: $SUBSCRIPTION"
89
+ if ! az account set --subscription "$SUBSCRIPTION" 2>/dev/null; then
90
+ echo "❌ Could not set subscription '$SUBSCRIPTION'." >&2
91
+ exit 1
92
+ fi
93
+ fi
94
+
95
+ echo "✅ Prerequisites passed"
96
+
97
+ # ── Verify resource group exists ──────────────────────────────────────────────
98
+
99
+ echo ""
100
+ echo "🔍 Verifying resource group: $RESOURCE_GROUP"
101
+
102
+ if ! az group show --name "$RESOURCE_GROUP" &>/dev/null; then
103
+ echo "❌ Resource group '$RESOURCE_GROUP' not found." >&2
104
+ echo " Run deploy.sh first to create the infrastructure." >&2
105
+ exit 2
106
+ fi
107
+
108
+ # ── Find the AI Services account ─────────────────────────────────────────────
109
+
110
+ echo "🔍 Looking up AI Services account: $ACCOUNT_NAME"
111
+
112
+ if ! az cognitiveservices account show \
113
+ --resource-group "$RESOURCE_GROUP" \
114
+ --name "$ACCOUNT_NAME" &>/dev/null; then
115
+ echo "⚠️ Account '$ACCOUNT_NAME' not found. Searching for AI Services accounts in the resource group..."
116
+ ACCOUNT_NAME=$(az cognitiveservices account list \
117
+ --resource-group "$RESOURCE_GROUP" \
118
+ --query "[?kind=='AIServices'].name | [0]" \
119
+ --output tsv 2>/dev/null || true)
120
+
121
+ if [[ -z "$ACCOUNT_NAME" ]]; then
122
+ echo "❌ No AI Services account found in resource group '$RESOURCE_GROUP'." >&2
123
+ exit 2
124
+ fi
125
+ echo " Found account: $ACCOUNT_NAME"
126
+ fi
127
+
128
+ # ── Find the project and its endpoint ────────────────────────────────────────
129
+
130
+ echo "🔍 Looking up Foundry project..."
131
+
132
+ PROJECT_ENDPOINT=$(az cognitiveservices account show \
133
+ --resource-group "$RESOURCE_GROUP" \
134
+ --name "$ACCOUNT_NAME" \
135
+ --query "properties.endpoints.\"AI Foundry API\"" \
136
+ --output tsv 2>/dev/null || true)
137
+
138
+ # If the account-level endpoint isn't what we need, try querying the project
139
+ if [[ -z "$PROJECT_ENDPOINT" ]]; then
140
+ # List projects under the account
141
+ PROJECT_NAME=$(az resource list \
142
+ --resource-group "$RESOURCE_GROUP" \
143
+ --resource-type "Microsoft.CognitiveServices/accounts/projects" \
144
+ --query "[0].name" \
145
+ --output tsv 2>/dev/null || true)
146
+
147
+ if [[ -n "$PROJECT_NAME" ]]; then
148
+ # The resource name is "account/project", extract just the project part
149
+ LOCAL_PROJECT="${PROJECT_NAME##*/}"
150
+ echo " Found project: $LOCAL_PROJECT"
151
+
152
+ PROJECT_ENDPOINT=$(az rest \
153
+ --method GET \
154
+ --uri "https://management.azure.com/subscriptions/$(az account show --query id -o tsv)/resourceGroups/$RESOURCE_GROUP/providers/Microsoft.CognitiveServices/accounts/$ACCOUNT_NAME/projects/$LOCAL_PROJECT?api-version=2025-06-01" \
155
+ --query "properties.endpoints.\"AI Foundry API\"" \
156
+ --output tsv 2>/dev/null || true)
157
+ fi
158
+ fi
159
+
160
+ if [[ -z "$PROJECT_ENDPOINT" ]]; then
161
+ echo "❌ Could not determine the Foundry project endpoint." >&2
162
+ echo " Ensure a project exists under account '$ACCOUNT_NAME'." >&2
163
+ exit 2
164
+ fi
165
+
166
+ echo " Endpoint: $PROJECT_ENDPOINT"
167
+
168
+ # ── Find the model deployment name ───────────────────────────────────────────
169
+
170
+ if [[ -z "$MODEL" ]]; then
171
+ echo "🔍 Looking up model deployment..."
172
+ MODEL=$(az cognitiveservices account deployment list \
173
+ --resource-group "$RESOURCE_GROUP" \
174
+ --name "$ACCOUNT_NAME" \
175
+ --query "[0].name" \
176
+ --output tsv 2>/dev/null || true)
177
+
178
+ if [[ -z "$MODEL" ]]; then
179
+ echo "⚠️ No model deployment found. Using default: gpt-4.1-mini"
180
+ MODEL="gpt-4.1-mini"
181
+ fi
182
+ fi
183
+
184
+ echo " Model deployment: $MODEL"
185
+
186
+ # ── Write .env file ───────────────────────────────────────────────────────────
187
+
188
+ ENV_FILE="$SCRIPT_DIR/../.env"
189
+
190
+ set_env_var() {
191
+ local key="$1" value="$2"
192
+ if [[ -f "$ENV_FILE" ]] && grep -q "^${key}=" "$ENV_FILE"; then
193
+ sed -i "s|^${key}=.*|${key}=\"${value}\"|" "$ENV_FILE"
194
+ else
195
+ echo "${key}=\"${value}\"" >> "$ENV_FILE"
196
+ fi
197
+ }
198
+
199
+ set_env_var "FOUNDRY_PROJECT_ENDPOINT" "$PROJECT_ENDPOINT"
200
+ set_env_var "FOUNDRY_MODEL_DEPLOYMENT_NAME" "$MODEL"
201
+
202
+ # ── Output ────────────────────────────────────────────────────────────────────
203
+
204
+ echo ""
205
+ echo "✅ Environment values gathered successfully!"
206
+ echo ""
207
+ echo "Written to $(realpath "$ENV_FILE"):"
208
+ echo ""
209
+ echo " FOUNDRY_PROJECT_ENDPOINT=\"$PROJECT_ENDPOINT\""
210
+ echo " FOUNDRY_MODEL_DEPLOYMENT_NAME=\"$MODEL\""
211
+ echo ""
@@ -0,0 +1,90 @@
1
+ // ──────────────────────────────────────────────────────────────────────────────
2
+ // Azure AI Foundry — Basic Agent Setup with Web Search
3
+ //
4
+ // Provisions:
5
+ // 1. Resource Group (auto-created)
6
+ // 2. AI Services account (Foundry) with project management enabled
7
+ // 3. Model deployment (default: gpt-4.1-mini, GlobalStandard SKU)
8
+ // 4. Foundry project (provides the endpoint URL)
9
+ // 5. Account-level capability host (Agents)
10
+ // 6. Project-level capability host (Agents, basic/Microsoft-managed)
11
+ //
12
+ // Usage:
13
+ // az deployment sub create --location <region> --template-file main.bicep \
14
+ // --parameters main.bicepparam
15
+ //
16
+ // See: specs/005-ai-search-deploy/research.md (R1, R2)
17
+ // ──────────────────────────────────────────────────────────────────────────────
18
+
19
+ targetScope = 'subscription'
20
+
21
+ // ── Parameters ───────────────────────────────────────────────────────────────
22
+
23
+ @description('Azure region for all resources. Must support Azure AI Foundry Agent Service.')
24
+ param location string = 'swedencentral'
25
+
26
+ @description('Name of the resource group to create or use.')
27
+ param resourceGroupName string
28
+
29
+ @description('Name of the Azure AI Services (Foundry) account. Used to derive the custom subdomain.')
30
+ param accountName string = 'sofia-foundry'
31
+
32
+ @description('Name of the Foundry project. Provides the endpoint URL for the sofIA CLI.')
33
+ param projectName string = 'sofia-project'
34
+
35
+ @description('Name of the model deployment. Used as FOUNDRY_MODEL_DEPLOYMENT_NAME env var.')
36
+ param modelDeploymentName string = 'gpt-4.1-mini'
37
+
38
+ @description('Model name to deploy. Must support web_search_preview tool type.')
39
+ param modelName string = 'gpt-4.1-mini'
40
+
41
+ @description('Model version to deploy. Pinned for reproducibility.')
42
+ param modelVersion string = '2025-04-14'
43
+
44
+ @description('SKU name for the model deployment. GlobalStandard provides broadest region availability.')
45
+ param modelSkuName string = 'GlobalStandard'
46
+
47
+ @description('SKU capacity (TPM in thousands). Default value=5000.')
48
+ param modelSkuCapacity int = 5000
49
+
50
+ @description('Object ID of the user principal to grant Azure AI Developer access. Obtain with: az ad signed-in-user show --query id -o tsv')
51
+ param userPrincipalId string
52
+
53
+ // ── Unique suffix for globally unique names ──────────────────────────────────
54
+
55
+ var uniqueSuffix = uniqueString(subscription().subscriptionId, resourceGroupName)
56
+
57
+ // ── Resource Group ───────────────────────────────────────────────────────────
58
+
59
+ // Auto-create the resource group if it doesn't exist (FR-002)
60
+ resource rg 'Microsoft.Resources/resourceGroups@2024-03-01' = {
61
+ name: resourceGroupName
62
+ location: location
63
+ }
64
+
65
+ // ── Module: all resources deployed into the resource group ───────────────────
66
+
67
+ module resources 'resources.bicep' = {
68
+ name: 'foundry-resources'
69
+ scope: rg
70
+ params: {
71
+ location: location
72
+ accountName: accountName
73
+ projectName: projectName
74
+ modelDeploymentName: modelDeploymentName
75
+ modelName: modelName
76
+ modelVersion: modelVersion
77
+ modelSkuName: modelSkuName
78
+ modelSkuCapacity: modelSkuCapacity
79
+ uniqueSuffix: uniqueSuffix
80
+ userPrincipalId: userPrincipalId
81
+ }
82
+ }
83
+
84
+ // ── Outputs ──────────────────────────────────────────────────────────────────
85
+
86
+ @description('Foundry project endpoint URL — set as FOUNDRY_PROJECT_ENDPOINT')
87
+ output projectEndpoint string = resources.outputs.projectEndpoint
88
+
89
+ @description('Model deployment name — set as FOUNDRY_MODEL_DEPLOYMENT_NAME')
90
+ output modelDeploymentName string = modelDeploymentName
@@ -0,0 +1,18 @@
1
+ using 'main.bicep'
2
+
3
+ // ── Default parameters for workshop/PoC deployment ───────────────────────────
4
+ // Override at deploy time via:
5
+ // az deployment sub create --parameters resourceGroupName='my-rg' location='eastus'
6
+
7
+ param resourceGroupName = 'sofia-rg'
8
+ param location = 'swedencentral'
9
+ param accountName = 'sofia-foundry'
10
+ param projectName = 'sofia-project'
11
+ param modelDeploymentName = 'gpt-4.1-mini'
12
+ param modelName = 'gpt-4.1-mini'
13
+ param modelVersion = '2025-04-14'
14
+ param modelSkuName = 'GlobalStandard'
15
+ param modelSkuCapacity = 1
16
+
17
+ // Resolved at deploy time by deploy.sh via: az ad signed-in-user show --query id -o tsv
18
+ param userPrincipalId = ''
@@ -0,0 +1,134 @@
1
+ // ──────────────────────────────────────────────────────────────────────────────
2
+ // Resource-group-scoped resources for Azure AI Foundry
3
+ //
4
+ // Deployed as a module from main.bicep (subscription-scoped).
5
+ // ──────────────────────────────────────────────────────────────────────────────
6
+
7
+ // ── Parameters (passed from main.bicep) ──────────────────────────────────────
8
+
9
+ param location string
10
+ param accountName string
11
+ param projectName string
12
+ param modelDeploymentName string
13
+ param modelName string
14
+ param modelVersion string
15
+ param modelSkuName string
16
+ param modelSkuCapacity int
17
+ param uniqueSuffix string
18
+
19
+ @description('Object ID of the user principal to grant Azure AI Developer access. Obtain with: az ad signed-in-user show --query id -o tsv')
20
+ param userPrincipalId string
21
+
22
+ // ── Derived values ───────────────────────────────────────────────────────────
23
+
24
+ var customSubDomainName = '${accountName}-${uniqueSuffix}'
25
+
26
+ // Azure AI Developer — allows creating/managing agents and using models
27
+ // https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#azure-ai-developer
28
+ var azureAIDeveloperRoleId = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '64702f94-c441-49e6-a78b-ef80e0188fee')
29
+
30
+ // ── Resource 1: AI Services Account (Foundry) ────────────────────────────────
31
+ // Top-level Foundry account with project management enabled.
32
+ // kind: AIServices provides access to Foundry Agent Service capabilities.
33
+
34
+ resource aiAccount 'Microsoft.CognitiveServices/accounts@2025-06-01' = {
35
+ name: accountName
36
+ location: location
37
+ kind: 'AIServices'
38
+ identity: {
39
+ type: 'SystemAssigned'
40
+ }
41
+ sku: {
42
+ name: 'S0'
43
+ }
44
+ properties: {
45
+ customSubDomainName: customSubDomainName
46
+ allowProjectManagement: true
47
+ publicNetworkAccess: 'Enabled'
48
+ }
49
+ }
50
+
51
+ // ── Resource 2: Model Deployment ─────────────────────────────────────────────
52
+ // Deploys the language model that will process web search queries.
53
+ // Default: gpt-4.1-mini with GlobalStandard SKU for broadest availability.
54
+
55
+ resource modelDeploy 'Microsoft.CognitiveServices/accounts/deployments@2025-06-01' = {
56
+ parent: aiAccount
57
+ name: modelDeploymentName
58
+ sku: {
59
+ name: modelSkuName
60
+ capacity: modelSkuCapacity
61
+ }
62
+ properties: {
63
+ model: {
64
+ format: 'OpenAI'
65
+ name: modelName
66
+ version: modelVersion
67
+ }
68
+ }
69
+ }
70
+
71
+ // ── Resource 3: Foundry Project ──────────────────────────────────────────────
72
+ // Provides the endpoint URL used by the sofIA CLI (FOUNDRY_PROJECT_ENDPOINT).
73
+
74
+ resource project 'Microsoft.CognitiveServices/accounts/projects@2025-06-01' = {
75
+ parent: aiAccount
76
+ name: projectName
77
+ location: location
78
+ identity: {
79
+ type: 'SystemAssigned'
80
+ }
81
+ properties: {}
82
+ dependsOn: [
83
+ modelDeploy
84
+ ]
85
+ }
86
+
87
+ // ── Resource 4: Account Capability Host (Agents) ─────────────────────────────
88
+ // Enables the Agent Service at the account level.
89
+ // Must be created before the project capability host.
90
+
91
+ resource accountCapabilityHost 'Microsoft.CognitiveServices/accounts/capabilityHosts@2025-06-01' = {
92
+ parent: aiAccount
93
+ name: 'default'
94
+ properties: {
95
+ capabilityHostKind: 'Agents'
96
+ }
97
+ dependsOn: [
98
+ project
99
+ modelDeploy
100
+ ]
101
+ }
102
+
103
+ // ── Resource 5: Project Capability Host (Agents) ─────────────────────────────
104
+ // Enables the Agent Service at the project level.
105
+ // Basic (Microsoft-managed) setup — empty connections array.
106
+
107
+ resource projectCapabilityHost 'Microsoft.CognitiveServices/accounts/projects/capabilityHosts@2025-06-01' = {
108
+ parent: project
109
+ name: 'default'
110
+ properties: {
111
+ capabilityHostKind: 'Agents'
112
+ }
113
+ dependsOn: [
114
+ accountCapabilityHost
115
+ ]
116
+ }
117
+
118
+ // ── Resource 6: Role Assignment — Azure AI Developer for the deploying user ──
119
+ // Grants the deploying user permission to create ephemeral agents, use models,
120
+ // and invoke web_search_preview through the Foundry Agent Service.
121
+
122
+ resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
123
+ name: guid(aiAccount.id, userPrincipalId, azureAIDeveloperRoleId)
124
+ scope: aiAccount
125
+ properties: {
126
+ principalId: userPrincipalId
127
+ roleDefinitionId: azureAIDeveloperRoleId
128
+ principalType: 'User'
129
+ }
130
+ }
131
+
132
+ // ── Outputs ──────────────────────────────────────────────────────────────────
133
+
134
+ output projectEndpoint string = project.properties.endpoints['AI Foundry API']