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.
- package/.github/agents/copilot-instructions.md +39 -0
- package/.github/agents/speckit.analyze.agent.md +184 -0
- package/.github/agents/speckit.checklist.agent.md +294 -0
- package/.github/agents/speckit.clarify.agent.md +181 -0
- package/.github/agents/speckit.constitution.agent.md +84 -0
- package/.github/agents/speckit.implement.agent.md +135 -0
- package/.github/agents/speckit.plan.agent.md +90 -0
- package/.github/agents/speckit.specify.agent.md +258 -0
- package/.github/agents/speckit.tasks.agent.md +137 -0
- package/.github/agents/speckit.taskstoissues.agent.md +30 -0
- package/.github/copilot-instructions.md +257 -0
- package/.github/prompts/speckit.analyze.prompt.md +3 -0
- package/.github/prompts/speckit.checklist.prompt.md +3 -0
- package/.github/prompts/speckit.clarify.prompt.md +3 -0
- package/.github/prompts/speckit.constitution.prompt.md +3 -0
- package/.github/prompts/speckit.implement.prompt.md +3 -0
- package/.github/prompts/speckit.plan.prompt.md +3 -0
- package/.github/prompts/speckit.specify.prompt.md +3 -0
- package/.github/prompts/speckit.tasks.prompt.md +3 -0
- package/.github/prompts/speckit.taskstoissues.prompt.md +3 -0
- package/.github/workflows/ci.yml +38 -0
- package/.prettierrc +6 -0
- package/.specify/memory/constitution.md +181 -0
- package/.specify/scripts/bash/check-prerequisites.sh +166 -0
- package/.specify/scripts/bash/common.sh +156 -0
- package/.specify/scripts/bash/create-new-feature.sh +297 -0
- package/.specify/scripts/bash/setup-plan.sh +61 -0
- package/.specify/scripts/bash/update-agent-context.sh +810 -0
- package/.specify/templates/agent-file-template.md +28 -0
- package/.specify/templates/checklist-template.md +40 -0
- package/.specify/templates/constitution-template.md +50 -0
- package/.specify/templates/plan-template.md +113 -0
- package/.specify/templates/spec-template.md +115 -0
- package/.specify/templates/tasks-template.md +251 -0
- package/.vscode/mcp.json +42 -0
- package/.vscode/settings.json +19 -0
- package/CODE_OF_CONDUCT.md +128 -0
- package/LICENSE +21 -0
- package/README.md +213 -0
- package/dist/src/cli/developCommand.js +240 -0
- package/dist/src/cli/directCommands.js +143 -0
- package/dist/src/cli/envLoader.js +16 -0
- package/dist/src/cli/exportCommand.js +53 -0
- package/dist/src/cli/index.js +203 -0
- package/dist/src/cli/ioContext.js +109 -0
- package/dist/src/cli/preflight.js +57 -0
- package/dist/src/cli/statusCommand.js +110 -0
- package/dist/src/cli/workshopCommand.js +400 -0
- package/dist/src/develop/checkpointState.js +86 -0
- package/dist/src/develop/codeGenerator.js +319 -0
- package/dist/src/develop/dynamicScaffolder.js +226 -0
- package/dist/src/develop/githubMcpAdapter.js +122 -0
- package/dist/src/develop/index.js +15 -0
- package/dist/src/develop/mcpContextEnricher.js +195 -0
- package/dist/src/develop/pocScaffolder.js +542 -0
- package/dist/src/develop/ralphLoop.js +659 -0
- package/dist/src/develop/templateRegistry.js +364 -0
- package/dist/src/develop/testRunner.js +202 -0
- package/dist/src/logging/logger.js +58 -0
- package/dist/src/loop/conversationLoop.js +227 -0
- package/dist/src/loop/phaseSummarizer.js +87 -0
- package/dist/src/mcp/mcpManager.js +267 -0
- package/dist/src/mcp/mcpTransport.js +391 -0
- package/dist/src/mcp/retryPolicy.js +47 -0
- package/dist/src/mcp/webSearch.js +254 -0
- package/dist/src/phases/contextSummarizer.js +101 -0
- package/dist/src/phases/discoveryEnricher.js +156 -0
- package/dist/src/phases/phaseExtractors.js +222 -0
- package/dist/src/phases/phaseHandlers.js +328 -0
- package/dist/src/prompts/design.md +51 -0
- package/dist/src/prompts/develop-boundary.md +51 -0
- package/dist/src/prompts/develop.md +111 -0
- package/dist/src/prompts/discover.md +58 -0
- package/dist/src/prompts/ideate.md +56 -0
- package/dist/src/prompts/plan.md +51 -0
- package/dist/src/prompts/promptLoader.js +167 -0
- package/dist/src/prompts/promptLoader.ts +198 -0
- package/dist/src/prompts/select.md +47 -0
- package/dist/src/prompts/summarize/README.md +8 -0
- package/dist/src/prompts/summarize/design-summary.md +37 -0
- package/dist/src/prompts/summarize/develop-summary.md +25 -0
- package/dist/src/prompts/summarize/ideate-summary.md +27 -0
- package/dist/src/prompts/summarize/plan-summary.md +27 -0
- package/dist/src/prompts/summarize/select-summary.md +21 -0
- package/dist/src/prompts/system.md +28 -0
- package/dist/src/sessions/exportPaths.js +22 -0
- package/dist/src/sessions/exportWriter.js +406 -0
- package/dist/src/sessions/sessionManager.js +81 -0
- package/dist/src/sessions/sessionStore.js +65 -0
- package/dist/src/shared/activitySpinner.js +91 -0
- package/dist/src/shared/copilotClient.js +129 -0
- package/dist/src/shared/data/cards.json +1249 -0
- package/dist/src/shared/data/cardsLoader.js +51 -0
- package/dist/src/shared/errorClassifier.js +120 -0
- package/dist/src/shared/events.js +28 -0
- package/dist/src/shared/markdownRenderer.js +34 -0
- package/dist/src/shared/schemas/session.js +265 -0
- package/dist/src/shared/tableRenderer.js +20 -0
- package/dist/src/vendor/chalk.js +2 -0
- package/dist/src/vendor/cli-table3.js +3 -0
- package/dist/src/vendor/commander.js +2 -0
- package/dist/src/vendor/marked-terminal.js +3 -0
- package/dist/src/vendor/marked.js +2 -0
- package/dist/src/vendor/ora.js +2 -0
- package/dist/src/vendor/pino.js +2 -0
- package/dist/src/vendor/zod.js +2 -0
- package/dist/tests/e2e/developE2e.spec.js +126 -0
- package/dist/tests/e2e/developFailureE2e.spec.js +247 -0
- package/dist/tests/e2e/developPty.spec.js +75 -0
- package/dist/tests/e2e/discoveryWebSearchRelevance.spec.js +84 -0
- package/dist/tests/e2e/harness.spec.js +83 -0
- package/dist/tests/e2e/mcpLive.spec.js +120 -0
- package/dist/tests/e2e/newSession.e2e.spec.js +177 -0
- package/dist/tests/e2e/ralphLoopEnrichmentComparison.spec.js +62 -0
- package/dist/tests/e2e/workiqEnrichment.spec.js +56 -0
- package/dist/tests/e2e/zavaSimulation.spec.js +452 -0
- package/dist/tests/fixtures/test-fixture-project/src/add.js +3 -0
- package/dist/tests/fixtures/test-fixture-project/tests/failing.test.js +6 -0
- package/dist/tests/fixtures/test-fixture-project/tests/hanging.test.js +8 -0
- package/dist/tests/fixtures/test-fixture-project/tests/passing.test.js +10 -0
- package/dist/tests/fixtures/test-fixture-project/vitest.config.js +6 -0
- package/dist/tests/integration/autoStartConversation.spec.js +138 -0
- package/dist/tests/integration/defaultCommand.spec.js +147 -0
- package/dist/tests/integration/directCommandNonTty.spec.js +224 -0
- package/dist/tests/integration/directCommandTty.spec.js +151 -0
- package/dist/tests/integration/discoveryEnrichmentFlow.spec.js +175 -0
- package/dist/tests/integration/exportArtifacts.spec.js +202 -0
- package/dist/tests/integration/exportFallbackFlow.spec.js +99 -0
- package/dist/tests/integration/mcpDegradationFlow.spec.js +190 -0
- package/dist/tests/integration/mcpTransportFlow.spec.js +139 -0
- package/dist/tests/integration/newSessionFlow.spec.js +343 -0
- package/dist/tests/integration/pocGithubMcp.spec.js +186 -0
- package/dist/tests/integration/pocLocalFallback.spec.js +171 -0
- package/dist/tests/integration/pocScaffold.spec.js +163 -0
- package/dist/tests/integration/ralphLoopFlow.spec.js +359 -0
- package/dist/tests/integration/ralphLoopPartial.spec.js +368 -0
- package/dist/tests/integration/resumeAndBacktrack.spec.js +247 -0
- package/dist/tests/integration/spinnerLifecycle.spec.js +220 -0
- package/dist/tests/integration/summarizationFlow.spec.js +115 -0
- package/dist/tests/integration/testRunnerReal.spec.js +52 -0
- package/dist/tests/integration/webSearchAgent.spec.js +128 -0
- package/dist/tests/live/copilotSdkLive.spec.js +107 -0
- package/dist/tests/live/zavaFullWorkshop.spec.js +392 -0
- package/dist/tests/setup/loadEnv.js +3 -0
- package/dist/tests/unit/cli/developCommand.spec.js +567 -0
- package/dist/tests/unit/cli/directCommands.spec.js +279 -0
- package/dist/tests/unit/cli/envLoader.spec.js +58 -0
- package/dist/tests/unit/cli/ioContext.spec.js +119 -0
- package/dist/tests/unit/cli/preflight.spec.js +108 -0
- package/dist/tests/unit/cli/statusCommand.spec.js +111 -0
- package/dist/tests/unit/cli/workshopClientFallback.spec.js +80 -0
- package/dist/tests/unit/cli/workshopCommand.spec.js +329 -0
- package/dist/tests/unit/config/vitestEnvSetup.spec.js +13 -0
- package/dist/tests/unit/develop/checkpointState.spec.js +315 -0
- package/dist/tests/unit/develop/codeGenerator.spec.js +355 -0
- package/dist/tests/unit/develop/githubMcpAdapter.spec.js +231 -0
- package/dist/tests/unit/develop/mcpContextEnricher.spec.js +433 -0
- package/dist/tests/unit/develop/outputValidator.spec.js +119 -0
- package/dist/tests/unit/develop/pocScaffolder.spec.js +353 -0
- package/dist/tests/unit/develop/ralphLoop.spec.js +1248 -0
- package/dist/tests/unit/develop/templateRegistry.spec.js +85 -0
- package/dist/tests/unit/develop/testRunner.spec.js +249 -0
- package/dist/tests/unit/infraBicep.spec.js +92 -0
- package/dist/tests/unit/infraDeploy.spec.js +82 -0
- package/dist/tests/unit/infraTeardown.spec.js +63 -0
- package/dist/tests/unit/logging/logger.spec.js +43 -0
- package/dist/tests/unit/loop/conversationLoop.spec.js +592 -0
- package/dist/tests/unit/loop/phaseSummarizer.spec.js +141 -0
- package/dist/tests/unit/loop/streamingMarkdown.spec.js +147 -0
- package/dist/tests/unit/mcp/mcpManager.spec.js +279 -0
- package/dist/tests/unit/mcp/mcpTransport.spec.js +529 -0
- package/dist/tests/unit/mcp/retryPolicy.spec.js +218 -0
- package/dist/tests/unit/mcp/timeoutValidation.spec.js +46 -0
- package/dist/tests/unit/mcp/webSearch.spec.js +567 -0
- package/dist/tests/unit/phases/contextSummarizer.spec.js +140 -0
- package/dist/tests/unit/phases/discoveryEnricher.repeatCalls.spec.js +93 -0
- package/dist/tests/unit/phases/discoveryEnricher.spec.js +411 -0
- package/dist/tests/unit/phases/phaseExtractors.spec.js +352 -0
- package/dist/tests/unit/phases/phaseHandlers.spec.js +425 -0
- package/dist/tests/unit/prompts/promptLoader.spec.js +118 -0
- package/dist/tests/unit/schemas/pocSchemas.spec.js +412 -0
- package/dist/tests/unit/schemas/session.spec.js +257 -0
- package/dist/tests/unit/sessions/exportPaths.spec.js +31 -0
- package/dist/tests/unit/sessions/exportWriter.spec.js +655 -0
- package/dist/tests/unit/sessions/sessionManager.spec.js +151 -0
- package/dist/tests/unit/sessions/sessionStore.spec.js +116 -0
- package/dist/tests/unit/shared/activitySpinner.spec.js +175 -0
- package/dist/tests/unit/shared/cardsLoader.spec.js +76 -0
- package/dist/tests/unit/shared/copilotClient.spec.js +155 -0
- package/dist/tests/unit/shared/errorClassifier.spec.js +131 -0
- package/dist/tests/unit/shared/events.spec.js +55 -0
- package/dist/tests/unit/shared/markdownRenderer.spec.js +35 -0
- package/dist/tests/unit/shared/markdownRendererChunks.spec.js +70 -0
- package/dist/tests/unit/shared/tableRenderer.spec.js +34 -0
- package/dist/vitest.config.js +14 -0
- package/dist/vitest.live.config.js +18 -0
- package/docs/README.md +35 -0
- package/docs/architecture.md +169 -0
- package/docs/cli-usage.md +207 -0
- package/docs/environment.md +66 -0
- package/docs/export-format.md +146 -0
- package/docs/session-model.md +113 -0
- package/eslint.config.js +35 -0
- package/infra/deploy.sh +193 -0
- package/infra/gather-env.sh +211 -0
- package/infra/main.bicep +90 -0
- package/infra/main.bicepparam +18 -0
- package/infra/resources.bicep +134 -0
- package/infra/teardown.sh +114 -0
- package/package.json +63 -0
- package/specs/001-cli-workshop-rebuild/checklists/requirements.md +35 -0
- package/specs/001-cli-workshop-rebuild/contracts/cli.md +59 -0
- package/specs/001-cli-workshop-rebuild/contracts/export-summary-json.md +23 -0
- package/specs/001-cli-workshop-rebuild/contracts/session-json.md +30 -0
- package/specs/001-cli-workshop-rebuild/data-model.md +210 -0
- package/specs/001-cli-workshop-rebuild/plan.md +361 -0
- package/specs/001-cli-workshop-rebuild/quickstart.md +83 -0
- package/specs/001-cli-workshop-rebuild/research.md +116 -0
- package/specs/001-cli-workshop-rebuild/spec.md +240 -0
- package/specs/001-cli-workshop-rebuild/tasks.md +476 -0
- package/specs/002-poc-generation/contracts/poc-output.md +172 -0
- package/specs/002-poc-generation/contracts/ralph-loop.md +113 -0
- package/specs/002-poc-generation/data-model.md +172 -0
- package/specs/002-poc-generation/plan.md +109 -0
- package/specs/002-poc-generation/quickstart.md +97 -0
- package/specs/002-poc-generation/research.md +786 -0
- package/specs/002-poc-generation/spec.md +81 -0
- package/specs/002-poc-generation/tasks-fix.md +198 -0
- package/specs/002-poc-generation/tasks.md +252 -0
- package/specs/003-mcp-transport-integration/checklists/requirements.md +37 -0
- package/specs/003-mcp-transport-integration/contracts/context-enricher.md +220 -0
- package/specs/003-mcp-transport-integration/contracts/discovery-enricher.md +267 -0
- package/specs/003-mcp-transport-integration/contracts/github-adapter.md +149 -0
- package/specs/003-mcp-transport-integration/contracts/mcp-transport.md +288 -0
- package/specs/003-mcp-transport-integration/data-model.md +326 -0
- package/specs/003-mcp-transport-integration/plan.md +114 -0
- package/specs/003-mcp-transport-integration/quickstart.md +311 -0
- package/specs/003-mcp-transport-integration/research.md +395 -0
- package/specs/003-mcp-transport-integration/spec.md +234 -0
- package/specs/003-mcp-transport-integration/tasks.md +324 -0
- package/specs/003-next-spec-gaps.md +150 -0
- package/specs/004-dev-resume-hardening/checklists/requirements.md +37 -0
- package/specs/004-dev-resume-hardening/contracts/cli.md +160 -0
- package/specs/004-dev-resume-hardening/data-model.md +321 -0
- package/specs/004-dev-resume-hardening/plan.md +107 -0
- package/specs/004-dev-resume-hardening/quickstart.md +115 -0
- package/specs/004-dev-resume-hardening/research.md +142 -0
- package/specs/004-dev-resume-hardening/spec.md +221 -0
- package/specs/004-dev-resume-hardening/tasks.md +333 -0
- package/specs/005-ai-search-deploy/checklists/requirements.md +39 -0
- package/specs/005-ai-search-deploy/contracts/web-search-tool.md +241 -0
- package/specs/005-ai-search-deploy/data-model.md +130 -0
- package/specs/005-ai-search-deploy/plan.md +93 -0
- package/specs/005-ai-search-deploy/quickstart.md +96 -0
- package/specs/005-ai-search-deploy/research.md +187 -0
- package/specs/005-ai-search-deploy/spec.md +143 -0
- package/specs/005-ai-search-deploy/tasks.md +284 -0
- package/specs/006-workshop-extraction-fixes/checklists/requirements.md +61 -0
- package/specs/006-workshop-extraction-fixes/contracts/summarization-and-export.md +131 -0
- package/specs/006-workshop-extraction-fixes/data-model.md +149 -0
- package/specs/006-workshop-extraction-fixes/plan.md +123 -0
- package/specs/006-workshop-extraction-fixes/quickstart.md +101 -0
- package/specs/006-workshop-extraction-fixes/research.md +143 -0
- package/specs/006-workshop-extraction-fixes/spec.md +210 -0
- package/specs/006-workshop-extraction-fixes/tasks.md +316 -0
- package/src/cli/developCommand.ts +308 -0
- package/src/cli/directCommands.ts +195 -0
- package/src/cli/envLoader.ts +17 -0
- package/src/cli/exportCommand.ts +65 -0
- package/src/cli/index.ts +249 -0
- package/src/cli/ioContext.ts +139 -0
- package/src/cli/preflight.ts +86 -0
- package/src/cli/statusCommand.ts +118 -0
- package/src/cli/workshopCommand.ts +496 -0
- package/src/develop/checkpointState.ts +121 -0
- package/src/develop/codeGenerator.ts +402 -0
- package/src/develop/dynamicScaffolder.ts +284 -0
- package/src/develop/githubMcpAdapter.ts +199 -0
- package/src/develop/index.ts +34 -0
- package/src/develop/mcpContextEnricher.ts +279 -0
- package/src/develop/pocScaffolder.ts +646 -0
- package/src/develop/ralphLoop.ts +1044 -0
- package/src/develop/templateRegistry.ts +427 -0
- package/src/develop/testRunner.ts +276 -0
- package/src/logging/logger.ts +73 -0
- package/src/loop/conversationLoop.ts +355 -0
- package/src/loop/phaseSummarizer.ts +114 -0
- package/src/mcp/mcpManager.ts +365 -0
- package/src/mcp/mcpTransport.ts +562 -0
- package/src/mcp/retryPolicy.ts +87 -0
- package/src/mcp/webSearch.ts +388 -0
- package/src/originalPrompts/design_thinking.md +178 -0
- package/src/originalPrompts/design_thinking_persona.md +76 -0
- package/src/originalPrompts/document_generator_example.md +77 -0
- package/src/originalPrompts/document_generator_persona.md +47 -0
- package/src/originalPrompts/facilitator_persona.md +125 -0
- package/src/originalPrompts/guardrails.md +47 -0
- package/src/phases/contextSummarizer.ts +154 -0
- package/src/phases/discoveryEnricher.ts +223 -0
- package/src/phases/phaseExtractors.ts +247 -0
- package/src/phases/phaseHandlers.ts +450 -0
- package/src/prompts/design.md +51 -0
- package/src/prompts/develop-boundary.md +51 -0
- package/src/prompts/develop.md +111 -0
- package/src/prompts/discover.md +58 -0
- package/src/prompts/ideate.md +56 -0
- package/src/prompts/plan.md +51 -0
- package/src/prompts/promptLoader.ts +198 -0
- package/src/prompts/select.md +47 -0
- package/src/prompts/summarize/README.md +8 -0
- package/src/prompts/summarize/design-summary.md +37 -0
- package/src/prompts/summarize/develop-summary.md +25 -0
- package/src/prompts/summarize/ideate-summary.md +27 -0
- package/src/prompts/summarize/plan-summary.md +27 -0
- package/src/prompts/summarize/select-summary.md +21 -0
- package/src/prompts/system.md +28 -0
- package/src/sessions/exportPaths.ts +28 -0
- package/src/sessions/exportWriter.ts +490 -0
- package/src/sessions/sessionManager.ts +119 -0
- package/src/sessions/sessionStore.ts +69 -0
- package/src/shared/activitySpinner.ts +108 -0
- package/src/shared/copilotClient.ts +291 -0
- package/src/shared/data/cards.json +1249 -0
- package/src/shared/data/cardsLoader.ts +70 -0
- package/src/shared/errorClassifier.ts +160 -0
- package/src/shared/events.ts +103 -0
- package/src/shared/markdownRenderer.ts +44 -0
- package/src/shared/schemas/session.ts +346 -0
- package/src/shared/tableRenderer.ts +28 -0
- package/src/types/marked-terminal.d.ts +5 -0
- package/src/vendor/chalk.ts +2 -0
- package/src/vendor/cli-table3.ts +3 -0
- package/src/vendor/commander.ts +2 -0
- package/src/vendor/marked-terminal.ts +3 -0
- package/src/vendor/marked.ts +2 -0
- package/src/vendor/ora.ts +2 -0
- package/src/vendor/pino.ts +3 -0
- package/src/vendor/zod.ts +3 -0
- package/tests/e2e/developE2e.spec.ts +152 -0
- package/tests/e2e/developFailureE2e.spec.ts +289 -0
- package/tests/e2e/developPty.spec.ts +86 -0
- package/tests/e2e/discoveryWebSearchRelevance.spec.ts +103 -0
- package/tests/e2e/harness.spec.ts +104 -0
- package/tests/e2e/mcpLive.spec.ts +149 -0
- package/tests/e2e/newSession.e2e.spec.ts +245 -0
- package/tests/e2e/ralphLoopEnrichmentComparison.spec.ts +70 -0
- package/tests/e2e/workiqEnrichment.spec.ts +72 -0
- package/tests/e2e/zava-assessment/agent-interaction-script.md +258 -0
- package/tests/e2e/zava-assessment/company-profile.md +98 -0
- package/tests/e2e/zava-assessment/expected-results-checklist.md +454 -0
- package/tests/e2e/zavaSimulation.spec.ts +511 -0
- package/tests/fixtures/completedSession.json +141 -0
- package/tests/fixtures/test-fixture-project/package-lock.json +1585 -0
- package/tests/fixtures/test-fixture-project/package.json +12 -0
- package/tests/fixtures/test-fixture-project/src/add.ts +3 -0
- package/tests/fixtures/test-fixture-project/tests/failing.test.ts +7 -0
- package/tests/fixtures/test-fixture-project/tests/hanging.test.ts +9 -0
- package/tests/fixtures/test-fixture-project/tests/passing.test.ts +13 -0
- package/tests/fixtures/test-fixture-project/vitest.config.ts +7 -0
- package/tests/integration/autoStartConversation.spec.ts +168 -0
- package/tests/integration/defaultCommand.spec.ts +179 -0
- package/tests/integration/directCommandNonTty.spec.ts +260 -0
- package/tests/integration/directCommandTty.spec.ts +185 -0
- package/tests/integration/discoveryEnrichmentFlow.spec.ts +209 -0
- package/tests/integration/exportArtifacts.spec.ts +232 -0
- package/tests/integration/exportFallbackFlow.spec.ts +115 -0
- package/tests/integration/mcpDegradationFlow.spec.ts +231 -0
- package/tests/integration/mcpTransportFlow.spec.ts +178 -0
- package/tests/integration/newSessionFlow.spec.ts +406 -0
- package/tests/integration/pocGithubMcp.spec.ts +224 -0
- package/tests/integration/pocLocalFallback.spec.ts +205 -0
- package/tests/integration/pocScaffold.spec.ts +220 -0
- package/tests/integration/ralphLoopFlow.spec.ts +430 -0
- package/tests/integration/ralphLoopPartial.spec.ts +416 -0
- package/tests/integration/resumeAndBacktrack.spec.ts +278 -0
- package/tests/integration/spinnerLifecycle.spec.ts +270 -0
- package/tests/integration/summarizationFlow.spec.ts +135 -0
- package/tests/integration/testRunnerReal.spec.ts +63 -0
- package/tests/integration/webSearchAgent.spec.ts +155 -0
- package/tests/live/copilotSdkLive.spec.ts +149 -0
- package/tests/live/zavaFullWorkshop.spec.ts +515 -0
- package/tests/setup/loadEnv.ts +5 -0
- package/tests/unit/cli/developCommand.spec.ts +679 -0
- package/tests/unit/cli/directCommands.spec.ts +325 -0
- package/tests/unit/cli/envLoader.spec.ts +73 -0
- package/tests/unit/cli/ioContext.spec.ts +148 -0
- package/tests/unit/cli/preflight.spec.ts +125 -0
- package/tests/unit/cli/statusCommand.spec.ts +134 -0
- package/tests/unit/cli/workshopClientFallback.spec.ts +100 -0
- package/tests/unit/cli/workshopCommand.spec.ts +378 -0
- package/tests/unit/config/vitestEnvSetup.spec.ts +24 -0
- package/tests/unit/develop/checkpointState.spec.ts +378 -0
- package/tests/unit/develop/codeGenerator.spec.ts +447 -0
- package/tests/unit/develop/githubMcpAdapter.spec.ts +283 -0
- package/tests/unit/develop/mcpContextEnricher.spec.ts +564 -0
- package/tests/unit/develop/outputValidator.spec.ts +134 -0
- package/tests/unit/develop/pocScaffolder.spec.ts +451 -0
- package/tests/unit/develop/ralphLoop.spec.ts +1439 -0
- package/tests/unit/develop/templateRegistry.spec.ts +106 -0
- package/tests/unit/develop/testRunner.spec.ts +294 -0
- package/tests/unit/infraBicep.spec.ts +116 -0
- package/tests/unit/infraDeploy.spec.ts +102 -0
- package/tests/unit/infraTeardown.spec.ts +77 -0
- package/tests/unit/logging/logger.spec.ts +50 -0
- package/tests/unit/loop/conversationLoop.spec.ts +719 -0
- package/tests/unit/loop/phaseSummarizer.spec.ts +169 -0
- package/tests/unit/loop/streamingMarkdown.spec.ts +180 -0
- package/tests/unit/mcp/mcpManager.spec.ts +336 -0
- package/tests/unit/mcp/mcpTransport.spec.ts +689 -0
- package/tests/unit/mcp/retryPolicy.spec.ts +278 -0
- package/tests/unit/mcp/timeoutValidation.spec.ts +55 -0
- package/tests/unit/mcp/webSearch.spec.ts +718 -0
- package/tests/unit/phases/contextSummarizer.spec.ts +158 -0
- package/tests/unit/phases/discoveryEnricher.repeatCalls.spec.ts +125 -0
- package/tests/unit/phases/discoveryEnricher.spec.ts +512 -0
- package/tests/unit/phases/phaseExtractors.spec.ts +406 -0
- package/tests/unit/phases/phaseHandlers.spec.ts +483 -0
- package/tests/unit/prompts/promptLoader.spec.ts +144 -0
- package/tests/unit/schemas/pocSchemas.spec.ts +457 -0
- package/tests/unit/schemas/session.spec.ts +328 -0
- package/tests/unit/sessions/exportPaths.spec.ts +38 -0
- package/tests/unit/sessions/exportWriter.spec.ts +737 -0
- package/tests/unit/sessions/sessionManager.spec.ts +174 -0
- package/tests/unit/sessions/sessionStore.spec.ts +136 -0
- package/tests/unit/shared/activitySpinner.spec.ts +211 -0
- package/tests/unit/shared/cardsLoader.spec.ts +89 -0
- package/tests/unit/shared/copilotClient.spec.ts +185 -0
- package/tests/unit/shared/errorClassifier.spec.ts +152 -0
- package/tests/unit/shared/events.spec.ts +71 -0
- package/tests/unit/shared/markdownRenderer.spec.ts +42 -0
- package/tests/unit/shared/markdownRendererChunks.spec.ts +83 -0
- package/tests/unit/shared/tableRenderer.spec.ts +38 -0
- package/tsconfig.json +20 -0
- package/vitest.config.ts +15 -0
- package/vitest.live.config.ts +19 -0
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Phase handler factory.
|
|
3
|
+
*
|
|
4
|
+
* Creates PhaseHandler instances for each workshop phase.
|
|
5
|
+
* Each handler:
|
|
6
|
+
* - Builds the system prompt from canonical prompts
|
|
7
|
+
* - Provides grounding document references
|
|
8
|
+
* - Extracts structured data from LLM responses
|
|
9
|
+
*/
|
|
10
|
+
import type { PhaseHandler } from '../loop/conversationLoop.js';
|
|
11
|
+
import type { LoopIO } from '../loop/conversationLoop.js';
|
|
12
|
+
import type { PhaseValue, WorkshopSession } from '../shared/schemas/session.js';
|
|
13
|
+
import { buildSystemPrompt, getPhaseReferences } from '../prompts/promptLoader.js';
|
|
14
|
+
import {
|
|
15
|
+
extractBusinessContext,
|
|
16
|
+
extractWorkflow,
|
|
17
|
+
extractIdeas,
|
|
18
|
+
extractEvaluation,
|
|
19
|
+
extractSelection,
|
|
20
|
+
extractPlan,
|
|
21
|
+
extractPocState,
|
|
22
|
+
extractSessionName,
|
|
23
|
+
} from './phaseExtractors.js';
|
|
24
|
+
import { DiscoveryEnricher } from './discoveryEnricher.js';
|
|
25
|
+
import type { WebSearchClient } from './discoveryEnricher.js';
|
|
26
|
+
import type { McpManager } from '../mcp/mcpManager.js';
|
|
27
|
+
import { buildSummarizedContext, renderSummarizedContext } from './contextSummarizer.js';
|
|
28
|
+
|
|
29
|
+
// ── Initial message helper ──────────────────────────────────────────────────
|
|
30
|
+
|
|
31
|
+
const PHASE_INTROS: Record<PhaseValue, string> = {
|
|
32
|
+
Discover:
|
|
33
|
+
'Introduce the Discover phase. Ask about the business, its challenges, and what area to focus on.',
|
|
34
|
+
Ideate:
|
|
35
|
+
'Introduce the Ideate phase. Review the business context and workflow, then brainstorm AI-powered ideas.',
|
|
36
|
+
Design:
|
|
37
|
+
'Introduce the Design phase. Review the generated ideas and help evaluate them using a feasibility-value matrix.',
|
|
38
|
+
Select:
|
|
39
|
+
'Introduce the Select phase. Present the top-ranked ideas and help the user choose the best one to implement.',
|
|
40
|
+
Plan: 'Introduce the Plan phase. Create an implementation plan with milestones for the selected idea.',
|
|
41
|
+
Develop:
|
|
42
|
+
'Introduce the Develop phase. Generate proof-of-concept code for the planned implementation.',
|
|
43
|
+
Complete: 'The workshop is complete. Summarize the results.',
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const PHASE_RESUMES: Record<PhaseValue, string> = {
|
|
47
|
+
Discover:
|
|
48
|
+
'We are resuming the Discover phase. Summarize what was discussed so far and ask the next question.',
|
|
49
|
+
Ideate:
|
|
50
|
+
'We are resuming the Ideate phase. Summarize the ideas generated so far and continue brainstorming.',
|
|
51
|
+
Design:
|
|
52
|
+
'We are resuming the Design phase. Summarize the evaluation progress and continue with the next step.',
|
|
53
|
+
Select: 'We are resuming the Select phase. Summarize the selection process so far and continue.',
|
|
54
|
+
Plan: 'We are resuming the Plan phase. Summarize the plan progress and continue with the next milestone.',
|
|
55
|
+
Develop:
|
|
56
|
+
'We are resuming the Develop phase. Summarize the PoC development progress and continue.',
|
|
57
|
+
Complete: 'The workshop is complete. Summarize the results.',
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Generate the initial message for a phase based on session state.
|
|
62
|
+
* New sessions get an introduction; resumed sessions get a progress summary prompt.
|
|
63
|
+
*/
|
|
64
|
+
function buildInitialMessage(phase: PhaseValue, session: WorkshopSession): string {
|
|
65
|
+
const phaseTurns = (session.turns ?? []).filter((t) => t.phase === phase);
|
|
66
|
+
if (phaseTurns.length > 0) {
|
|
67
|
+
return PHASE_RESUMES[phase];
|
|
68
|
+
}
|
|
69
|
+
return PHASE_INTROS[phase];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ── Discover Phase ──────────────────────────────────────────────────────────
|
|
73
|
+
|
|
74
|
+
export interface DiscoverHandlerConfig {
|
|
75
|
+
/** IO for permission prompts */
|
|
76
|
+
io?: LoopIO;
|
|
77
|
+
/** MCP manager for WorkIQ tool calls */
|
|
78
|
+
mcpManager?: McpManager;
|
|
79
|
+
/** Web search client */
|
|
80
|
+
webSearchClient?: WebSearchClient;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function createDiscoverHandler(config?: DiscoverHandlerConfig): PhaseHandler {
|
|
84
|
+
let cachedPrompt: string | null = null;
|
|
85
|
+
let cachedRefs: string[] | null = null;
|
|
86
|
+
let enrichmentDone = false;
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
phase: 'Discover',
|
|
90
|
+
|
|
91
|
+
buildSystemPrompt(_session: WorkshopSession): string {
|
|
92
|
+
// Lazy-loaded in run() but we need sync return.
|
|
93
|
+
// The prompt is pre-loaded before the loop starts.
|
|
94
|
+
return (
|
|
95
|
+
cachedPrompt ??
|
|
96
|
+
'You are an AI Discovery Workshop facilitator helping with the Discover phase.'
|
|
97
|
+
);
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
getReferences(_session: WorkshopSession): string[] {
|
|
101
|
+
return cachedRefs ?? [];
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
extractResult(session: WorkshopSession, response: string): Partial<WorkshopSession> {
|
|
105
|
+
const updates: Partial<WorkshopSession> = {};
|
|
106
|
+
const bc = extractBusinessContext(response);
|
|
107
|
+
if (bc) updates.businessContext = bc;
|
|
108
|
+
const wf = extractWorkflow(response);
|
|
109
|
+
if (wf) updates.workflow = wf;
|
|
110
|
+
// First-write-wins: only set name if session doesn't already have one
|
|
111
|
+
if (!session.name) {
|
|
112
|
+
const sessionName = extractSessionName(response);
|
|
113
|
+
if (sessionName) updates.name = sessionName;
|
|
114
|
+
}
|
|
115
|
+
return updates;
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
async postExtract(session: WorkshopSession): Promise<Partial<WorkshopSession>> {
|
|
119
|
+
// Trigger enrichment once when businessContext is first available
|
|
120
|
+
if (enrichmentDone || !session.businessContext) return {};
|
|
121
|
+
enrichmentDone = true;
|
|
122
|
+
|
|
123
|
+
const enricher = new DiscoveryEnricher();
|
|
124
|
+
const io = config?.io;
|
|
125
|
+
const mcpManager = config?.mcpManager;
|
|
126
|
+
const webSearchClient = config?.webSearchClient;
|
|
127
|
+
|
|
128
|
+
// Only run enrichment if at least one source is available
|
|
129
|
+
if (!webSearchClient && (!mcpManager || !mcpManager.isAvailable('workiq'))) {
|
|
130
|
+
return {};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const companySummary = session.businessContext.businessDescription;
|
|
134
|
+
|
|
135
|
+
try {
|
|
136
|
+
const enrichment = await enricher.enrich({
|
|
137
|
+
companySummary,
|
|
138
|
+
mcpManager:
|
|
139
|
+
mcpManager ??
|
|
140
|
+
({ isAvailable: () => false, callTool: async () => ({}) } as unknown as McpManager),
|
|
141
|
+
io: io ?? {
|
|
142
|
+
write: () => {},
|
|
143
|
+
writeActivity: () => {},
|
|
144
|
+
writeToolSummary: () => {},
|
|
145
|
+
readInput: async () => null,
|
|
146
|
+
showDecisionGate: async () => ({ choice: 'continue' as const }),
|
|
147
|
+
isJsonMode: false,
|
|
148
|
+
isTTY: false,
|
|
149
|
+
},
|
|
150
|
+
webSearchClient,
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
return {
|
|
154
|
+
discovery: {
|
|
155
|
+
enrichment,
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
} catch {
|
|
159
|
+
// Enrichment failure is non-fatal
|
|
160
|
+
return {};
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
|
|
164
|
+
isComplete(session: WorkshopSession, _response: string): boolean {
|
|
165
|
+
// Discover is complete when we have business context and workflow
|
|
166
|
+
return !!(session.businessContext && session.workflow);
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
getInitialMessage(session: WorkshopSession): string {
|
|
170
|
+
return buildInitialMessage('Discover', session);
|
|
171
|
+
},
|
|
172
|
+
|
|
173
|
+
// Extension: allows pre-loading async prompts
|
|
174
|
+
async _preload() {
|
|
175
|
+
cachedPrompt = await buildSystemPrompt('Discover');
|
|
176
|
+
cachedRefs = await getPhaseReferences('Discover');
|
|
177
|
+
},
|
|
178
|
+
} as PhaseHandler & { _preload(): Promise<void> };
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ── Ideate Phase ────────────────────────────────────────────────────────────
|
|
182
|
+
|
|
183
|
+
function createIdeateHandler(): PhaseHandler & { _preload(): Promise<void> } {
|
|
184
|
+
let cachedPrompt: string | null = null;
|
|
185
|
+
let cachedRefs: string[] | null = null;
|
|
186
|
+
|
|
187
|
+
return {
|
|
188
|
+
phase: 'Ideate',
|
|
189
|
+
|
|
190
|
+
buildSystemPrompt(session: WorkshopSession): string {
|
|
191
|
+
// FR-016: Use unified summarized context instead of ad-hoc injection
|
|
192
|
+
const context = renderSummarizedContext(buildSummarizedContext(session));
|
|
193
|
+
return (cachedPrompt ?? 'You are facilitating the Ideate phase.') + context;
|
|
194
|
+
},
|
|
195
|
+
|
|
196
|
+
getReferences(_session: WorkshopSession): string[] {
|
|
197
|
+
return cachedRefs ?? [];
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
extractResult(session: WorkshopSession, response: string): Partial<WorkshopSession> {
|
|
201
|
+
const ideas = extractIdeas(response);
|
|
202
|
+
if (ideas && ideas.length > 0) {
|
|
203
|
+
// Merge with existing ideas (append, deduplicate by id)
|
|
204
|
+
const existing = session.ideas ?? [];
|
|
205
|
+
const existingIds = new Set(existing.map((i) => i.id));
|
|
206
|
+
const merged = [...existing, ...ideas.filter((i) => !existingIds.has(i.id))];
|
|
207
|
+
return { ideas: merged };
|
|
208
|
+
}
|
|
209
|
+
return {};
|
|
210
|
+
},
|
|
211
|
+
|
|
212
|
+
isComplete(session: WorkshopSession, _response: string): boolean {
|
|
213
|
+
return !!(session.ideas && session.ideas.length > 0);
|
|
214
|
+
},
|
|
215
|
+
|
|
216
|
+
getInitialMessage(session: WorkshopSession): string {
|
|
217
|
+
return buildInitialMessage('Ideate', session);
|
|
218
|
+
},
|
|
219
|
+
|
|
220
|
+
async _preload() {
|
|
221
|
+
cachedPrompt = await buildSystemPrompt('Ideate');
|
|
222
|
+
cachedRefs = await getPhaseReferences('Ideate');
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// ── Design Phase ────────────────────────────────────────────────────────────
|
|
228
|
+
|
|
229
|
+
function createDesignHandler(): PhaseHandler & { _preload(): Promise<void> } {
|
|
230
|
+
let cachedPrompt: string | null = null;
|
|
231
|
+
let cachedRefs: string[] | null = null;
|
|
232
|
+
|
|
233
|
+
return {
|
|
234
|
+
phase: 'Design',
|
|
235
|
+
|
|
236
|
+
buildSystemPrompt(session: WorkshopSession): string {
|
|
237
|
+
// FR-016: Use unified summarized context
|
|
238
|
+
const context = renderSummarizedContext(buildSummarizedContext(session));
|
|
239
|
+
return (cachedPrompt ?? 'You are facilitating the Design phase.') + context;
|
|
240
|
+
},
|
|
241
|
+
|
|
242
|
+
getReferences(_session: WorkshopSession): string[] {
|
|
243
|
+
return cachedRefs ?? [];
|
|
244
|
+
},
|
|
245
|
+
|
|
246
|
+
extractResult(session: WorkshopSession, response: string): Partial<WorkshopSession> {
|
|
247
|
+
const evaluation = extractEvaluation(response);
|
|
248
|
+
if (evaluation) return { evaluation };
|
|
249
|
+
return {};
|
|
250
|
+
},
|
|
251
|
+
|
|
252
|
+
isComplete(session: WorkshopSession, _response: string): boolean {
|
|
253
|
+
return !!session.evaluation;
|
|
254
|
+
},
|
|
255
|
+
|
|
256
|
+
getInitialMessage(session: WorkshopSession): string {
|
|
257
|
+
return buildInitialMessage('Design', session);
|
|
258
|
+
},
|
|
259
|
+
|
|
260
|
+
async _preload() {
|
|
261
|
+
cachedPrompt = await buildSystemPrompt('Design');
|
|
262
|
+
cachedRefs = await getPhaseReferences('Design');
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// ── Select Phase ────────────────────────────────────────────────────────────
|
|
268
|
+
|
|
269
|
+
function createSelectHandler(): PhaseHandler & { _preload(): Promise<void> } {
|
|
270
|
+
let cachedPrompt: string | null = null;
|
|
271
|
+
let cachedRefs: string[] | null = null;
|
|
272
|
+
|
|
273
|
+
return {
|
|
274
|
+
phase: 'Select',
|
|
275
|
+
|
|
276
|
+
buildSystemPrompt(session: WorkshopSession): string {
|
|
277
|
+
// FR-016: Use unified summarized context
|
|
278
|
+
const context = renderSummarizedContext(buildSummarizedContext(session));
|
|
279
|
+
return (cachedPrompt ?? 'You are facilitating the Select phase.') + context;
|
|
280
|
+
},
|
|
281
|
+
|
|
282
|
+
getReferences(_session: WorkshopSession): string[] {
|
|
283
|
+
return cachedRefs ?? [];
|
|
284
|
+
},
|
|
285
|
+
|
|
286
|
+
extractResult(session: WorkshopSession, response: string): Partial<WorkshopSession> {
|
|
287
|
+
const selection = extractSelection(response);
|
|
288
|
+
if (selection) return { selection };
|
|
289
|
+
return {};
|
|
290
|
+
},
|
|
291
|
+
|
|
292
|
+
isComplete(session: WorkshopSession, _response: string): boolean {
|
|
293
|
+
return !!session.selection?.confirmedByUser;
|
|
294
|
+
},
|
|
295
|
+
|
|
296
|
+
getInitialMessage(session: WorkshopSession): string {
|
|
297
|
+
return buildInitialMessage('Select', session);
|
|
298
|
+
},
|
|
299
|
+
|
|
300
|
+
async _preload() {
|
|
301
|
+
cachedPrompt = await buildSystemPrompt('Select');
|
|
302
|
+
cachedRefs = await getPhaseReferences('Select');
|
|
303
|
+
},
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// ── Plan Phase ──────────────────────────────────────────────────────────────
|
|
308
|
+
|
|
309
|
+
function createPlanHandler(): PhaseHandler & { _preload(): Promise<void> } {
|
|
310
|
+
let cachedPrompt: string | null = null;
|
|
311
|
+
let cachedRefs: string[] | null = null;
|
|
312
|
+
|
|
313
|
+
return {
|
|
314
|
+
phase: 'Plan',
|
|
315
|
+
|
|
316
|
+
buildSystemPrompt(session: WorkshopSession): string {
|
|
317
|
+
// FR-016: Use unified summarized context
|
|
318
|
+
const context = renderSummarizedContext(buildSummarizedContext(session));
|
|
319
|
+
return (cachedPrompt ?? 'You are facilitating the Plan phase.') + context;
|
|
320
|
+
},
|
|
321
|
+
|
|
322
|
+
getReferences(_session: WorkshopSession): string[] {
|
|
323
|
+
return cachedRefs ?? [];
|
|
324
|
+
},
|
|
325
|
+
|
|
326
|
+
extractResult(session: WorkshopSession, response: string): Partial<WorkshopSession> {
|
|
327
|
+
const plan = extractPlan(response);
|
|
328
|
+
if (plan) return { plan };
|
|
329
|
+
return {};
|
|
330
|
+
},
|
|
331
|
+
|
|
332
|
+
isComplete(session: WorkshopSession, _response: string): boolean {
|
|
333
|
+
return !!session.plan?.milestones?.length;
|
|
334
|
+
},
|
|
335
|
+
|
|
336
|
+
getInitialMessage(session: WorkshopSession): string {
|
|
337
|
+
return buildInitialMessage('Plan', session);
|
|
338
|
+
},
|
|
339
|
+
|
|
340
|
+
async _preload() {
|
|
341
|
+
cachedPrompt = await buildSystemPrompt('Plan');
|
|
342
|
+
cachedRefs = await getPhaseReferences('Plan');
|
|
343
|
+
},
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// ── Develop Boundary Phase ──────────────────────────────────────────────────
|
|
348
|
+
// T021: This handler covers the boundary (requirements capture) phase.
|
|
349
|
+
// For full PoC generation, use `sofia dev` which invokes the RalphLoop
|
|
350
|
+
// (src/develop/ralphLoop.ts) directly. The develop-boundary.md prompt is
|
|
351
|
+
// kept for backward compatibility.
|
|
352
|
+
|
|
353
|
+
function createDevelopHandler(): PhaseHandler & { _preload(): Promise<void> } {
|
|
354
|
+
let cachedPrompt: string | null = null;
|
|
355
|
+
let cachedRefs: string[] | null = null;
|
|
356
|
+
|
|
357
|
+
return {
|
|
358
|
+
phase: 'Develop',
|
|
359
|
+
|
|
360
|
+
buildSystemPrompt(session: WorkshopSession): string {
|
|
361
|
+
// FR-016: Use unified summarized context
|
|
362
|
+
const context = renderSummarizedContext(buildSummarizedContext(session));
|
|
363
|
+
return (cachedPrompt ?? 'You are facilitating the Develop boundary phase.') + context;
|
|
364
|
+
},
|
|
365
|
+
|
|
366
|
+
getReferences(_session: WorkshopSession): string[] {
|
|
367
|
+
return cachedRefs ?? [];
|
|
368
|
+
},
|
|
369
|
+
|
|
370
|
+
extractResult(session: WorkshopSession, response: string): Partial<WorkshopSession> {
|
|
371
|
+
const poc = extractPocState(response);
|
|
372
|
+
if (poc) return { poc };
|
|
373
|
+
return {};
|
|
374
|
+
},
|
|
375
|
+
|
|
376
|
+
isComplete(session: WorkshopSession, _response: string): boolean {
|
|
377
|
+
return !!session.poc;
|
|
378
|
+
},
|
|
379
|
+
|
|
380
|
+
getInitialMessage(session: WorkshopSession): string {
|
|
381
|
+
return buildInitialMessage('Develop', session);
|
|
382
|
+
},
|
|
383
|
+
|
|
384
|
+
async _preload() {
|
|
385
|
+
cachedPrompt = await buildSystemPrompt('Develop');
|
|
386
|
+
cachedRefs = await getPhaseReferences('Develop');
|
|
387
|
+
},
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// ── Factory ─────────────────────────────────────────────────────────────────
|
|
392
|
+
|
|
393
|
+
export type PreloadablePhaseHandler = PhaseHandler & { _preload(): Promise<void> };
|
|
394
|
+
|
|
395
|
+
export interface PhaseHandlerConfig {
|
|
396
|
+
/** Discovery enrichment config (only used for Discover phase) */
|
|
397
|
+
discover?: DiscoverHandlerConfig;
|
|
398
|
+
/** MCP manager for tool calls (FR-011) */
|
|
399
|
+
mcpManager?: McpManager;
|
|
400
|
+
/** Web search client (FR-012) */
|
|
401
|
+
webSearchClient?: WebSearchClient;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
const PHASE_FACTORIES: Record<
|
|
405
|
+
PhaseValue,
|
|
406
|
+
(config?: PhaseHandlerConfig) => PreloadablePhaseHandler
|
|
407
|
+
> = {
|
|
408
|
+
Discover: (config) => createDiscoverHandler(config?.discover) as PreloadablePhaseHandler,
|
|
409
|
+
Ideate: () => createIdeateHandler(),
|
|
410
|
+
Design: () => createDesignHandler(),
|
|
411
|
+
Select: () => createSelectHandler(),
|
|
412
|
+
Plan: () => createPlanHandler(),
|
|
413
|
+
Develop: () => createDevelopHandler(),
|
|
414
|
+
Complete: () => createDiscoverHandler() as PreloadablePhaseHandler, // Placeholder
|
|
415
|
+
};
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Create a phase handler for the given phase.
|
|
419
|
+
* Call `_preload()` before using in a ConversationLoop to load prompts.
|
|
420
|
+
*/
|
|
421
|
+
export function createPhaseHandler(
|
|
422
|
+
phase: PhaseValue,
|
|
423
|
+
config?: PhaseHandlerConfig,
|
|
424
|
+
): PreloadablePhaseHandler {
|
|
425
|
+
const factory = PHASE_FACTORIES[phase];
|
|
426
|
+
if (!factory) {
|
|
427
|
+
throw new Error(`No handler for phase: ${phase}`);
|
|
428
|
+
}
|
|
429
|
+
const handler = factory(config);
|
|
430
|
+
// Override the phase to match what was requested
|
|
431
|
+
handler.phase = phase;
|
|
432
|
+
return handler;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Get the ordered list of workshop phases (excluding Complete).
|
|
437
|
+
*/
|
|
438
|
+
export function getPhaseOrder(): PhaseValue[] {
|
|
439
|
+
return ['Discover', 'Ideate', 'Design', 'Select', 'Plan', 'Develop'];
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Get the next phase after the given one, or null if at the end.
|
|
444
|
+
*/
|
|
445
|
+
export function getNextPhase(current: PhaseValue): PhaseValue | null {
|
|
446
|
+
const order = getPhaseOrder();
|
|
447
|
+
const idx = order.indexOf(current);
|
|
448
|
+
if (idx === -1 || idx >= order.length - 1) return null;
|
|
449
|
+
return order[idx + 1];
|
|
450
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Design Phase Prompt
|
|
2
|
+
|
|
3
|
+
You are facilitating the **Design** phase of the AI Discovery Workshop (Steps 10–12).
|
|
4
|
+
|
|
5
|
+
## Context From Previous Phases
|
|
6
|
+
|
|
7
|
+
You have access to:
|
|
8
|
+
- Business context, topic, workflow map (from Discover)
|
|
9
|
+
- AI Discovery Cards mapping, generated ideas as Idea Cards (from Ideate)
|
|
10
|
+
|
|
11
|
+
## What You Must Accomplish
|
|
12
|
+
|
|
13
|
+
### Step 10: Create Idea Cards
|
|
14
|
+
- Refine each idea from the Ideate phase into a complete Idea Card:
|
|
15
|
+
- **Title**: Clear, compelling name
|
|
16
|
+
- **Description**: Detailed explanation of the solution concept
|
|
17
|
+
- **Workflow Steps Covered**: Mapped activities
|
|
18
|
+
- **Aspirational Solution Scope**: Vision of success
|
|
19
|
+
- **Assumptions**: What must be true for this to work
|
|
20
|
+
- Present all refined Idea Cards to the user for review and editing.
|
|
21
|
+
|
|
22
|
+
### Step 11: Evaluate Ideas
|
|
23
|
+
- Create a **Feasibility/Value Matrix** for all ideas:
|
|
24
|
+
- X-axis: Feasibility (1–5) — How easy is it to build?
|
|
25
|
+
- Y-axis: Business Value (1–5) — How impactful is it?
|
|
26
|
+
- Ask the user to score each idea.
|
|
27
|
+
- Present results as a table and Mermaid quadrant chart.
|
|
28
|
+
- Consider KPIs and metrics from the workflow mapping.
|
|
29
|
+
|
|
30
|
+
### Step 12: Assess Impact
|
|
31
|
+
For each idea, evaluate and document:
|
|
32
|
+
- **Data Needed**: What data sources are required?
|
|
33
|
+
- **Risks**: Technical, organizational, ethical risks
|
|
34
|
+
- **Business Impact**: Revenue, cost, efficiency effects
|
|
35
|
+
- **Human Value**: Employee experience, customer satisfaction
|
|
36
|
+
- **Key Metrics Influenced**: Which KPIs will improve?
|
|
37
|
+
|
|
38
|
+
Use the **BXT Framework** (Business, eXperience, Technology) to structure the assessment:
|
|
39
|
+
- **Business**: Strategic alignment, ROI potential, market differentiation
|
|
40
|
+
- **eXperience**: User satisfaction, accessibility, adoption likelihood
|
|
41
|
+
- **Technology**: Technical feasibility, data readiness, integration complexity
|
|
42
|
+
|
|
43
|
+
## Output at End of Design Phase
|
|
44
|
+
|
|
45
|
+
Produce:
|
|
46
|
+
1. **Refined Idea Cards**: Complete cards with all fields
|
|
47
|
+
2. **Feasibility/Value Matrix**: Scored ideas in a table and quadrant chart
|
|
48
|
+
3. **Impact Assessment**: BXT analysis for each idea
|
|
49
|
+
4. **Architecture Sketch**: High-level Mermaid diagram showing how the top idea(s) could be implemented
|
|
50
|
+
|
|
51
|
+
Confirm this output with the user before proceeding to the Select phase.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Develop Boundary Prompt
|
|
2
|
+
|
|
3
|
+
You are facilitating the **Develop** boundary phase of the AI Discovery Workshop.
|
|
4
|
+
|
|
5
|
+
> **Note**: This phase captures PoC intent and requirements but does NOT generate code.
|
|
6
|
+
> Code generation is handled by Feature 002 (PoC Generation & Ralph Loop).
|
|
7
|
+
|
|
8
|
+
## Context From Previous Phases
|
|
9
|
+
|
|
10
|
+
You have access to:
|
|
11
|
+
- The selected idea with full details
|
|
12
|
+
- Implementation plan with milestones and architecture
|
|
13
|
+
- PoC scope definition with success criteria
|
|
14
|
+
|
|
15
|
+
## What You Must Accomplish
|
|
16
|
+
|
|
17
|
+
### Capture PoC Requirements
|
|
18
|
+
- Confirm the PoC scope with the user:
|
|
19
|
+
- Core functionality to demonstrate
|
|
20
|
+
- Data sources and sample data needed
|
|
21
|
+
- Target platform/runtime
|
|
22
|
+
- Integration requirements
|
|
23
|
+
|
|
24
|
+
### Define Success Criteria
|
|
25
|
+
- Document measurable success criteria:
|
|
26
|
+
- Functional requirements (what must work)
|
|
27
|
+
- Performance targets (response time, throughput)
|
|
28
|
+
- User experience goals (interaction patterns)
|
|
29
|
+
|
|
30
|
+
### Capture Technical Preferences
|
|
31
|
+
- Ask the user about:
|
|
32
|
+
- Preferred programming language/framework
|
|
33
|
+
- Hosting preferences (cloud, local, hybrid)
|
|
34
|
+
- Authentication/authorization requirements
|
|
35
|
+
- Any existing infrastructure to leverage
|
|
36
|
+
|
|
37
|
+
### Prepare Handoff
|
|
38
|
+
- Structure all captured information into the `PocDevelopmentState`:
|
|
39
|
+
- `repoPath`: Where the PoC will be generated (if known)
|
|
40
|
+
- `iterations`: Empty initially (filled by Feature 002)
|
|
41
|
+
- PoC requirements captured in session context
|
|
42
|
+
|
|
43
|
+
## Output at End of Develop Boundary
|
|
44
|
+
|
|
45
|
+
Produce:
|
|
46
|
+
1. **PoC Requirements Document**: Complete requirements for code generation
|
|
47
|
+
2. **Success Criteria Checklist**: Measurable criteria for the PoC
|
|
48
|
+
3. **Technical Preferences**: Language, platform, and infrastructure notes
|
|
49
|
+
4. **Handoff Summary**: Everything needed for the Ralph Loop to begin
|
|
50
|
+
|
|
51
|
+
Mark the session phase as `Complete` after user confirms the captured requirements.
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Develop Phase System Prompt
|
|
2
|
+
|
|
3
|
+
You are **sofIA's PoC Code Generator**, an expert TypeScript/Node.js developer responsible for generating and iteratively refining a proof-of-concept repository as part of the sofIA AI Discovery Workshop.
|
|
4
|
+
|
|
5
|
+
## Your Role
|
|
6
|
+
|
|
7
|
+
You generate complete, working code files for a TypeScript + Vitest PoC that demonstrates the AI idea selected during the workshop. You follow a strict **test-driven approach**: you write or fix code so that the provided test failures are resolved.
|
|
8
|
+
|
|
9
|
+
## Output Format
|
|
10
|
+
|
|
11
|
+
You MUST respond with fenced code blocks that include the target file path using the `file=` attribute:
|
|
12
|
+
|
|
13
|
+
````
|
|
14
|
+
```typescript file=src/index.ts
|
|
15
|
+
// complete file content here
|
|
16
|
+
```
|
|
17
|
+
````
|
|
18
|
+
|
|
19
|
+
- Always output the **complete file content** (not diffs or partial snippets)
|
|
20
|
+
- Use relative paths from the PoC root (e.g., `src/index.ts`, `tests/index.test.ts`)
|
|
21
|
+
- You may output multiple code blocks to modify multiple files in one response
|
|
22
|
+
- Do not include explanatory text before/after code blocks (code only)
|
|
23
|
+
|
|
24
|
+
## Iteration Context
|
|
25
|
+
|
|
26
|
+
Each iteration provides you with:
|
|
27
|
+
- The current state (iteration number, previous outcome)
|
|
28
|
+
- Failing test details (test name, error message, expected vs actual values)
|
|
29
|
+
- The list of current files in the PoC directory
|
|
30
|
+
- Any library documentation fetched via Context7 MCP
|
|
31
|
+
- Any Azure/cloud architecture guidance fetched via Azure MCP
|
|
32
|
+
- Web search results when you have been stuck for 2+ iterations
|
|
33
|
+
|
|
34
|
+
## Code Generation Guidelines
|
|
35
|
+
|
|
36
|
+
### TypeScript Standards
|
|
37
|
+
- Use ES modules (`import`/`export`), not CommonJS (`require`)
|
|
38
|
+
- Target ES2022 (`"module": "Node16"` in tsconfig)
|
|
39
|
+
- Use strict TypeScript — no `any` unless absolutely necessary
|
|
40
|
+
- Export named functions and classes (not default exports where possible)
|
|
41
|
+
|
|
42
|
+
### Dependencies
|
|
43
|
+
- Use `vitest` for testing (already in devDependencies)
|
|
44
|
+
- If you need to add a new npm dependency, update `package.json` — the loop will detect the change and run `npm install` automatically
|
|
45
|
+
- Prefer lightweight packages; avoid heavy frameworks for PoC unless the plan requires them
|
|
46
|
+
|
|
47
|
+
### Test Quality
|
|
48
|
+
- Tests must be runnable with `npx vitest run`
|
|
49
|
+
- Use `describe` / `it` / `expect` from vitest
|
|
50
|
+
- Each test should be independent (no shared state between tests)
|
|
51
|
+
- Mock external services (APIs, databases) using `vi.mock()` or dependency injection
|
|
52
|
+
|
|
53
|
+
### MCP Tool Use (when available)
|
|
54
|
+
|
|
55
|
+
**Context7** — Use when you need up-to-date library documentation:
|
|
56
|
+
- Query for the specific npm package APIs you are using
|
|
57
|
+
- Especially useful for packages with rapidly evolving APIs
|
|
58
|
+
|
|
59
|
+
**web.search** — Use when stuck on an implementation pattern:
|
|
60
|
+
- Search for specific error messages you are encountering
|
|
61
|
+
- Look for examples of the specific integration you need
|
|
62
|
+
|
|
63
|
+
**Microsoft Docs / Azure MCP** — Use when the plan references Azure services:
|
|
64
|
+
- Query for the specific Azure SDK API needed
|
|
65
|
+
- Use for connection string formats, authentication patterns, SDK initialization
|
|
66
|
+
|
|
67
|
+
## Error Recovery
|
|
68
|
+
|
|
69
|
+
If tests are still failing after your changes:
|
|
70
|
+
1. Re-read the exact error message — it often points to the precise line/assertion
|
|
71
|
+
2. Check if you need to update the test to match the implementation (or vice versa)
|
|
72
|
+
3. Ensure all imports resolve correctly (check package.json for the dependency)
|
|
73
|
+
4. Consider if a simpler implementation would pass the test first, then refine
|
|
74
|
+
|
|
75
|
+
## Iteration Prompt Template
|
|
76
|
+
|
|
77
|
+
When you receive the iteration context, it will be structured as:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
## Current State
|
|
81
|
+
- Iteration: {N} of {max}
|
|
82
|
+
- Previous outcome: {scaffold | tests-passing | tests-failing | error}
|
|
83
|
+
|
|
84
|
+
## Test Results
|
|
85
|
+
- Passed: {N}, Failed: {N}, Skipped: {N}
|
|
86
|
+
- Duration: {ms}ms
|
|
87
|
+
- Failures:
|
|
88
|
+
1. {testName}: {message}
|
|
89
|
+
Expected: {expected}
|
|
90
|
+
Actual: {actual}
|
|
91
|
+
At: {file}:{line}
|
|
92
|
+
|
|
93
|
+
## Files in PoC
|
|
94
|
+
{directory tree}
|
|
95
|
+
|
|
96
|
+
## MCP Context (if available)
|
|
97
|
+
{library docs / Azure guidance / web search results}
|
|
98
|
+
|
|
99
|
+
## Task
|
|
100
|
+
Fix the failing tests. Respond with complete updated file contents using fenced code blocks.
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Quality Bar
|
|
104
|
+
|
|
105
|
+
The PoC is considered successful when:
|
|
106
|
+
- All tests in `tests/` pass with `npm test`
|
|
107
|
+
- The `src/index.ts` entry point exports the main functionality
|
|
108
|
+
- The README explains what the PoC demonstrates and how to run it
|
|
109
|
+
- No TypeScript compilation errors
|
|
110
|
+
|
|
111
|
+
Focus on correctness first, then clarity. The PoC should demonstrate the AI capability described in the workshop plan, not be production-ready software.
|