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,346 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Zod schemas for WorkshopSession and related entities.
|
|
3
|
+
*
|
|
4
|
+
* Source of truth: specs/001-cli-workshop-rebuild/data-model.md
|
|
5
|
+
* Contract: specs/001-cli-workshop-rebuild/contracts/session-json.md
|
|
6
|
+
*/
|
|
7
|
+
import { z } from '../../vendor/zod.js';
|
|
8
|
+
|
|
9
|
+
// ── Enums ────────────────────────────────────────────────────────────────────
|
|
10
|
+
|
|
11
|
+
export const Phase = [
|
|
12
|
+
'Discover',
|
|
13
|
+
'Ideate',
|
|
14
|
+
'Design',
|
|
15
|
+
'Select',
|
|
16
|
+
'Plan',
|
|
17
|
+
'Develop',
|
|
18
|
+
'Complete',
|
|
19
|
+
] as const;
|
|
20
|
+
|
|
21
|
+
export const phaseSchema = z.enum(Phase);
|
|
22
|
+
export type PhaseValue = z.infer<typeof phaseSchema>;
|
|
23
|
+
|
|
24
|
+
export const SessionStatus = ['Active', 'Paused', 'Completed', 'Errored'] as const;
|
|
25
|
+
export const sessionStatusSchema = z.enum(SessionStatus);
|
|
26
|
+
export type SessionStatusValue = z.infer<typeof sessionStatusSchema>;
|
|
27
|
+
|
|
28
|
+
// ── Leaf entities ────────────────────────────────────────────────────────────
|
|
29
|
+
|
|
30
|
+
export const metricSchema = z.object({
|
|
31
|
+
name: z.string(),
|
|
32
|
+
value: z.string().optional(),
|
|
33
|
+
unit: z.string().optional(),
|
|
34
|
+
});
|
|
35
|
+
export type Metric = z.infer<typeof metricSchema>;
|
|
36
|
+
|
|
37
|
+
export const participantSchema = z.object({
|
|
38
|
+
id: z.string(),
|
|
39
|
+
displayName: z.string(),
|
|
40
|
+
role: z.enum(['Facilitator', 'Attendee', 'Observer']),
|
|
41
|
+
});
|
|
42
|
+
export type Participant = z.infer<typeof participantSchema>;
|
|
43
|
+
|
|
44
|
+
export const businessContextSchema = z.object({
|
|
45
|
+
businessDescription: z.string(),
|
|
46
|
+
challenges: z.array(z.string()),
|
|
47
|
+
constraints: z.array(z.string()).optional(),
|
|
48
|
+
successMetrics: z.array(metricSchema).optional(),
|
|
49
|
+
});
|
|
50
|
+
export type BusinessContext = z.infer<typeof businessContextSchema>;
|
|
51
|
+
|
|
52
|
+
export const topicSelectionSchema = z.object({
|
|
53
|
+
topicArea: z.string(),
|
|
54
|
+
scopeNotes: z.string().optional(),
|
|
55
|
+
});
|
|
56
|
+
export type TopicSelection = z.infer<typeof topicSelectionSchema>;
|
|
57
|
+
|
|
58
|
+
// ── Workflow ─────────────────────────────────────────────────────────────────
|
|
59
|
+
|
|
60
|
+
export const workflowStepSchema = z.object({
|
|
61
|
+
id: z.string(),
|
|
62
|
+
name: z.string(),
|
|
63
|
+
description: z.string().optional(),
|
|
64
|
+
metrics: z.array(metricSchema).optional(),
|
|
65
|
+
});
|
|
66
|
+
export type WorkflowStep = z.infer<typeof workflowStepSchema>;
|
|
67
|
+
|
|
68
|
+
export const workflowEdgeSchema = z.object({
|
|
69
|
+
fromStepId: z.string(),
|
|
70
|
+
toStepId: z.string(),
|
|
71
|
+
});
|
|
72
|
+
export type WorkflowEdge = z.infer<typeof workflowEdgeSchema>;
|
|
73
|
+
|
|
74
|
+
export const workflowMapSchema = z.object({
|
|
75
|
+
activities: z.array(workflowStepSchema),
|
|
76
|
+
edges: z.array(workflowEdgeSchema),
|
|
77
|
+
});
|
|
78
|
+
export type WorkflowMap = z.infer<typeof workflowMapSchema>;
|
|
79
|
+
|
|
80
|
+
// ── Cards ────────────────────────────────────────────────────────────────────
|
|
81
|
+
|
|
82
|
+
export const envisioningCardSchema = z.object({
|
|
83
|
+
id: z.string(),
|
|
84
|
+
title: z.string(),
|
|
85
|
+
category: z.string().optional(),
|
|
86
|
+
notes: z.string().optional(),
|
|
87
|
+
});
|
|
88
|
+
export type EnvisioningCard = z.infer<typeof envisioningCardSchema>;
|
|
89
|
+
|
|
90
|
+
export const cardScoreSchema = z.object({
|
|
91
|
+
cardId: z.string(),
|
|
92
|
+
dimensions: z.record(z.string(), z.number()),
|
|
93
|
+
});
|
|
94
|
+
export type CardScore = z.infer<typeof cardScoreSchema>;
|
|
95
|
+
|
|
96
|
+
export const cardSelectionSchema = z.object({
|
|
97
|
+
selectedCards: z.array(envisioningCardSchema),
|
|
98
|
+
scores: z.array(cardScoreSchema).optional(),
|
|
99
|
+
});
|
|
100
|
+
export type CardSelection = z.infer<typeof cardSelectionSchema>;
|
|
101
|
+
|
|
102
|
+
// ── Ideas ────────────────────────────────────────────────────────────────────
|
|
103
|
+
|
|
104
|
+
export const ideaCardSchema = z.object({
|
|
105
|
+
id: z.string(),
|
|
106
|
+
title: z.string(),
|
|
107
|
+
description: z.string(),
|
|
108
|
+
workflowStepIds: z.array(z.string()),
|
|
109
|
+
aspirationalScope: z.string().optional(),
|
|
110
|
+
assumptions: z.array(z.string()).optional(),
|
|
111
|
+
});
|
|
112
|
+
export type IdeaCard = z.infer<typeof ideaCardSchema>;
|
|
113
|
+
|
|
114
|
+
// ── Evaluation ───────────────────────────────────────────────────────────────
|
|
115
|
+
|
|
116
|
+
export const ideaEvaluationItemSchema = z.object({
|
|
117
|
+
ideaId: z.string(),
|
|
118
|
+
feasibility: z.number(),
|
|
119
|
+
value: z.number(),
|
|
120
|
+
risks: z.array(z.string()).optional(),
|
|
121
|
+
dataNeeded: z.array(z.string()).optional(),
|
|
122
|
+
humanValue: z.array(z.string()).optional(),
|
|
123
|
+
kpisInfluenced: z.array(z.string()).optional(),
|
|
124
|
+
});
|
|
125
|
+
export type IdeaEvaluationItem = z.infer<typeof ideaEvaluationItemSchema>;
|
|
126
|
+
|
|
127
|
+
export const ideaEvaluationSchema = z.object({
|
|
128
|
+
ideas: z.array(ideaEvaluationItemSchema),
|
|
129
|
+
method: z.enum(['feasibility-value-matrix', 'custom']),
|
|
130
|
+
});
|
|
131
|
+
export type IdeaEvaluation = z.infer<typeof ideaEvaluationSchema>;
|
|
132
|
+
|
|
133
|
+
// ── Selection ────────────────────────────────────────────────────────────────
|
|
134
|
+
|
|
135
|
+
export const selectedIdeaSchema = z.object({
|
|
136
|
+
ideaId: z.string(),
|
|
137
|
+
selectionRationale: z.string(),
|
|
138
|
+
confirmedByUser: z.boolean(),
|
|
139
|
+
confirmedAt: z.string().optional(),
|
|
140
|
+
});
|
|
141
|
+
export type SelectedIdea = z.infer<typeof selectedIdeaSchema>;
|
|
142
|
+
|
|
143
|
+
// ── Plan ─────────────────────────────────────────────────────────────────────
|
|
144
|
+
|
|
145
|
+
export const milestoneSchema = z.object({
|
|
146
|
+
id: z.string(),
|
|
147
|
+
title: z.string(),
|
|
148
|
+
items: z.array(z.string()),
|
|
149
|
+
});
|
|
150
|
+
export type Milestone = z.infer<typeof milestoneSchema>;
|
|
151
|
+
|
|
152
|
+
export const implementationPlanSchema = z.object({
|
|
153
|
+
milestones: z.array(milestoneSchema),
|
|
154
|
+
architectureNotes: z.string().optional(),
|
|
155
|
+
dependencies: z.array(z.string()).optional(),
|
|
156
|
+
});
|
|
157
|
+
export type ImplementationPlan = z.infer<typeof implementationPlanSchema>;
|
|
158
|
+
|
|
159
|
+
// ── PoC ──────────────────────────────────────────────────────────────────────
|
|
160
|
+
|
|
161
|
+
// T007: New schemas for TechStack, TestFailure, TestResults
|
|
162
|
+
|
|
163
|
+
export const techStackSchema = z.object({
|
|
164
|
+
language: z.string(),
|
|
165
|
+
framework: z.string().optional(),
|
|
166
|
+
testRunner: z.string(),
|
|
167
|
+
buildCommand: z.string().optional(),
|
|
168
|
+
runtime: z.string(),
|
|
169
|
+
});
|
|
170
|
+
export type TechStack = z.infer<typeof techStackSchema>;
|
|
171
|
+
|
|
172
|
+
export const testFailureSchema = z.object({
|
|
173
|
+
testName: z.string(),
|
|
174
|
+
message: z.string(),
|
|
175
|
+
expected: z.string().optional(),
|
|
176
|
+
actual: z.string().optional(),
|
|
177
|
+
file: z.string().optional(),
|
|
178
|
+
line: z.number().optional(),
|
|
179
|
+
});
|
|
180
|
+
export type TestFailure = z.infer<typeof testFailureSchema>;
|
|
181
|
+
|
|
182
|
+
export const testResultsSchema = z
|
|
183
|
+
.object({
|
|
184
|
+
passed: z.number(),
|
|
185
|
+
failed: z.number(),
|
|
186
|
+
skipped: z.number(),
|
|
187
|
+
total: z.number(),
|
|
188
|
+
durationMs: z.number(),
|
|
189
|
+
failures: z.array(testFailureSchema),
|
|
190
|
+
rawOutput: z.string().optional(),
|
|
191
|
+
})
|
|
192
|
+
.refine((d) => d.total === d.passed + d.failed + d.skipped, {
|
|
193
|
+
message: 'total must equal passed + failed + skipped',
|
|
194
|
+
});
|
|
195
|
+
export type TestResults = z.infer<typeof testResultsSchema>;
|
|
196
|
+
|
|
197
|
+
// T005: Extended pocIterationSchema
|
|
198
|
+
export const pocIterationSchema = z.object({
|
|
199
|
+
iteration: z.number(),
|
|
200
|
+
startedAt: z.string(),
|
|
201
|
+
endedAt: z.string().optional(),
|
|
202
|
+
changesSummary: z.string().optional(),
|
|
203
|
+
/** @deprecated kept for backward compatibility with pre-002 session files */
|
|
204
|
+
testsRun: z.array(z.string()).optional(),
|
|
205
|
+
// New fields for Feature 002
|
|
206
|
+
outcome: z
|
|
207
|
+
.enum(['tests-passing', 'tests-failing', 'error', 'scaffold'])
|
|
208
|
+
.optional()
|
|
209
|
+
.default('scaffold'),
|
|
210
|
+
filesChanged: z.array(z.string()).default([]),
|
|
211
|
+
testResults: testResultsSchema.optional(),
|
|
212
|
+
errorMessage: z.string().optional(),
|
|
213
|
+
llmPromptContext: z.string().optional(),
|
|
214
|
+
});
|
|
215
|
+
export type PocIteration = z.infer<typeof pocIterationSchema>;
|
|
216
|
+
|
|
217
|
+
// T006: Extended pocDevelopmentStateSchema
|
|
218
|
+
export const pocDevelopmentStateSchema = z.object({
|
|
219
|
+
repoPath: z.string().optional(),
|
|
220
|
+
repoUrl: z.string().optional(),
|
|
221
|
+
repoSource: z.enum(['local']), // Always local - users push manually to GitHub when ready
|
|
222
|
+
techStack: techStackSchema.optional(),
|
|
223
|
+
iterations: z.array(pocIterationSchema),
|
|
224
|
+
finalStatus: z.enum(['success', 'failed', 'partial']).optional(),
|
|
225
|
+
terminationReason: z
|
|
226
|
+
.enum(['tests-passing', 'max-iterations', 'user-stopped', 'error'])
|
|
227
|
+
.optional(),
|
|
228
|
+
totalDurationMs: z.number().optional(),
|
|
229
|
+
finalTestResults: testResultsSchema.optional(),
|
|
230
|
+
});
|
|
231
|
+
export type PocDevelopmentState = z.infer<typeof pocDevelopmentStateSchema>;
|
|
232
|
+
|
|
233
|
+
// ── Artifacts ────────────────────────────────────────────────────────────────
|
|
234
|
+
|
|
235
|
+
// ── Discovery Enrichment (Feature 003) ───────────────────────────────────────
|
|
236
|
+
|
|
237
|
+
export const DiscoveryEnrichmentSchema = z.object({
|
|
238
|
+
/** Raw web search summary text (combined from all queries) */
|
|
239
|
+
webSearchResults: z.string().optional(),
|
|
240
|
+
/** Recent news headlines/snippets about the company */
|
|
241
|
+
companyNews: z.array(z.string()).max(10).optional(),
|
|
242
|
+
/** Competitor activity summaries */
|
|
243
|
+
competitorInfo: z.array(z.string()).max(10).optional(),
|
|
244
|
+
/** Industry trend descriptions */
|
|
245
|
+
industryTrends: z.array(z.string()).max(10).optional(),
|
|
246
|
+
/** WorkIQ-derived team insights (only present if user consented) */
|
|
247
|
+
workiqInsights: z
|
|
248
|
+
.object({
|
|
249
|
+
/** Identified team skill areas */
|
|
250
|
+
teamExpertise: z.array(z.string()).max(10).optional(),
|
|
251
|
+
/** Meeting/communication patterns identified */
|
|
252
|
+
collaborationPatterns: z.array(z.string()).max(10).optional(),
|
|
253
|
+
/** Areas lacking internal documentation */
|
|
254
|
+
documentationGaps: z.array(z.string()).max(10).optional(),
|
|
255
|
+
})
|
|
256
|
+
.optional(),
|
|
257
|
+
/** ISO 8601 timestamp when enrichment was collected */
|
|
258
|
+
enrichedAt: z.string().datetime().optional(),
|
|
259
|
+
/** Which sources were queried ('websearch', 'workiq') */
|
|
260
|
+
sourcesUsed: z.array(z.string()).optional(),
|
|
261
|
+
});
|
|
262
|
+
export type DiscoveryEnrichment = z.infer<typeof DiscoveryEnrichmentSchema>;
|
|
263
|
+
|
|
264
|
+
export const DiscoveryStateSchema = z.object({
|
|
265
|
+
enrichment: DiscoveryEnrichmentSchema.optional(),
|
|
266
|
+
});
|
|
267
|
+
export type DiscoveryState = z.infer<typeof DiscoveryStateSchema>;
|
|
268
|
+
|
|
269
|
+
// ── Artifacts ────────────────────────────────────────────────────────────────
|
|
270
|
+
|
|
271
|
+
export const generatedFileSchema = z.object({
|
|
272
|
+
relativePath: z.string(),
|
|
273
|
+
type: z.enum(['markdown', 'json', 'text']),
|
|
274
|
+
createdAt: z.string(),
|
|
275
|
+
});
|
|
276
|
+
export type GeneratedFile = z.infer<typeof generatedFileSchema>;
|
|
277
|
+
|
|
278
|
+
export const artifactIndexSchema = z.object({
|
|
279
|
+
exportDir: z.string().optional(),
|
|
280
|
+
generatedFiles: z.array(generatedFileSchema),
|
|
281
|
+
});
|
|
282
|
+
export type ArtifactIndex = z.infer<typeof artifactIndexSchema>;
|
|
283
|
+
|
|
284
|
+
// ── Conversation Turn ────────────────────────────────────────────────────────
|
|
285
|
+
|
|
286
|
+
export const conversationTurnSchema = z.object({
|
|
287
|
+
phase: phaseSchema,
|
|
288
|
+
sequence: z.number(),
|
|
289
|
+
role: z.enum(['user', 'assistant', 'system']),
|
|
290
|
+
content: z.string(),
|
|
291
|
+
timestamp: z.string(),
|
|
292
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
293
|
+
});
|
|
294
|
+
export type ConversationTurn = z.infer<typeof conversationTurnSchema>;
|
|
295
|
+
|
|
296
|
+
// ── Error Record ─────────────────────────────────────────────────────────────
|
|
297
|
+
|
|
298
|
+
export const errorRecordSchema = z.object({
|
|
299
|
+
timestamp: z.string(),
|
|
300
|
+
code: z.string(),
|
|
301
|
+
message: z.string(),
|
|
302
|
+
details: z.record(z.string(), z.unknown()).optional(),
|
|
303
|
+
});
|
|
304
|
+
export type ErrorRecord = z.infer<typeof errorRecordSchema>;
|
|
305
|
+
|
|
306
|
+
// ── Activity (telemetry event) ───────────────────────────────────────────────
|
|
307
|
+
|
|
308
|
+
export const activitySchema = z.object({
|
|
309
|
+
id: z.string(),
|
|
310
|
+
timestamp: z.string(),
|
|
311
|
+
kind: z.enum(['phase', 'tool', 'io', 'warning', 'error', 'progress']),
|
|
312
|
+
message: z.string(),
|
|
313
|
+
data: z.record(z.string(), z.unknown()).optional(),
|
|
314
|
+
});
|
|
315
|
+
export type Activity = z.infer<typeof activitySchema>;
|
|
316
|
+
|
|
317
|
+
// ── Workshop Session (root) ──────────────────────────────────────────────────
|
|
318
|
+
|
|
319
|
+
export const workshopSessionSchema = z
|
|
320
|
+
.object({
|
|
321
|
+
sessionId: z.string(),
|
|
322
|
+
schemaVersion: z.string(),
|
|
323
|
+
createdAt: z.string(),
|
|
324
|
+
updatedAt: z.string(),
|
|
325
|
+
name: z.string().optional(),
|
|
326
|
+
phase: phaseSchema,
|
|
327
|
+
status: sessionStatusSchema,
|
|
328
|
+
participants: z.array(participantSchema),
|
|
329
|
+
businessContext: businessContextSchema.optional(),
|
|
330
|
+
topic: topicSelectionSchema.optional(),
|
|
331
|
+
activities: z.array(activitySchema).optional(),
|
|
332
|
+
workflow: workflowMapSchema.optional(),
|
|
333
|
+
cards: cardSelectionSchema.optional(),
|
|
334
|
+
ideas: z.array(ideaCardSchema).optional(),
|
|
335
|
+
evaluation: ideaEvaluationSchema.optional(),
|
|
336
|
+
selection: selectedIdeaSchema.optional(),
|
|
337
|
+
plan: implementationPlanSchema.optional(),
|
|
338
|
+
poc: pocDevelopmentStateSchema.optional(),
|
|
339
|
+
discovery: DiscoveryStateSchema.optional(),
|
|
340
|
+
artifacts: artifactIndexSchema,
|
|
341
|
+
turns: z.array(conversationTurnSchema).optional(),
|
|
342
|
+
errors: z.array(errorRecordSchema).optional(),
|
|
343
|
+
})
|
|
344
|
+
.passthrough(); // Forward compatibility: preserve unknown fields
|
|
345
|
+
|
|
346
|
+
export type WorkshopSession = z.infer<typeof workshopSessionSchema>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table rendering helper using cli-table3.
|
|
3
|
+
*/
|
|
4
|
+
import Table from 'cli-table3';
|
|
5
|
+
|
|
6
|
+
export interface TableOptions {
|
|
7
|
+
head?: string[];
|
|
8
|
+
rows: string[][];
|
|
9
|
+
colWidths?: number[];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Render a table as a string.
|
|
14
|
+
*/
|
|
15
|
+
export function renderTable(options: TableOptions): string {
|
|
16
|
+
const { head, rows, colWidths } = options;
|
|
17
|
+
|
|
18
|
+
const tableOpts: Table.TableConstructorOptions = {};
|
|
19
|
+
if (head) tableOpts.head = head;
|
|
20
|
+
if (colWidths) tableOpts.colWidths = colWidths;
|
|
21
|
+
|
|
22
|
+
const table = new Table(tableOpts);
|
|
23
|
+
for (const row of rows) {
|
|
24
|
+
table.push(row);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return table.toString();
|
|
28
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T041: E2E happy-path test for `sofia dev` command.
|
|
3
|
+
*
|
|
4
|
+
* Runs `sofia dev --session <fixtureId>` as a subprocess;
|
|
5
|
+
* verifies exit code 0; verifies output directory has required files;
|
|
6
|
+
* verifies session JSON updated with poc state.
|
|
7
|
+
*
|
|
8
|
+
* Note: This E2E test uses a fake CopilotClient (no real LLM calls).
|
|
9
|
+
* It validates the CLI plumbing, argument parsing, and file creation.
|
|
10
|
+
*/
|
|
11
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
12
|
+
import { mkdtemp, rm, readFile, writeFile, mkdir } from 'node:fs/promises';
|
|
13
|
+
import { join } from 'node:path';
|
|
14
|
+
import { tmpdir } from 'node:os';
|
|
15
|
+
import { createRequire } from 'node:module';
|
|
16
|
+
|
|
17
|
+
import { buildCli } from '../../src/cli/index.js';
|
|
18
|
+
import { validateSessionForDevelop } from '../../src/cli/developCommand.js';
|
|
19
|
+
import { PocScaffolder } from '../../src/develop/pocScaffolder.js';
|
|
20
|
+
import { validatePocOutput } from '../../src/develop/pocScaffolder.js';
|
|
21
|
+
import type { WorkshopSession } from '../../src/shared/schemas/session.js';
|
|
22
|
+
|
|
23
|
+
const require = createRequire(import.meta.url);
|
|
24
|
+
const fixtureSession: WorkshopSession = require('../fixtures/completedSession.json') as WorkshopSession;
|
|
25
|
+
|
|
26
|
+
describe('E2E: sofia dev command', () => {
|
|
27
|
+
let workDir: string;
|
|
28
|
+
|
|
29
|
+
beforeEach(async () => {
|
|
30
|
+
workDir = await mkdtemp(join(tmpdir(), 'sofia-e2e-dev-'));
|
|
31
|
+
// Create a .sofia/sessions dir for the session store
|
|
32
|
+
await mkdir(join(workDir, '.sofia', 'sessions'), { recursive: true });
|
|
33
|
+
// Write the fixture session
|
|
34
|
+
await writeFile(
|
|
35
|
+
join(workDir, '.sofia', 'sessions', `${fixtureSession.sessionId}.json`),
|
|
36
|
+
JSON.stringify(fixtureSession),
|
|
37
|
+
'utf-8',
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
afterEach(async () => {
|
|
42
|
+
await rm(workDir, { recursive: true, force: true });
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('CLI registers dev command with correct description', () => {
|
|
46
|
+
const program = buildCli();
|
|
47
|
+
const commands = program.commands.map((c) => c.name());
|
|
48
|
+
expect(commands).toContain('dev');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('dev command shows in help output', () => {
|
|
52
|
+
const program = buildCli();
|
|
53
|
+
const devCmd = program.commands.find((c) => c.name() === 'dev');
|
|
54
|
+
expect(devCmd).toBeDefined();
|
|
55
|
+
expect(devCmd?.description()).toContain('proof-of-concept');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('dev command has --max-iterations option', () => {
|
|
59
|
+
const program = buildCli();
|
|
60
|
+
const devCmd = program.commands.find((c) => c.name() === 'dev');
|
|
61
|
+
const options = devCmd?.options.map((o) => o.long);
|
|
62
|
+
expect(options).toContain('--max-iterations');
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
it('dev command has --output option', () => {
|
|
66
|
+
const program = buildCli();
|
|
67
|
+
const devCmd = program.commands.find((c) => c.name() === 'dev');
|
|
68
|
+
const options = devCmd?.options.map((o) => o.long);
|
|
69
|
+
expect(options).toContain('--output');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('dev command has --force option', () => {
|
|
73
|
+
const program = buildCli();
|
|
74
|
+
const devCmd = program.commands.find((c) => c.name() === 'dev');
|
|
75
|
+
const options = devCmd?.options.map((o) => o.long);
|
|
76
|
+
expect(options).toContain('--force');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe('validateSessionForDevelop (session readiness)', () => {
|
|
80
|
+
it('fixture session passes validation (has selection + plan)', () => {
|
|
81
|
+
const error = validateSessionForDevelop(fixtureSession);
|
|
82
|
+
expect(error).toBeNull();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('fixture session has a valid selection', () => {
|
|
86
|
+
expect(fixtureSession.selection).toBeDefined();
|
|
87
|
+
expect(fixtureSession.selection!.confirmedByUser).toBe(true);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it('fixture session has a valid plan with milestones', () => {
|
|
91
|
+
expect(fixtureSession.plan).toBeDefined();
|
|
92
|
+
expect(fixtureSession.plan!.milestones.length).toBeGreaterThan(0);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe('PocScaffolder with fixture session', () => {
|
|
97
|
+
let outputDir: string;
|
|
98
|
+
|
|
99
|
+
beforeEach(async () => {
|
|
100
|
+
outputDir = await mkdtemp(join(tmpdir(), 'sofia-e2e-poc-'));
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
afterEach(async () => {
|
|
104
|
+
await rm(outputDir, { recursive: true, force: true });
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('scaffolds valid PoC output from fixture session', async () => {
|
|
108
|
+
const scaffolder = new PocScaffolder();
|
|
109
|
+
const ctx = PocScaffolder.buildContext(fixtureSession, outputDir);
|
|
110
|
+
await scaffolder.scaffold(ctx);
|
|
111
|
+
|
|
112
|
+
const validation = await validatePocOutput(outputDir);
|
|
113
|
+
expect(validation.valid).toBe(true);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('generated package.json has correct project name from fixture', async () => {
|
|
117
|
+
const scaffolder = new PocScaffolder();
|
|
118
|
+
const ctx = PocScaffolder.buildContext(fixtureSession, outputDir);
|
|
119
|
+
await scaffolder.scaffold(ctx);
|
|
120
|
+
|
|
121
|
+
const pkgContent = await readFile(join(outputDir, 'package.json'), 'utf-8');
|
|
122
|
+
const pkg = JSON.parse(pkgContent) as { name: string };
|
|
123
|
+
expect(pkg.name).toBe('ai-powered-route-optimizer');
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
it('session JSON would be updated with poc state after loop', () => {
|
|
127
|
+
// Verify the shape of poc state that RalphLoop would produce
|
|
128
|
+
const expectedPocShape = {
|
|
129
|
+
repoSource: 'local',
|
|
130
|
+
iterations: expect.arrayContaining([
|
|
131
|
+
expect.objectContaining({
|
|
132
|
+
outcome: 'scaffold',
|
|
133
|
+
}),
|
|
134
|
+
]),
|
|
135
|
+
};
|
|
136
|
+
// This test verifies the schema is correct
|
|
137
|
+
const poc = {
|
|
138
|
+
repoSource: 'local' as const,
|
|
139
|
+
repoPath: outputDir,
|
|
140
|
+
iterations: [
|
|
141
|
+
{
|
|
142
|
+
iteration: 1,
|
|
143
|
+
startedAt: new Date().toISOString(),
|
|
144
|
+
outcome: 'scaffold' as const,
|
|
145
|
+
filesChanged: ['package.json', 'src/index.ts'],
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
};
|
|
149
|
+
expect(poc).toMatchObject(expectedPocShape);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
});
|