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,160 @@
|
|
|
1
|
+
# CLI Contracts: Dev Resume & Hardening
|
|
2
|
+
|
|
3
|
+
**Feature**: 004-dev-resume-hardening
|
|
4
|
+
**Date**: 2026-03-01
|
|
5
|
+
|
|
6
|
+
## `sofia dev` Command Contract
|
|
7
|
+
|
|
8
|
+
### Synopsis
|
|
9
|
+
|
|
10
|
+
```
|
|
11
|
+
sofia dev --session <id> [--force] [--max-iterations <n>] [--output-dir <path>] [--debug]
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### Resume Behavior (New)
|
|
15
|
+
|
|
16
|
+
| Session State | `--force` | Behavior |
|
|
17
|
+
| -------------------------------------------- | --------- | ---------------------------------------------- |
|
|
18
|
+
| `poc` undefined | N/A | Fresh run: scaffold → install → iterate from 1 |
|
|
19
|
+
| `poc.finalStatus` = `'success'` | `false` | Exit with "PoC already complete" message |
|
|
20
|
+
| `poc.finalStatus` = `'success'` | `true` | Reset poc → fresh run |
|
|
21
|
+
| `poc.finalStatus` = `'failed'`/`'partial'` | `false` | Resume from last iteration (default) |
|
|
22
|
+
| `poc.finalStatus` = `'failed'`/`'partial'` | `true` | Reset poc → fresh run |
|
|
23
|
+
| `poc.finalStatus` undefined + iterations > 0 | `false` | Resume from last completed iteration |
|
|
24
|
+
| `poc.finalStatus` undefined + iterations > 0 | `true` | Reset poc → fresh run |
|
|
25
|
+
|
|
26
|
+
### Exit Codes
|
|
27
|
+
|
|
28
|
+
| Code | Meaning |
|
|
29
|
+
| ---- | -------------------------------------------------------------- |
|
|
30
|
+
| `0` | PoC completed successfully (tests passing) or already complete |
|
|
31
|
+
| `0` | PoC resumed and completed |
|
|
32
|
+
| `1` | Error during execution |
|
|
33
|
+
| `0` | User interrupted (Ctrl+C) — session saved for resume |
|
|
34
|
+
|
|
35
|
+
### Info-Level Resume Logs (FR-007a)
|
|
36
|
+
|
|
37
|
+
All resume decisions produce info-level log messages (visible without `--debug`):
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
Resuming session abc123 from iteration 5 (4 completed iterations found)
|
|
41
|
+
Re-running incomplete iteration 4 (no test results recorded)
|
|
42
|
+
Skipping scaffold — output directory and .sofia-metadata.json present
|
|
43
|
+
Re-running dependency installation (npm install)
|
|
44
|
+
Selected template: node-ts-vitest (matched 'typescript' in architecture notes)
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### `--force` Reset Contract
|
|
48
|
+
|
|
49
|
+
When `--force` is specified:
|
|
50
|
+
|
|
51
|
+
1. Delete output directory (`rm -rf <outputDir>`)
|
|
52
|
+
2. Clear `session.poc` entirely (`session.poc = undefined`)
|
|
53
|
+
3. Persist session (`store.save(session)`)
|
|
54
|
+
4. Proceed with fresh scaffold → install → iterate from 1
|
|
55
|
+
|
|
56
|
+
**Post-condition**: `session.poc.iterations` is empty after first `updateSessionPoc` call.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Template Registry Contract
|
|
61
|
+
|
|
62
|
+
### Template Selection
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
// Input: plan's architectureNotes + dependencies
|
|
66
|
+
// Output: TemplateEntry
|
|
67
|
+
selectTemplate(registry, architectureNotes?, dependencies?): TemplateEntry
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Selection rules** (first match wins, case-insensitive):
|
|
71
|
+
|
|
72
|
+
1. Concatenate `architectureNotes` + `dependencies` into search text
|
|
73
|
+
2. For each registry entry (in registration order), check if any `matchPattern` appears in search text
|
|
74
|
+
3. If match found → return that entry
|
|
75
|
+
4. If no match → return `node-ts-vitest` (default)
|
|
76
|
+
|
|
77
|
+
### Registered Templates
|
|
78
|
+
|
|
79
|
+
#### `node-ts-vitest` (default)
|
|
80
|
+
|
|
81
|
+
| Field | Value |
|
|
82
|
+
| -------------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
83
|
+
| installCommand | `npm install` |
|
|
84
|
+
| testCommand | `npm test -- --reporter=json` |
|
|
85
|
+
| matchPatterns | `typescript`, `node`, `vitest`, `ts` |
|
|
86
|
+
| files | `.gitignore`, `package.json`, `tsconfig.json`, `README.md`, `src/index.ts`, `tests/index.test.ts`, `.sofia-metadata.json` |
|
|
87
|
+
|
|
88
|
+
#### `python-pytest`
|
|
89
|
+
|
|
90
|
+
| Field | Value |
|
|
91
|
+
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
92
|
+
| installCommand | `pip install -r requirements.txt` |
|
|
93
|
+
| testCommand | `pytest --tb=short -q --json-report --json-report-file=-` |
|
|
94
|
+
| matchPatterns | `python`, `fastapi`, `flask`, `django`, `pytest` |
|
|
95
|
+
| files | `.gitignore`, `requirements.txt`, `pytest.ini`, `README.md`, `src/__init__.py`, `src/main.py`, `tests/test_main.py`, `.sofia-metadata.json` |
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Workshop → Dev Transition Contract
|
|
100
|
+
|
|
101
|
+
### Plan Phase Completion Output
|
|
102
|
+
|
|
103
|
+
When the Plan phase completes in `sofia workshop`, the following message MUST be displayed:
|
|
104
|
+
|
|
105
|
+
```markdown
|
|
106
|
+
### Ready for PoC Generation
|
|
107
|
+
|
|
108
|
+
The Plan phase is complete. To generate the proof-of-concept, run:
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
sofia dev --session <actual-session-id>
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
This will scaffold a project matching your plan's technology stack, install dependencies,
|
|
116
|
+
and iteratively generate code until all tests pass.
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Interactive Mode Offer (FR-021, SHOULD)
|
|
120
|
+
|
|
121
|
+
In interactive mode, after the above message, the system SHOULD offer:
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
? Would you like to start PoC development now? (Y/n)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
- **Yes** (default): Invoke `developCommand` internally with the current session
|
|
128
|
+
- **No**: Save session and exit with the command displayed above
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## `.sofia-metadata.json` Extended Schema
|
|
133
|
+
|
|
134
|
+
```json
|
|
135
|
+
{
|
|
136
|
+
"sessionId": "string",
|
|
137
|
+
"featureSpec": "string",
|
|
138
|
+
"generatedAt": "ISO 8601 string",
|
|
139
|
+
"ideaTitle": "string",
|
|
140
|
+
"totalIterations": 0,
|
|
141
|
+
"finalStatus": "string | null",
|
|
142
|
+
"terminationReason": "string | null",
|
|
143
|
+
"techStack": {
|
|
144
|
+
"language": "string",
|
|
145
|
+
"runtime": "string",
|
|
146
|
+
"testRunner": "string"
|
|
147
|
+
},
|
|
148
|
+
"templateId": "string",
|
|
149
|
+
"todos": {
|
|
150
|
+
"totalInitial": 0,
|
|
151
|
+
"remaining": 0,
|
|
152
|
+
"markers": ["string"]
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
New fields:
|
|
158
|
+
|
|
159
|
+
- `templateId`: Which template was used (for resume context)
|
|
160
|
+
- `todos`: TODO marker tracking (FR-022)
|
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
# Data Model: Dev Resume & Hardening
|
|
2
|
+
|
|
3
|
+
**Feature**: 004-dev-resume-hardening
|
|
4
|
+
**Date**: 2026-03-01
|
|
5
|
+
|
|
6
|
+
## Entity Overview
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
┌──────────────────────┐ uses ┌──────────────────────┐
|
|
10
|
+
│ CheckpointState │◄─────────────│ developCommand.ts │
|
|
11
|
+
│ (runtime derived) │ │ (entry point) │
|
|
12
|
+
└──────────┬───────────┘ └──────────┬───────────┘
|
|
13
|
+
│ │
|
|
14
|
+
│ reads from │ passes to
|
|
15
|
+
▼ ▼
|
|
16
|
+
┌──────────────────────┐ ┌──────────────────────┐
|
|
17
|
+
│ PocDevelopmentState │◄──────────────│ RalphLoop │
|
|
18
|
+
│ (session.poc) │ updates │ (seeds iterations) │
|
|
19
|
+
│ [EXISTING SCHEMA] │ └──────────┬───────────┘
|
|
20
|
+
└──────────────────────┘ │
|
|
21
|
+
│ uses
|
|
22
|
+
▼
|
|
23
|
+
┌──────────────────────┐
|
|
24
|
+
│ TemplateRegistry │
|
|
25
|
+
│ (template lookup) │
|
|
26
|
+
└──────────┬───────────┘
|
|
27
|
+
│
|
|
28
|
+
│ contains
|
|
29
|
+
▼
|
|
30
|
+
┌──────────────────────┐
|
|
31
|
+
│ TemplateEntry │
|
|
32
|
+
│ (scaffold config) │
|
|
33
|
+
└──────────────────────┘
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Entity Definitions
|
|
37
|
+
|
|
38
|
+
### CheckpointState (New — runtime-only, not persisted)
|
|
39
|
+
|
|
40
|
+
Derived from existing `session.poc` to determine resume behavior. This is NOT a new schema — it's a convenience type used by `developCommand.ts` and `RalphLoop.run()` to make resume decisions.
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
export interface CheckpointState {
|
|
44
|
+
/** Whether a prior PoC run exists */
|
|
45
|
+
hasPriorRun: boolean;
|
|
46
|
+
/** Number of fully completed iterations (with testResults) */
|
|
47
|
+
completedIterations: number;
|
|
48
|
+
/** Whether the last iteration was interrupted (no testResults) */
|
|
49
|
+
lastIterationIncomplete: boolean;
|
|
50
|
+
/** The iteration number to resume from */
|
|
51
|
+
resumeFromIteration: number;
|
|
52
|
+
/** Whether scaffolding can be skipped (output dir + metadata exist) */
|
|
53
|
+
canSkipScaffold: boolean;
|
|
54
|
+
/** Final status from prior run, if any */
|
|
55
|
+
priorFinalStatus: 'success' | 'failed' | 'partial' | undefined;
|
|
56
|
+
/** Prior iterations for LLM context seeding */
|
|
57
|
+
priorIterations: PocIteration[];
|
|
58
|
+
}
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Derivation logic**:
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
function deriveCheckpointState(session: WorkshopSession, outputDir: string): CheckpointState {
|
|
65
|
+
const poc = session.poc;
|
|
66
|
+
if (!poc || poc.iterations.length === 0) {
|
|
67
|
+
return {
|
|
68
|
+
hasPriorRun: false,
|
|
69
|
+
completedIterations: 0,
|
|
70
|
+
lastIterationIncomplete: false,
|
|
71
|
+
resumeFromIteration: 1,
|
|
72
|
+
canSkipScaffold: false,
|
|
73
|
+
priorFinalStatus: undefined,
|
|
74
|
+
priorIterations: [],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const lastIter = poc.iterations[poc.iterations.length - 1];
|
|
79
|
+
const lastIncomplete = !lastIter.testResults && lastIter.outcome !== 'scaffold';
|
|
80
|
+
const completedIters = lastIncomplete ? poc.iterations.slice(0, -1) : poc.iterations;
|
|
81
|
+
|
|
82
|
+
const metadataExists = existsSync(join(outputDir, '.sofia-metadata.json'));
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
hasPriorRun: true,
|
|
86
|
+
completedIterations: completedIters.length,
|
|
87
|
+
lastIterationIncomplete: lastIncomplete,
|
|
88
|
+
resumeFromIteration: completedIters.length + 1,
|
|
89
|
+
canSkipScaffold: metadataExists,
|
|
90
|
+
priorFinalStatus: poc.finalStatus,
|
|
91
|
+
priorIterations: completedIters,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Validation rules**:
|
|
97
|
+
|
|
98
|
+
- `resumeFromIteration` >= 1
|
|
99
|
+
- `completedIterations` >= 0
|
|
100
|
+
- If `lastIterationIncomplete`, the incomplete iteration is excluded from `priorIterations`
|
|
101
|
+
- `canSkipScaffold` requires both output directory AND `.sofia-metadata.json` to exist
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
### TemplateEntry (New — code-defined)
|
|
106
|
+
|
|
107
|
+
A single scaffold template configuration. Registered in the `TemplateRegistry`.
|
|
108
|
+
|
|
109
|
+
```typescript
|
|
110
|
+
export interface TemplateEntry {
|
|
111
|
+
/** Unique template identifier */
|
|
112
|
+
id: string;
|
|
113
|
+
/** Human-readable name for logging */
|
|
114
|
+
displayName: string;
|
|
115
|
+
/** Scaffold file definitions */
|
|
116
|
+
files: TemplateFile[];
|
|
117
|
+
/** Technology stack for session state */
|
|
118
|
+
techStack: TechStack;
|
|
119
|
+
/** Command to install dependencies (e.g., 'npm install') */
|
|
120
|
+
installCommand: string;
|
|
121
|
+
/** Command to run tests with JSON output (e.g., 'npm test -- --reporter=json') */
|
|
122
|
+
testCommand: string;
|
|
123
|
+
/** Keywords to match from plan's architectureNotes/dependencies */
|
|
124
|
+
matchPatterns: string[];
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**Validation rules**:
|
|
129
|
+
|
|
130
|
+
- `id` must be unique within the registry
|
|
131
|
+
- `files` must include `.sofia-metadata.json`
|
|
132
|
+
- `installCommand` must be non-empty
|
|
133
|
+
- `testCommand` must be non-empty
|
|
134
|
+
- `matchPatterns` must contain at least one pattern (case-insensitive matching)
|
|
135
|
+
|
|
136
|
+
**Predefined entries**:
|
|
137
|
+
|
|
138
|
+
| id | displayName | matchPatterns | installCommand | testCommand |
|
|
139
|
+
| ---------------- | ----------------------------- | ---------------------------------------------------- | --------------------------------- | --------------------------------------------------------- |
|
|
140
|
+
| `node-ts-vitest` | TypeScript + Node.js + Vitest | `['typescript', 'node', 'vitest', 'ts']` | `npm install` | `npm test -- --reporter=json` |
|
|
141
|
+
| `python-pytest` | Python + pytest | `['python', 'fastapi', 'flask', 'django', 'pytest']` | `pip install -r requirements.txt` | `pytest --tb=short -q --json-report --json-report-file=-` |
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### TemplateRegistry (New — code-defined)
|
|
146
|
+
|
|
147
|
+
Registry type and selection function. Simple map + match-first-wins logic.
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
export type TemplateRegistry = Map<string, TemplateEntry>;
|
|
151
|
+
|
|
152
|
+
export function selectTemplate(
|
|
153
|
+
registry: TemplateRegistry,
|
|
154
|
+
architectureNotes?: string,
|
|
155
|
+
dependencies?: string[],
|
|
156
|
+
): TemplateEntry {
|
|
157
|
+
const searchText = [architectureNotes ?? '', ...(dependencies ?? [])].join(' ').toLowerCase();
|
|
158
|
+
|
|
159
|
+
for (const entry of registry.values()) {
|
|
160
|
+
if (entry.matchPatterns.some((p) => searchText.includes(p.toLowerCase()))) {
|
|
161
|
+
return entry;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Default fallback
|
|
166
|
+
return registry.get('node-ts-vitest')!;
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
### TestFixtureProject (New — test infrastructure)
|
|
173
|
+
|
|
174
|
+
A minimal project in `tests/fixtures/test-fixture-project/` used by testRunner integration tests. Not a runtime entity — exists only in the test suite.
|
|
175
|
+
|
|
176
|
+
```
|
|
177
|
+
tests/fixtures/test-fixture-project/
|
|
178
|
+
├── package.json # minimal: { "scripts": { "test": "vitest run --reporter=json" } }
|
|
179
|
+
├── vitest.config.ts # minimal config
|
|
180
|
+
├── src/
|
|
181
|
+
│ └── add.ts # function add(a, b) { return a + b; }
|
|
182
|
+
└── tests/
|
|
183
|
+
├── passing.test.ts # test('adds numbers', () => expect(add(1,2)).toBe(3))
|
|
184
|
+
├── failing.test.ts # test('fails', () => expect(1).toBe(2))
|
|
185
|
+
└── hanging.test.ts # test('hangs', async () => await new Promise(() => {}))
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
**Purpose**: Enables FR-016 through FR-019 (real subprocess testing of testRunner).
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
### SofiaMetadata (Extended — file-system artifact)
|
|
193
|
+
|
|
194
|
+
Current schema in `.sofia-metadata.json` (pocScaffolder.ts L243-L260), extended with TODO tracking.
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
interface SofiaMetadata {
|
|
198
|
+
sessionId: string;
|
|
199
|
+
featureSpec: string;
|
|
200
|
+
generatedAt: string;
|
|
201
|
+
ideaTitle: string;
|
|
202
|
+
totalIterations: number;
|
|
203
|
+
finalStatus: string | null;
|
|
204
|
+
terminationReason: string | null;
|
|
205
|
+
techStack: {
|
|
206
|
+
language: string;
|
|
207
|
+
runtime: string;
|
|
208
|
+
testRunner: string;
|
|
209
|
+
};
|
|
210
|
+
// NEW: FR-022 — scaffold TODO tracking
|
|
211
|
+
todos?: {
|
|
212
|
+
totalInitial: number;
|
|
213
|
+
remaining: number;
|
|
214
|
+
markers: string[]; // e.g., ["src/main.py:12: TODO: Implement business logic"]
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
## Existing Entities (Modified)
|
|
222
|
+
|
|
223
|
+
### TechStack (session.ts — schema extension)
|
|
224
|
+
|
|
225
|
+
The existing `techStackSchema` may need two optional fields for template-defined commands:
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
export const techStackSchema = z.object({
|
|
229
|
+
language: z.string(),
|
|
230
|
+
framework: z.string().optional(),
|
|
231
|
+
testRunner: z.string(),
|
|
232
|
+
buildCommand: z.string().optional(),
|
|
233
|
+
runtime: z.string(),
|
|
234
|
+
// Potential additions for Feature 004:
|
|
235
|
+
installCommand: z.string().optional(), // 'npm install' | 'pip install -r requirements.txt'
|
|
236
|
+
testCommand: z.string().optional(), // full test command with reporter flags
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**Note**: These fields could live solely on `TemplateEntry` rather than in the persisted session schema. If they're only needed at scaffold/runtime and not for resume, keeping them off the session avoids schema migration. Decision: keep `installCommand` and `testCommand` on `TemplateEntry` only. The existing `testRunner` field on `TechStack` (e.g., `'npm test'`) is sufficient for session display purposes.
|
|
241
|
+
|
|
242
|
+
### PocDevelopmentState (session.ts — no schema change)
|
|
243
|
+
|
|
244
|
+
The existing schema already supports everything needed for resume:
|
|
245
|
+
|
|
246
|
+
- `iterations: PocIteration[]` — seeded on resume
|
|
247
|
+
- `finalStatus?: 'success' | 'failed' | 'partial'` — undefined = resumable
|
|
248
|
+
- `terminationReason?` — read for status messages
|
|
249
|
+
- `techStack?` — preserved on resume
|
|
250
|
+
|
|
251
|
+
No schema migration required. The `.passthrough()` on `WorkshopSession` provides forward compatibility.
|
|
252
|
+
|
|
253
|
+
## State Transitions
|
|
254
|
+
|
|
255
|
+
### PoC Lifecycle States
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
┌──────────┐
|
|
259
|
+
first run │ No PoC │ session.poc = undefined
|
|
260
|
+
└────┬─────┘
|
|
261
|
+
│ sofia dev --session X
|
|
262
|
+
▼
|
|
263
|
+
┌──────────┐
|
|
264
|
+
│ Running │ finalStatus = undefined, iterations growing
|
|
265
|
+
└────┬─────┘
|
|
266
|
+
│
|
|
267
|
+
┌───────────┼───────────┐
|
|
268
|
+
▼ ▼ ▼
|
|
269
|
+
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
270
|
+
│ Success │ │ Partial │ │ Failed │
|
|
271
|
+
│ final= │ │ final= │ │ final= │
|
|
272
|
+
│'success' │ │'partial' │ │'failed' │
|
|
273
|
+
└──────────┘ └────┬─────┘ └────┬─────┘
|
|
274
|
+
│ │
|
|
275
|
+
▼ ▼
|
|
276
|
+
┌──────────┐ ┌──────────┐
|
|
277
|
+
resume │Resumable │ │Resumable │ resume
|
|
278
|
+
(FR-001/006) │ w/prior │ │ w/prior │ (FR-006)
|
|
279
|
+
└────┬─────┘ └────┬─────┘
|
|
280
|
+
│ │
|
|
281
|
+
▼ ▼
|
|
282
|
+
┌──────────┐
|
|
283
|
+
│ Running │ (loop continues from prior state)
|
|
284
|
+
└──────────┘
|
|
285
|
+
|
|
286
|
+
┌──────────────────────────┐
|
|
287
|
+
│ Interrupted (SIGINT) │ finalStatus = undefined
|
|
288
|
+
│ iterations.length > 0 │ (directly resumable via FR-001)
|
|
289
|
+
└──────────────────────────┘
|
|
290
|
+
|
|
291
|
+
Any state + --force → No PoC (FR-008/009/010)
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Resume Decision Tree
|
|
295
|
+
|
|
296
|
+
```
|
|
297
|
+
sofia dev --session X
|
|
298
|
+
│
|
|
299
|
+
├── session.poc undefined?
|
|
300
|
+
│ └── YES → Fresh run (scaffold + install + iterate from 1)
|
|
301
|
+
│
|
|
302
|
+
├── session.poc.finalStatus === 'success'?
|
|
303
|
+
│ └── YES → Display "PoC complete" message, exit (FR-005)
|
|
304
|
+
│
|
|
305
|
+
├── session.poc.finalStatus === 'failed' | 'partial'?
|
|
306
|
+
│ └── YES → Default to resume, allow --force override (FR-006)
|
|
307
|
+
│ └── Resume: seed iterations, start from N+1
|
|
308
|
+
│
|
|
309
|
+
├── session.poc.finalStatus undefined + iterations.length > 0?
|
|
310
|
+
│ └── YES → Resume (interrupted session) (FR-001)
|
|
311
|
+
│ ├── Last iteration has testResults?
|
|
312
|
+
│ │ └── YES → Start from iterations.length + 1
|
|
313
|
+
│ │ └── NO → Pop incomplete, start from iterations.length (FR-001a)
|
|
314
|
+
│ ├── Output dir exists + .sofia-metadata.json?
|
|
315
|
+
│ │ └── YES → Skip scaffold (FR-002)
|
|
316
|
+
│ │ └── NO → Re-scaffold (FR-007)
|
|
317
|
+
│ └── Always re-run npm install (FR-003)
|
|
318
|
+
│
|
|
319
|
+
└── --force flag set?
|
|
320
|
+
└── YES → Clear poc + delete dir → Fresh run (FR-008/009/010)
|
|
321
|
+
```
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Implementation Plan: Dev Resume & Hardening
|
|
2
|
+
|
|
3
|
+
**Branch**: `004-dev-resume-hardening` | **Date**: 2026-03-01 | **Spec**: [spec.md](spec.md)
|
|
4
|
+
**Input**: Feature specification from `/specs/004-dev-resume-hardening/spec.md`
|
|
5
|
+
|
|
6
|
+
## Summary
|
|
7
|
+
|
|
8
|
+
Harden the `sofia dev` command for production use by implementing resume/checkpoint support (seeding `RalphLoop.run()` from persisted `session.poc.iterations`), fixing `--force` to reset both output directory and session state, introducing a template registry for multi-language PoC scaffolding (starting with `python-pytest`), increasing `testRunner.ts` coverage from 45% to 80%+, and adding workshop→dev transition guidance. The core change is making `RalphLoop` read existing iteration state on startup instead of always starting from `iterations = []`.
|
|
9
|
+
|
|
10
|
+
## Technical Context
|
|
11
|
+
|
|
12
|
+
**Language/Version**: TypeScript (ES2022 target) on Node.js ≥ 20 LTS, ESM (`"type": "module"`)
|
|
13
|
+
**Primary Dependencies**: `@github/copilot-sdk` ^0.1.28, `commander` ^11.1.0, `zod` ^4.3.6, `pino` ^8.17.2, `ora` ^7.0.1, `chalk` ^5.2.0
|
|
14
|
+
**Storage**: Local JSON files via `SessionStore` (atomic write-then-rename to `.sofia/sessions/<id>.json`)
|
|
15
|
+
**Testing**: Vitest ^4.0.18 with `@vitest/coverage-v8`; `node-pty` ^1.0.0 for PTY E2E tests
|
|
16
|
+
**Target Platform**: Linux/macOS/Windows CLI (Node.js LTS)
|
|
17
|
+
**Project Type**: CLI application
|
|
18
|
+
**Performance Goals**: Resume detection adds <500ms overhead to `sofia dev` startup (SC-004-007)
|
|
19
|
+
**Constraints**: No breaking changes to session schema (`.passthrough()` ensures forward compatibility); template registry must be extensible without modifying core scaffolder/loop logic
|
|
20
|
+
**Scale/Scope**: ~936 lines in `ralphLoop.ts`, ~267 lines in `testRunner.ts`, ~444 lines in `pocScaffolder.ts`, ~267 lines in `developCommand.ts`; 48 existing test files (33 unit, 11 integration, 3 E2E, 1 live)
|
|
21
|
+
|
|
22
|
+
## Constitution Check
|
|
23
|
+
|
|
24
|
+
_GATE: Must pass before Phase 0 research. Re-check after Phase 1 design._
|
|
25
|
+
|
|
26
|
+
| Gate | Status | Evidence |
|
|
27
|
+
| ------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
28
|
+
| **Outcome-first discovery** | ✅ PASS | Resume/checkpoint directly addresses user-reported pain (lost iteration progress on interruption). SC-004-001 through SC-004-007 define measurable outcomes tied to facilitator productivity. |
|
|
29
|
+
| **Secure-by-default** | ✅ PASS | No new secrets, tokens, or PII handling. Resume reads existing session state from local files already governed by least-privilege. Info-level resume logs contain only iteration numbers and decision flags — no sensitive data. |
|
|
30
|
+
| **Node.js + TypeScript** | ✅ PASS | All implementation in TypeScript/Node.js using existing SDK patterns. Template registry extends current `PocScaffolder` without introducing new runtimes. |
|
|
31
|
+
| **MCP-first** | ✅ PASS | No new external integrations introduced. Template registry is code-defined (internal). Existing MCP connections (GitHub, Context7) remain unchanged. |
|
|
32
|
+
| **Test-first (NON-NEGOTIABLE)** | ✅ PASS | Spec mandates TDD via constitution. Every task phase starts with failing tests. US4 explicitly targets testRunner coverage from 45% → 80%+. |
|
|
33
|
+
| **CLI transparency** | ✅ PASS | FR-007a mandates info-level resume decision logging. FR-005/FR-006 require clear completion/status messages. FR-020 requires actionable next-step guidance with exact command. |
|
|
34
|
+
|
|
35
|
+
All gates pass. No exceptions required.
|
|
36
|
+
|
|
37
|
+
## Project Structure
|
|
38
|
+
|
|
39
|
+
### Documentation (this feature)
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
specs/004-dev-resume-hardening/
|
|
43
|
+
├── plan.md # This file
|
|
44
|
+
├── research.md # Phase 0 output
|
|
45
|
+
├── data-model.md # Phase 1 output
|
|
46
|
+
├── quickstart.md # Phase 1 output
|
|
47
|
+
├── contracts/ # Phase 1 output
|
|
48
|
+
└── tasks.md # Phase 2 output (created by /speckit.tasks)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Source Code (repository root)
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
src/
|
|
55
|
+
├── cli/
|
|
56
|
+
│ └── developCommand.ts # Modified: resume detection, --force session reset
|
|
57
|
+
├── develop/
|
|
58
|
+
│ ├── ralphLoop.ts # Modified: seed iterations from session, skip scaffold
|
|
59
|
+
│ ├── pocScaffolder.ts # Modified: extract template registry, add python-pytest
|
|
60
|
+
│ ├── templateRegistry.ts # New: template registry with selection logic
|
|
61
|
+
│ └── testRunner.ts # Unchanged (tests added, not code)
|
|
62
|
+
├── phases/
|
|
63
|
+
│ └── phaseHandlers.ts # Modified: Plan phase → dev transition guidance
|
|
64
|
+
├── sessions/
|
|
65
|
+
│ └── sessionManager.ts # Possibly modified: backtrack for --force poc reset
|
|
66
|
+
└── shared/
|
|
67
|
+
└── schemas/
|
|
68
|
+
└── session.ts # Possibly extended: TechStack install/test commands
|
|
69
|
+
|
|
70
|
+
tests/
|
|
71
|
+
├── unit/
|
|
72
|
+
│ ├── cli/
|
|
73
|
+
│ │ └── developCommand.spec.ts # Extended: resume + --force scenarios
|
|
74
|
+
│ └── develop/
|
|
75
|
+
│ ├── ralphLoop.spec.ts # Extended: resume iteration seeding
|
|
76
|
+
│ ├── pocScaffolder.spec.ts # Extended: template registry selection
|
|
77
|
+
│ └── templateRegistry.spec.ts # New: registry unit tests
|
|
78
|
+
├── integration/
|
|
79
|
+
│ ├── ralphLoopFlow.spec.ts # Extended: full resume flow
|
|
80
|
+
│ ├── ralphLoopPartial.spec.ts # Extended: partial resume scenarios
|
|
81
|
+
│ └── testRunnerReal.spec.ts # New: real fixture-based testRunner tests
|
|
82
|
+
├── e2e/
|
|
83
|
+
│ └── developPty.spec.ts # New: PTY-based interactive E2E
|
|
84
|
+
└── fixtures/
|
|
85
|
+
└── test-fixture-project/ # New: minimal Vitest project for testRunner tests
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Structure Decision**: Single project (Option 1) — consistent with existing repo layout. New files are limited to `templateRegistry.ts`, test files, and test fixture. All changes extend existing modules.
|
|
89
|
+
|
|
90
|
+
## Complexity Tracking
|
|
91
|
+
|
|
92
|
+
> No constitution violations. All gates pass.
|
|
93
|
+
|
|
94
|
+
## Post-Design Constitution Re-Check
|
|
95
|
+
|
|
96
|
+
_Re-evaluated after Phase 1 design artifacts (data-model.md, contracts/, quickstart.md)._
|
|
97
|
+
|
|
98
|
+
| Gate | Status | Post-Design Evidence |
|
|
99
|
+
| ------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
100
|
+
| **Outcome-first discovery** | ✅ PASS | CheckpointState derivation directly maps to resume UX outcomes. TemplateRegistry enables multi-language PoC — ties to broader workshop value. |
|
|
101
|
+
| **Secure-by-default** | ✅ PASS | No new data flows. CheckpointState is derived from existing session data. Template registry is code-defined, no external fetches. TODO tracking scans local files only. |
|
|
102
|
+
| **Node.js + TypeScript** | ✅ PASS | All new types (CheckpointState, TemplateEntry, TemplateRegistry) are TypeScript interfaces. No schema migration needed — existing Zod schemas support resume as-is. |
|
|
103
|
+
| **MCP-first** | ✅ PASS | No new external integrations. Feature is internal hardening. |
|
|
104
|
+
| **Test-first (NON-NEGOTIABLE)** | ✅ PASS | Quickstart outlines TDD workflow. TestFixtureProject entity provides real subprocess testing. Data model specifies testable derivation logic (deriveCheckpointState). |
|
|
105
|
+
| **CLI transparency** | ✅ PASS | Contracts define exact info-level log messages for every resume decision. Workshop→dev transition contract specifies exact command output. |
|
|
106
|
+
|
|
107
|
+
All gates pass post-design. No exceptions required.
|