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,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error classifier tests (T055).
|
|
3
|
+
*
|
|
4
|
+
* Validates centralized error classification and user-facing messages:
|
|
5
|
+
* - Maps known error codes to categories
|
|
6
|
+
* - Provides actionable messages
|
|
7
|
+
* - Handles unknown errors gracefully
|
|
8
|
+
* - Supports MCP, network, auth, and session errors
|
|
9
|
+
*/
|
|
10
|
+
import { describe, it, expect } from 'vitest';
|
|
11
|
+
import { classifyError, toUserMessage, } from '../../../src/shared/errorClassifier.js';
|
|
12
|
+
describe('errorClassifier', () => {
|
|
13
|
+
describe('classifyError', () => {
|
|
14
|
+
it('classifies ECONNREFUSED as connection error', () => {
|
|
15
|
+
const err = Object.assign(new Error('connect ECONNREFUSED'), { code: 'ECONNREFUSED' });
|
|
16
|
+
const result = classifyError(err);
|
|
17
|
+
expect(result.category).toBe('connection');
|
|
18
|
+
expect(result.recoverable).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
it('classifies ENOTFOUND as dns error', () => {
|
|
21
|
+
const err = Object.assign(new Error('getaddrinfo ENOTFOUND'), { code: 'ENOTFOUND' });
|
|
22
|
+
const result = classifyError(err);
|
|
23
|
+
expect(result.category).toBe('dns');
|
|
24
|
+
expect(result.recoverable).toBe(true);
|
|
25
|
+
});
|
|
26
|
+
it('classifies ETIMEDOUT as timeout error', () => {
|
|
27
|
+
const err = Object.assign(new Error('connect ETIMEDOUT'), { code: 'ETIMEDOUT' });
|
|
28
|
+
const result = classifyError(err);
|
|
29
|
+
expect(result.category).toBe('timeout');
|
|
30
|
+
expect(result.recoverable).toBe(true);
|
|
31
|
+
});
|
|
32
|
+
it('classifies 401 as auth error', () => {
|
|
33
|
+
const err = Object.assign(new Error('Unauthorized'), { statusCode: 401 });
|
|
34
|
+
const result = classifyError(err);
|
|
35
|
+
expect(result.category).toBe('auth');
|
|
36
|
+
expect(result.recoverable).toBe(false);
|
|
37
|
+
});
|
|
38
|
+
it('classifies 403 as auth error', () => {
|
|
39
|
+
const err = Object.assign(new Error('Forbidden'), { statusCode: 403 });
|
|
40
|
+
const result = classifyError(err);
|
|
41
|
+
expect(result.category).toBe('auth');
|
|
42
|
+
});
|
|
43
|
+
it('classifies 429 as rate-limit error', () => {
|
|
44
|
+
const err = Object.assign(new Error('Too Many Requests'), { statusCode: 429 });
|
|
45
|
+
const result = classifyError(err);
|
|
46
|
+
expect(result.category).toBe('rate-limit');
|
|
47
|
+
expect(result.recoverable).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
it('classifies ENOENT as not-found error', () => {
|
|
50
|
+
const err = Object.assign(new Error('ENOENT: no such file'), { code: 'ENOENT' });
|
|
51
|
+
const result = classifyError(err);
|
|
52
|
+
expect(result.category).toBe('not-found');
|
|
53
|
+
});
|
|
54
|
+
it('classifies session validation errors', () => {
|
|
55
|
+
const err = new Error('Invalid session: missing required field');
|
|
56
|
+
err.name = 'ZodError';
|
|
57
|
+
const result = classifyError(err);
|
|
58
|
+
expect(result.category).toBe('validation');
|
|
59
|
+
});
|
|
60
|
+
it('classifies unknown errors as internal', () => {
|
|
61
|
+
const err = new Error('Something unexpected happened');
|
|
62
|
+
const result = classifyError(err);
|
|
63
|
+
expect(result.category).toBe('internal');
|
|
64
|
+
expect(result.recoverable).toBe(false);
|
|
65
|
+
});
|
|
66
|
+
it('classifies MCP-related errors', () => {
|
|
67
|
+
const err = new Error('MCP server workiq failed to start');
|
|
68
|
+
const result = classifyError(err);
|
|
69
|
+
expect(result.category).toBe('mcp');
|
|
70
|
+
});
|
|
71
|
+
it('handles non-Error objects', () => {
|
|
72
|
+
const result = classifyError('string error');
|
|
73
|
+
expect(result.category).toBe('internal');
|
|
74
|
+
expect(result.originalError).toBe('string error');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
describe('toUserMessage', () => {
|
|
78
|
+
it('returns actionable message for connection errors', () => {
|
|
79
|
+
const classification = {
|
|
80
|
+
category: 'connection',
|
|
81
|
+
recoverable: true,
|
|
82
|
+
message: 'Connection refused',
|
|
83
|
+
originalError: new Error('ECONNREFUSED'),
|
|
84
|
+
};
|
|
85
|
+
const msg = toUserMessage(classification);
|
|
86
|
+
expect(msg).toContain('connection');
|
|
87
|
+
});
|
|
88
|
+
it('returns actionable message for auth errors', () => {
|
|
89
|
+
const classification = {
|
|
90
|
+
category: 'auth',
|
|
91
|
+
recoverable: false,
|
|
92
|
+
message: 'Unauthorized',
|
|
93
|
+
originalError: new Error('401'),
|
|
94
|
+
};
|
|
95
|
+
const msg = toUserMessage(classification);
|
|
96
|
+
expect(msg).toContain('auth');
|
|
97
|
+
});
|
|
98
|
+
it('returns actionable message for timeout errors', () => {
|
|
99
|
+
const classification = {
|
|
100
|
+
category: 'timeout',
|
|
101
|
+
recoverable: true,
|
|
102
|
+
message: 'Request timed out',
|
|
103
|
+
originalError: new Error('ETIMEDOUT'),
|
|
104
|
+
};
|
|
105
|
+
const msg = toUserMessage(classification);
|
|
106
|
+
expect(msg).toContain('timed out');
|
|
107
|
+
});
|
|
108
|
+
it('returns generic message for internal errors', () => {
|
|
109
|
+
const classification = {
|
|
110
|
+
category: 'internal',
|
|
111
|
+
recoverable: false,
|
|
112
|
+
message: 'Unexpected error',
|
|
113
|
+
originalError: new Error('kaboom'),
|
|
114
|
+
};
|
|
115
|
+
const msg = toUserMessage(classification);
|
|
116
|
+
expect(msg.length).toBeGreaterThan(0);
|
|
117
|
+
});
|
|
118
|
+
it('does not include stack traces', () => {
|
|
119
|
+
const err = new Error('test');
|
|
120
|
+
err.stack = 'Error: test\n at something.js:1:2';
|
|
121
|
+
const classification = {
|
|
122
|
+
category: 'internal',
|
|
123
|
+
recoverable: false,
|
|
124
|
+
message: 'test',
|
|
125
|
+
originalError: err,
|
|
126
|
+
};
|
|
127
|
+
const msg = toUserMessage(classification);
|
|
128
|
+
expect(msg).not.toContain('at something');
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
});
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for event model.
|
|
3
|
+
*/
|
|
4
|
+
import { describe, it, expect } from 'vitest';
|
|
5
|
+
import { createTextDeltaEvent, createActivityEvent, createToolCallEvent, createToolResultEvent, createPhaseChangedEvent, createErrorEvent, } from '../../../src/shared/events.js';
|
|
6
|
+
describe('event model', () => {
|
|
7
|
+
it('createTextDeltaEvent creates a valid event', () => {
|
|
8
|
+
const event = createTextDeltaEvent('Hello ');
|
|
9
|
+
expect(event.type).toBe('TextDelta');
|
|
10
|
+
expect(event.text).toBe('Hello ');
|
|
11
|
+
expect(event.timestamp).toBeTruthy();
|
|
12
|
+
});
|
|
13
|
+
it('createActivityEvent creates a valid event', () => {
|
|
14
|
+
const event = createActivityEvent('Connecting to MCP...');
|
|
15
|
+
expect(event.type).toBe('Activity');
|
|
16
|
+
expect(event.message).toBe('Connecting to MCP...');
|
|
17
|
+
});
|
|
18
|
+
it('createToolCallEvent includes tool name and args', () => {
|
|
19
|
+
const event = createToolCallEvent('web.search', { query: 'AI trends' });
|
|
20
|
+
expect(event.type).toBe('ToolCall');
|
|
21
|
+
expect(event.toolName).toBe('web.search');
|
|
22
|
+
expect(event.args).toEqual({ query: 'AI trends' });
|
|
23
|
+
});
|
|
24
|
+
it('createToolResultEvent includes tool name and result', () => {
|
|
25
|
+
const event = createToolResultEvent('web.search', { results: [] });
|
|
26
|
+
expect(event.type).toBe('ToolResult');
|
|
27
|
+
expect(event.toolName).toBe('web.search');
|
|
28
|
+
});
|
|
29
|
+
it('createPhaseChangedEvent includes old and new phase', () => {
|
|
30
|
+
const event = createPhaseChangedEvent('Discover', 'Ideate');
|
|
31
|
+
expect(event.type).toBe('PhaseChanged');
|
|
32
|
+
expect(event.fromPhase).toBe('Discover');
|
|
33
|
+
expect(event.toPhase).toBe('Ideate');
|
|
34
|
+
});
|
|
35
|
+
it('createErrorEvent includes code and message', () => {
|
|
36
|
+
const event = createErrorEvent('MCP_TIMEOUT', 'WorkIQ timed out');
|
|
37
|
+
expect(event.type).toBe('Error');
|
|
38
|
+
expect(event.code).toBe('MCP_TIMEOUT');
|
|
39
|
+
expect(event.message).toBe('WorkIQ timed out');
|
|
40
|
+
});
|
|
41
|
+
it('all events have a timestamp', () => {
|
|
42
|
+
const events = [
|
|
43
|
+
createTextDeltaEvent('x'),
|
|
44
|
+
createActivityEvent('y'),
|
|
45
|
+
createToolCallEvent('t', {}),
|
|
46
|
+
createToolResultEvent('t', {}),
|
|
47
|
+
createPhaseChangedEvent('Discover', 'Ideate'),
|
|
48
|
+
createErrorEvent('E', 'msg'),
|
|
49
|
+
];
|
|
50
|
+
for (const e of events) {
|
|
51
|
+
expect(e.timestamp).toBeTruthy();
|
|
52
|
+
expect(typeof e.timestamp).toBe('string');
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for markdown renderer.
|
|
3
|
+
*/
|
|
4
|
+
import { describe, it, expect } from 'vitest';
|
|
5
|
+
import { renderMarkdown } from '../../../src/shared/markdownRenderer.js';
|
|
6
|
+
describe('renderMarkdown', () => {
|
|
7
|
+
it('renders a heading', () => {
|
|
8
|
+
const output = renderMarkdown('# Hello World');
|
|
9
|
+
expect(output).toBeTruthy();
|
|
10
|
+
expect(output.length).toBeGreaterThan(0);
|
|
11
|
+
});
|
|
12
|
+
it('renders a list', () => {
|
|
13
|
+
const output = renderMarkdown('- One\n- Two\n- Three');
|
|
14
|
+
expect(output).toContain('One');
|
|
15
|
+
expect(output).toContain('Two');
|
|
16
|
+
});
|
|
17
|
+
it('renders a code block', () => {
|
|
18
|
+
const output = renderMarkdown('```json\n{"key": "value"}\n```');
|
|
19
|
+
expect(output).toContain('key');
|
|
20
|
+
});
|
|
21
|
+
it('returns plain text in non-TTY mode', () => {
|
|
22
|
+
const output = renderMarkdown('# Hello World', { isTTY: false });
|
|
23
|
+
// Should not contain ANSI codes in non-TTY mode
|
|
24
|
+
expect(output).toContain('Hello World');
|
|
25
|
+
});
|
|
26
|
+
it('handles empty string', () => {
|
|
27
|
+
const output = renderMarkdown('');
|
|
28
|
+
expect(output).toBe('');
|
|
29
|
+
});
|
|
30
|
+
it('handles raw Markdown preservation in non-TTY json mode', () => {
|
|
31
|
+
const output = renderMarkdown('# Title\n\nBody text', { isTTY: false, jsonMode: true });
|
|
32
|
+
// In json mode, return raw markdown
|
|
33
|
+
expect(output).toContain('# Title');
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for markdownRenderer handling of partial/incremental chunks (T081).
|
|
3
|
+
*
|
|
4
|
+
* Verifies that renderMarkdown doesn't crash on partial markdown input
|
|
5
|
+
* (split headings, incomplete bold, partial tables).
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect } from 'vitest';
|
|
8
|
+
import { renderMarkdown } from '../../../src/shared/markdownRenderer.js';
|
|
9
|
+
describe('renderMarkdown incremental chunk handling (T081)', () => {
|
|
10
|
+
it('handles a partial heading (no newline)', () => {
|
|
11
|
+
// During streaming, a heading might arrive without a trailing newline
|
|
12
|
+
const result = renderMarkdown('## Start of head', { isTTY: true });
|
|
13
|
+
expect(result).toBeTruthy();
|
|
14
|
+
expect(result).toContain('Start of head');
|
|
15
|
+
});
|
|
16
|
+
it('handles incomplete bold syntax', () => {
|
|
17
|
+
// Bold started but not closed
|
|
18
|
+
const result = renderMarkdown('Some **bold text without', { isTTY: true });
|
|
19
|
+
expect(result).toBeTruthy();
|
|
20
|
+
expect(result).toContain('bold text without');
|
|
21
|
+
});
|
|
22
|
+
it('handles incomplete code block', () => {
|
|
23
|
+
// Code block opened but not closed
|
|
24
|
+
const result = renderMarkdown('```typescript\nconst x = 1;\n', { isTTY: true });
|
|
25
|
+
expect(result).toBeTruthy();
|
|
26
|
+
expect(result).toContain('const x = 1');
|
|
27
|
+
});
|
|
28
|
+
it('handles partial table row', () => {
|
|
29
|
+
const result = renderMarkdown('| Column 1 | Column 2 |\n| ----', { isTTY: true });
|
|
30
|
+
expect(result).toBeTruthy();
|
|
31
|
+
});
|
|
32
|
+
it('handles empty chunk', () => {
|
|
33
|
+
const result = renderMarkdown('', { isTTY: true });
|
|
34
|
+
expect(result).toBe('');
|
|
35
|
+
});
|
|
36
|
+
it('handles single character chunk', () => {
|
|
37
|
+
const result = renderMarkdown('H', { isTTY: true });
|
|
38
|
+
expect(result).toBeTruthy();
|
|
39
|
+
});
|
|
40
|
+
it('handles newline-only chunk without throwing', () => {
|
|
41
|
+
const result = renderMarkdown('\n', { isTTY: true });
|
|
42
|
+
// A newline-only chunk may produce empty string; it must not throw
|
|
43
|
+
expect(typeof result).toBe('string');
|
|
44
|
+
});
|
|
45
|
+
it('handles incomplete link syntax', () => {
|
|
46
|
+
const result = renderMarkdown('Click [here](http://example', { isTTY: true });
|
|
47
|
+
expect(result).toBeTruthy();
|
|
48
|
+
});
|
|
49
|
+
it('handles partial list item', () => {
|
|
50
|
+
const result = renderMarkdown('- Item one\n- Item tw', { isTTY: true });
|
|
51
|
+
expect(result).toBeTruthy();
|
|
52
|
+
expect(result).toContain('Item one');
|
|
53
|
+
});
|
|
54
|
+
it('renders complete markdown correctly in TTY mode', () => {
|
|
55
|
+
const md = '## Title\n\n- **Bold item**\n- Regular item\n\n```js\nconst x = 1;\n```\n';
|
|
56
|
+
const result = renderMarkdown(md, { isTTY: true });
|
|
57
|
+
expect(result).toContain('Title');
|
|
58
|
+
expect(result).toContain('Bold item');
|
|
59
|
+
expect(result).toContain('Regular item');
|
|
60
|
+
});
|
|
61
|
+
it('returns raw markdown in JSON mode regardless of content', () => {
|
|
62
|
+
const md = '## Partial **heading';
|
|
63
|
+
const result = renderMarkdown(md, { isTTY: true, jsonMode: true });
|
|
64
|
+
expect(result).toBe(md);
|
|
65
|
+
});
|
|
66
|
+
it('handles non-TTY mode with partial markdown', () => {
|
|
67
|
+
const result = renderMarkdown('**incomplete bold', { isTTY: false });
|
|
68
|
+
expect(result).toBeTruthy();
|
|
69
|
+
});
|
|
70
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for table renderer.
|
|
3
|
+
*/
|
|
4
|
+
import { describe, it, expect } from 'vitest';
|
|
5
|
+
import { renderTable } from '../../../src/shared/tableRenderer.js';
|
|
6
|
+
describe('renderTable', () => {
|
|
7
|
+
it('renders a simple table', () => {
|
|
8
|
+
const output = renderTable({
|
|
9
|
+
head: ['Name', 'Score'],
|
|
10
|
+
rows: [
|
|
11
|
+
['Idea A', '85'],
|
|
12
|
+
['Idea B', '72'],
|
|
13
|
+
],
|
|
14
|
+
});
|
|
15
|
+
expect(output).toContain('Name');
|
|
16
|
+
expect(output).toContain('Score');
|
|
17
|
+
expect(output).toContain('Idea A');
|
|
18
|
+
expect(output).toContain('85');
|
|
19
|
+
});
|
|
20
|
+
it('handles empty rows', () => {
|
|
21
|
+
const output = renderTable({
|
|
22
|
+
head: ['Col1'],
|
|
23
|
+
rows: [],
|
|
24
|
+
});
|
|
25
|
+
expect(output).toContain('Col1');
|
|
26
|
+
});
|
|
27
|
+
it('renders without headers', () => {
|
|
28
|
+
const output = renderTable({
|
|
29
|
+
rows: [['a', 'b'], ['c', 'd']],
|
|
30
|
+
});
|
|
31
|
+
expect(output).toContain('a');
|
|
32
|
+
expect(output).toContain('d');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config';
|
|
2
|
+
export default defineConfig({
|
|
3
|
+
test: {
|
|
4
|
+
globals: true,
|
|
5
|
+
setupFiles: ['tests/setup/loadEnv.ts'],
|
|
6
|
+
include: ['tests/**/*.{test,spec}.ts'],
|
|
7
|
+
exclude: ['tests/live/**', 'tests/fixtures/**'],
|
|
8
|
+
coverage: {
|
|
9
|
+
enabled: true,
|
|
10
|
+
provider: 'v8',
|
|
11
|
+
},
|
|
12
|
+
testTimeout: 10_000, // Default timeout for tests (can be overridden per test)
|
|
13
|
+
},
|
|
14
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vitest config for live (slow) tests that hit the real Copilot SDK.
|
|
3
|
+
* Run with: npm run test:live
|
|
4
|
+
*/
|
|
5
|
+
import { defineConfig } from 'vitest/config';
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
test: {
|
|
8
|
+
globals: true,
|
|
9
|
+
setupFiles: ['tests/setup/loadEnv.ts'],
|
|
10
|
+
include: ['tests/live/**/*.{test,spec}.ts'],
|
|
11
|
+
testTimeout: 120_000,
|
|
12
|
+
hookTimeout: 60_000,
|
|
13
|
+
coverage: {
|
|
14
|
+
enabled: true,
|
|
15
|
+
provider: 'v8',
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
});
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# sofIA CLI Documentation
|
|
2
|
+
|
|
3
|
+
sofIA is an AI Discovery Workshop CLI that guides facilitators through the structured process of discovering, ideating, designing, selecting, and planning AI solutions for business needs.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [CLI Usage](./cli-usage.md) — Commands, flags, and examples
|
|
8
|
+
- [Session Model](./session-model.md) — Session lifecycle, phases, and persistence
|
|
9
|
+
- [Export Format](./export-format.md) — Exported artifacts and summary JSON structure
|
|
10
|
+
- [Environment Variables](./environment.md) — Configuration via environment
|
|
11
|
+
- [Architecture](./architecture.md) — Module overview and data flow
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Install dependencies
|
|
17
|
+
npm install
|
|
18
|
+
|
|
19
|
+
# Start an interactive workshop
|
|
20
|
+
npm run start -- workshop
|
|
21
|
+
|
|
22
|
+
# Check session status
|
|
23
|
+
npm run start -- status
|
|
24
|
+
|
|
25
|
+
# Generate a PoC from a completed session
|
|
26
|
+
npm run start -- dev --session <id>
|
|
27
|
+
|
|
28
|
+
# Export session artifacts
|
|
29
|
+
npm run start -- export --session <id>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
For the full specification, see:
|
|
33
|
+
|
|
34
|
+
- Workshop phases (Discover → Plan): [specs/001-cli-workshop-rebuild/](../specs/001-cli-workshop-rebuild/)
|
|
35
|
+
- PoC generation & Ralph loop (Develop): [specs/002-poc-generation/](../specs/002-poc-generation/)
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Architecture
|
|
2
|
+
|
|
3
|
+
## Module Overview
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
src/
|
|
7
|
+
├── cli/ # CLI entrypoints and command handlers
|
|
8
|
+
│ ├── index.ts # Main entrypoint (commander setup)
|
|
9
|
+
│ ├── workshopCommand.ts # Interactive workshop menu and flow
|
|
10
|
+
│ ├── developCommand.ts # `sofia dev` — PoC generation handler
|
|
11
|
+
│ ├── statusCommand.ts # Session status display
|
|
12
|
+
│ ├── exportCommand.ts # Artifact export handler
|
|
13
|
+
│ ├── directCommands.ts # Non-interactive direct command mode
|
|
14
|
+
│ ├── ioContext.ts # TTY/non-TTY detection, JSON mode, I/O
|
|
15
|
+
│ └── preflight.ts # Pre-flight environment checks
|
|
16
|
+
├── develop/ # PoC generation & Ralph loop
|
|
17
|
+
│ ├── index.ts # Barrel export
|
|
18
|
+
│ ├── ralphLoop.ts # Autonomous iteration orchestrator
|
|
19
|
+
│ ├── pocScaffolder.ts # PoC project scaffolding + output validation
|
|
20
|
+
│ ├── codeGenerator.ts # LLM-driven code generation & prompt building
|
|
21
|
+
│ ├── testRunner.ts # Test execution and result parsing
|
|
22
|
+
│ ├── mcpContextEnricher.ts# MCP-driven context enrichment (Context7, Azure, web search)
|
|
23
|
+
│ └── githubMcpAdapter.ts # GitHub MCP repo creation adapter
|
|
24
|
+
├── loop/
|
|
25
|
+
│ └── conversationLoop.ts # Multi-turn conversation orchestrator
|
|
26
|
+
├── phases/
|
|
27
|
+
│ ├── phaseHandlers.ts # Phase handler factory (one per phase)
|
|
28
|
+
│ └── phaseExtractors.ts # JSON block extraction + Zod validation
|
|
29
|
+
├── sessions/
|
|
30
|
+
│ ├── sessionStore.ts # Read/write session JSON files
|
|
31
|
+
│ ├── sessionManager.ts # Backtracking, phase transitions
|
|
32
|
+
│ ├── exportWriter.ts # Markdown + summary.json generation
|
|
33
|
+
│ └── exportPaths.ts # Export directory path resolution
|
|
34
|
+
├── mcp/
|
|
35
|
+
│ ├── mcpManager.ts # MCP server connection manager
|
|
36
|
+
│ └── webSearch.ts # Azure AI Foundry Bing Search tool
|
|
37
|
+
├── prompts/
|
|
38
|
+
│ └── promptLoader.ts # Cached prompt template composition
|
|
39
|
+
├── logging/
|
|
40
|
+
│ └── logger.ts # Pino logger with PII redaction
|
|
41
|
+
├── shared/
|
|
42
|
+
│ ├── schemas/
|
|
43
|
+
│ │ └── session.ts # Zod schemas for all session entities
|
|
44
|
+
│ ├── copilotClient.ts # Copilot SDK abstraction + test fakes
|
|
45
|
+
│ ├── errorClassifier.ts # Error categorization (9 types)
|
|
46
|
+
│ ├── events.ts # Activity/telemetry event model
|
|
47
|
+
│ ├── markdownRenderer.ts # marked + marked-terminal rendering
|
|
48
|
+
│ ├── tableRenderer.ts # cli-table3 wrapper
|
|
49
|
+
│ └── data/
|
|
50
|
+
│ ├── cards.json # AI Envisioning Cards dataset
|
|
51
|
+
│ └── cardsLoader.ts # Cards dataset loader
|
|
52
|
+
└── vendor/
|
|
53
|
+
└── zod.ts # Re-export of zod/v4
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Data Flow
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
User Input
|
|
60
|
+
│
|
|
61
|
+
▼
|
|
62
|
+
┌─────────────────┐ ┌──────────────────┐
|
|
63
|
+
│ CLI Commands │────▶│ workshopCommand │
|
|
64
|
+
│ (index.ts) │ │ statusCommand │
|
|
65
|
+
│ │ │ exportCommand │
|
|
66
|
+
│ │ │ directCommands │
|
|
67
|
+
└─────────────────┘ └────────┬─────────┘
|
|
68
|
+
│
|
|
69
|
+
┌────────────▼───────────┐
|
|
70
|
+
│ ConversationLoop │
|
|
71
|
+
│ (multi-turn chat) │
|
|
72
|
+
└────────────┬───────────┘
|
|
73
|
+
│
|
|
74
|
+
┌──────────────────┼──────────────────┐
|
|
75
|
+
▼ ▼ ▼
|
|
76
|
+
┌────────────────┐ ┌──────────────┐ ┌──────────────────┐
|
|
77
|
+
│ PhaseHandlers │ │ CopilotClient│ │ SessionStore │
|
|
78
|
+
│ (per-phase │ │ (SDK or fake)│ │ (JSON persist) │
|
|
79
|
+
│ logic) │ └──────────────┘ └──────────────────┘
|
|
80
|
+
└────────┬───────┘
|
|
81
|
+
│
|
|
82
|
+
┌──────┴──────┐
|
|
83
|
+
▼ ▼
|
|
84
|
+
┌──────────────┐ ┌─────────────────┐
|
|
85
|
+
│ promptLoader │ │ phaseExtractors │
|
|
86
|
+
│ (templates) │ │ (Zod parse) │
|
|
87
|
+
└──────────────┘ └─────────────────┘
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Key Design Patterns
|
|
91
|
+
|
|
92
|
+
### PhaseHandler Interface
|
|
93
|
+
|
|
94
|
+
Each workshop phase implements the `PhaseHandler` interface:
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
interface PhaseHandler {
|
|
98
|
+
phase: PhaseValue;
|
|
99
|
+
buildSystemPrompt(session: WorkshopSession): string;
|
|
100
|
+
getReferences(session: WorkshopSession): Reference[];
|
|
101
|
+
extractResult(text: string): unknown;
|
|
102
|
+
isComplete(session: WorkshopSession): boolean;
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### ConversationLoop
|
|
107
|
+
|
|
108
|
+
The `ConversationLoop` orchestrates multi-turn conversations between the user, the Copilot client, and the active `PhaseHandler`. It handles:
|
|
109
|
+
|
|
110
|
+
- Streaming responses with real-time rendering
|
|
111
|
+
- Activity/telemetry event emission
|
|
112
|
+
- Ctrl+C signal handling for graceful shutdown
|
|
113
|
+
- Session persistence after every turn
|
|
114
|
+
|
|
115
|
+
### LoopIO Interface
|
|
116
|
+
|
|
117
|
+
I/O is abstracted behind `LoopIO` for testability:
|
|
118
|
+
|
|
119
|
+
- **TTY mode:** Interactive prompts via terminal
|
|
120
|
+
- **Non-TTY mode:** Reads from stdin, writes JSON to stdout
|
|
121
|
+
- **JSON mode:** Activity events go to stderr, structured data to stdout
|
|
122
|
+
|
|
123
|
+
### Error Classification
|
|
124
|
+
|
|
125
|
+
Errors are classified into 9 categories with recovery hints:
|
|
126
|
+
|
|
127
|
+
| Category | Recoverable | Example |
|
|
128
|
+
| ------------ | ----------- | --------------------- |
|
|
129
|
+
| `connection` | Yes | Network unreachable |
|
|
130
|
+
| `dns` | Yes | DNS resolution failed |
|
|
131
|
+
| `timeout` | Yes | Request timed out |
|
|
132
|
+
| `auth` | No | Invalid credentials |
|
|
133
|
+
| `rate-limit` | Yes | Too many requests |
|
|
134
|
+
| `not-found` | No | Resource not found |
|
|
135
|
+
| `validation` | No | Invalid input |
|
|
136
|
+
| `mcp` | Yes | MCP server down |
|
|
137
|
+
| `internal` | No | Unexpected error |
|
|
138
|
+
|
|
139
|
+
### Pre-flight Checks
|
|
140
|
+
|
|
141
|
+
Before starting a workshop, `runPreflightChecks()` runs environment validations in parallel:
|
|
142
|
+
|
|
143
|
+
- Copilot SDK connectivity
|
|
144
|
+
- MCP server readiness
|
|
145
|
+
- Web search tool availability
|
|
146
|
+
|
|
147
|
+
Each check reports pass/warn/fail with a message. Required checks block startup; optional checks emit warnings.
|
|
148
|
+
|
|
149
|
+
## Testing Architecture
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
tests/
|
|
153
|
+
├── unit/ # Single-module tests with mocks
|
|
154
|
+
├── integration/ # Multi-module flow tests
|
|
155
|
+
└── e2e/ # PTY-based interactive tests
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
- **Test runner:** Vitest with v8 coverage
|
|
159
|
+
- **Mocking:** `vi.mock()` at module boundaries
|
|
160
|
+
- **Fakes:** `createFakeCopilotClient()` for deterministic chat responses
|
|
161
|
+
- **TDD workflow:** Red → Green → Review for all new behavior
|
|
162
|
+
|
|
163
|
+
## Related
|
|
164
|
+
|
|
165
|
+
- Feature 001 spec: [specs/001-cli-workshop-rebuild/spec.md](../specs/001-cli-workshop-rebuild/spec.md)
|
|
166
|
+
- Feature 001 plan: [specs/001-cli-workshop-rebuild/plan.md](../specs/001-cli-workshop-rebuild/plan.md)
|
|
167
|
+
- Feature 002 spec: [specs/002-poc-generation/spec.md](../specs/002-poc-generation/spec.md)
|
|
168
|
+
- Feature 002 plan: [specs/002-poc-generation/plan.md](../specs/002-poc-generation/plan.md)
|
|
169
|
+
- Research notes: [specs/001-cli-workshop-rebuild/research.md](../specs/001-cli-workshop-rebuild/research.md)
|