scaffold-ca-python 0.1.2__tar.gz → 0.1.3__tar.gz
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.
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/agents/copilot-instructions.md +7 -5
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.pre-commit-config.yaml +5 -0
- scaffold_ca_python-0.1.3/.release-please-manifest.json +3 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.specify/memory/constitution.md +1 -1
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/CHANGELOG.md +7 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/PKG-INFO +6 -6
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/README.md +5 -5
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/015-factory-builder-refactor/tasks.md +11 -11
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/019-mcp-entry-point-restructure/plan.md +2 -2
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/factory/fixtures/dry_run_baseline.json +9 -2
- scaffold_ca_python-0.1.3/tests/factory/test_dry_run_parity.py +96 -0
- scaffold_ca_python-0.1.3/tests/factory/test_extensibility.py +46 -0
- scaffold_ca_python-0.1.3/tests/factory/test_registry.py +54 -0
- scaffold_ca_python-0.1.3/tests/templates/__init__.py +0 -0
- scaffold_ca_python-0.1.2/.release-please-manifest.json +0 -3
- scaffold_ca_python-0.1.2/specs/010-fix-restapi-cleanup/checklists/requirements.md +0 -34
- scaffold_ca_python-0.1.2/specs/010-fix-restapi-cleanup/spec.md +0 -76
- scaffold_ca_python-0.1.2/specs/013-tests-in-src/spec.md +0 -128
- scaffold_ca_python-0.1.2/specs/018-mcp-entry-point-restructure/checklists/requirements.md +0 -37
- scaffold_ca_python-0.1.2/specs/019-mcp-entry-point-restructure/spec.md +0 -128
- scaffold_ca_python-0.1.2/src/scaffold_ca_python/__init__.py +0 -1
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/agents/speckit.analyze.agent.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/agents/speckit.checklist.agent.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/agents/speckit.clarify.agent.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/agents/speckit.constitution.agent.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/agents/speckit.implement.agent.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/agents/speckit.plan.agent.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/agents/speckit.specify.agent.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/agents/speckit.tasks.agent.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/agents/speckit.taskstoissues.agent.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/issue_template.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/prompts/speckit.analyze.prompt.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/prompts/speckit.checklist.prompt.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/prompts/speckit.clarify.prompt.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/prompts/speckit.constitution.prompt.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/prompts/speckit.implement.prompt.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/prompts/speckit.plan.prompt.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/prompts/speckit.specify.prompt.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/prompts/speckit.tasks.prompt.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/prompts/speckit.taskstoissues.prompt.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/pull_request_template.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/workflows/build.yml +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/workflows/dependency-review.yml +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/workflows/publish.yml +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/workflows/release-please.yml +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/workflows/scorecards-analysis.yml +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/workflows/secret-scanner.yml +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.gitignore +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.python-version +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.specify/init-options.json +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.specify/scripts/bash/check-prerequisites.sh +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.specify/scripts/bash/common.sh +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.specify/scripts/bash/create-new-feature.sh +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.specify/scripts/bash/setup-plan.sh +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.specify/scripts/bash/update-agent-context.sh +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.specify/templates/agent-file-template.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.specify/templates/checklist-template.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.specify/templates/constitution-template.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.specify/templates/plan-template.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.specify/templates/spec-template.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.specify/templates/tasks-template.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/LICENSE +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/SECURITY.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/pyproject.toml +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/release-please-config.json +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/004-scaffold-ca-python-cli/checklists/requirements.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/004-scaffold-ca-python-cli/contracts/ca.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/004-scaffold-ca-python-cli/contracts/dm.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/004-scaffold-ca-python-cli/contracts/gda.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/004-scaffold-ca-python-cli/contracts/gep.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/004-scaffold-ca-python-cli/contracts/gh.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/004-scaffold-ca-python-cli/contracts/gm.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/004-scaffold-ca-python-cli/contracts/gpipe.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/004-scaffold-ca-python-cli/contracts/guc.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/004-scaffold-ca-python-cli/contracts/up.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/004-scaffold-ca-python-cli/contracts/vs.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/004-scaffold-ca-python-cli/data-model.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/004-scaffold-ca-python-cli/plan.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/004-scaffold-ca-python-cli/quickstart.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/004-scaffold-ca-python-cli/research.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/004-scaffold-ca-python-cli/spec.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/004-scaffold-ca-python-cli/tasks.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/006-ca-scaffold-enhancements/checklists/requirements.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/006-ca-scaffold-enhancements/plan.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/006-ca-scaffold-enhancements/spec.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/006-ca-scaffold-enhancements/tasks.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/007-cli-usability-enhancements/checklists/requirements.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/007-cli-usability-enhancements/contracts/clean-architecture.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/007-cli-usability-enhancements/contracts/gda.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/007-cli-usability-enhancements/contracts/gep.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/007-cli-usability-enhancements/contracts/gpipe.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/007-cli-usability-enhancements/data-model.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/007-cli-usability-enhancements/plan.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/007-cli-usability-enhancements/quickstart.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/007-cli-usability-enhancements/research.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/007-cli-usability-enhancements/spec.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/007-cli-usability-enhancements/tasks.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/008-fastapi-entrypoint-baseline/checklists/requirements.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/008-fastapi-entrypoint-baseline/contracts/gep.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/008-fastapi-entrypoint-baseline/data-model.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/008-fastapi-entrypoint-baseline/plan.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/008-fastapi-entrypoint-baseline/quickstart.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/008-fastapi-entrypoint-baseline/research.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/008-fastapi-entrypoint-baseline/spec.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/008-fastapi-entrypoint-baseline/tasks.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/009-app-factory-split/checklists/requirements.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/009-app-factory-split/contracts/gep-restapi.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/009-app-factory-split/data-model.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/009-app-factory-split/plan.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/009-app-factory-split/quickstart.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/009-app-factory-split/research.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/009-app-factory-split/spec.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/009-app-factory-split/tasks.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/011-fix-restapi-cleanup/data-model.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/011-fix-restapi-cleanup/plan.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/011-fix-restapi-cleanup/quickstart.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/011-fix-restapi-cleanup/research.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/011-fix-restapi-cleanup/spec.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/011-fix-restapi-cleanup/tasks.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/012-fix-restapi-test-templates/checklists/requirements.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/012-fix-restapi-test-templates/data-model.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/012-fix-restapi-test-templates/plan.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/012-fix-restapi-test-templates/quickstart.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/012-fix-restapi-test-templates/research.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/012-fix-restapi-test-templates/spec.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/012-fix-restapi-test-templates/tasks.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/014-tests-in-src/checklists/requirements.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/014-tests-in-src/data-model.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/014-tests-in-src/plan.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/014-tests-in-src/quickstart.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/014-tests-in-src/research.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/014-tests-in-src/spec.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/014-tests-in-src/tasks.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/015-factory-builder-refactor/checklists/requirements.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/015-factory-builder-refactor/data-model.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/015-factory-builder-refactor/plan.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/015-factory-builder-refactor/quickstart.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/015-factory-builder-refactor/research.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/015-factory-builder-refactor/spec.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/016-dedup-command-aliases/checklists/requirements.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/016-dedup-command-aliases/data-model.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/016-dedup-command-aliases/plan.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/016-dedup-command-aliases/research.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/016-dedup-command-aliases/spec.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/016-dedup-command-aliases/tasks.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/017-pep8-naming-validation/checklists/requirements.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/017-pep8-naming-validation/contracts/name-validation.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/017-pep8-naming-validation/data-model.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/017-pep8-naming-validation/plan.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/017-pep8-naming-validation/research.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/017-pep8-naming-validation/spec.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/017-pep8-naming-validation/tasks.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/019-mcp-entry-point-restructure/contracts/gep-mcp.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/019-mcp-entry-point-restructure/data-model.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/019-mcp-entry-point-restructure/research.md +0 -0
- {scaffold_ca_python-0.1.2/specs/018-mcp-entry-point-restructure → scaffold_ca_python-0.1.3/specs/019-mcp-entry-point-restructure}/spec.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/019-mcp-entry-point-restructure/tasks.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/020-pypi-publish-readme/checklists/requirements.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/020-pypi-publish-readme/contracts/readme-outline.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/020-pypi-publish-readme/data-model.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/020-pypi-publish-readme/plan.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/020-pypi-publish-readme/quickstart.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/020-pypi-publish-readme/research.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/020-pypi-publish-readme/spec.md +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/020-pypi-publish-readme/tasks.md +0 -0
- {scaffold_ca_python-0.1.2/src/scaffold_ca_python/commands → scaffold_ca_python-0.1.3/src/scaffold_ca_python}/__init__.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/cli.py +0 -0
- {scaffold_ca_python-0.1.2/src/scaffold_ca_python/core → scaffold_ca_python-0.1.3/src/scaffold_ca_python/commands}/__init__.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/commands/delete_module.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/commands/generate_driven_adapter.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/commands/generate_entry_point.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/commands/generate_helper.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/commands/generate_model.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/commands/generate_pipeline.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/commands/generate_project.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/commands/generate_use_case.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/commands/update_project.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/commands/validate_structure.py +0 -0
- {scaffold_ca_python-0.1.2/src/scaffold_ca_python/factory/driven_adapters → scaffold_ca_python-0.1.3/src/scaffold_ca_python/core}/__init__.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/core/file_writer.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/core/module_builder.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/core/name_utils.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/core/project_detector.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/core/pyproject_writer.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/core/structure_validator.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/core/template_renderer.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/factory/__init__.py +0 -0
- {scaffold_ca_python-0.1.2/src/scaffold_ca_python/factory/entry_points → scaffold_ca_python-0.1.3/src/scaffold_ca_python/factory/driven_adapters}/__init__.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/factory/driven_adapters/da_generic.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/factory/driven_adapters/da_rest_consumer.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/factory/driven_adapters/da_secrets.py +0 -0
- {scaffold_ca_python-0.1.2/src/scaffold_ca_python/factory/simple → scaffold_ca_python-0.1.3/src/scaffold_ca_python/factory/entry_points}/__init__.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/factory/entry_points/ep_agent.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/factory/entry_points/ep_generic.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/factory/entry_points/ep_mcp.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/factory/entry_points/ep_restapi.py +0 -0
- {scaffold_ca_python-0.1.2/src/scaffold_ca_python/models → scaffold_ca_python-0.1.3/src/scaffold_ca_python/factory/simple}/__init__.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/factory/simple/delete_module_factory.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/factory/simple/helper_factory.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/factory/simple/model_factory.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/factory/simple/use_case_factory.py +0 -0
- {scaffold_ca_python-0.1.2/src/scaffold_ca_python/templates → scaffold_ca_python-0.1.3/src/scaffold_ca_python/models}/__init__.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/models/context.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/models/file_operation.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/models/layer.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/models/violation.py +0 -0
- {scaffold_ca_python-0.1.2/tests → scaffold_ca_python-0.1.3/src/scaffold_ca_python/templates}/__init__.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/driven_adapter/generic/__init__.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/driven_adapter/generic/adapter.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/driven_adapter/generic/test_adapter.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/driven_adapter/rest_consumer/__init__.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/driven_adapter/rest_consumer/rest_consumer.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/driven_adapter/rest_consumer/test_rest_consumer.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/driven_adapter/secrets/__init__.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/driven_adapter/secrets/secrets_adapter.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/driven_adapter/secrets/test_secrets_adapter.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/agent/__init__.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/agent/agent.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/agent/card.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/agent/entrypoint_main.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/agent/test_agent.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/generic/__init__.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/generic/entrypoint_main.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/generic/handler.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/generic/test_handler.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/mcp/__init__.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/mcp/app.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/mcp/prompts.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/mcp/resources.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/mcp/server.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/mcp/test_app.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/mcp/test_prompts.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/mcp/test_resources.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/mcp/test_tools.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/mcp/tools.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/restapi/__init__.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/restapi/app.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/restapi/exception_handler.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/restapi/health.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/restapi/rest_controller.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/restapi/server.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/restapi/test_app.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/restapi/test_exception_handler.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/restapi/test_rest_controller.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/entry_point/restapi/test_server.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/helper/__init__.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/helper/helper.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/helper/test_helper.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/model/model.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/model/test_model.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/pipeline/azure/azure_pipelines.yml.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/pipeline/github/ci.yml.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/project/README.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/project/application/config/__init__.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/project/application/config/config.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/project/application/config/container.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/project/application/config/driven_adapters_container.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/project/application/config/resource_container.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/project/application/config/usecases_container.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/project/dockerfile.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/project/dockerignore.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/project/gitignore.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/project/layer_init.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/project/main.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/project/mypy_ini.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/project/pyproject_toml.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/project/python_version.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/use_case/test_use_case.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/src/scaffold_ca_python/templates/use_case/use_case.py.jinja2 +0 -0
- {scaffold_ca_python-0.1.2/tests/commands → scaffold_ca_python-0.1.3/tests}/__init__.py +0 -0
- {scaffold_ca_python-0.1.2/tests/core → scaffold_ca_python-0.1.3/tests/commands}/__init__.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/commands/test_cli.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/commands/test_delete_module.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/commands/test_dry_run_checksum.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/commands/test_generate_driven_adapter.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/commands/test_generate_entry_point.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/commands/test_generate_helper.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/commands/test_generate_model.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/commands/test_generate_pipeline.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/commands/test_generate_project.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/commands/test_generate_use_case.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/commands/test_performance.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/commands/test_update_project.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/commands/test_validate_structure.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/commands/test_workflow.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/conftest.py +0 -0
- {scaffold_ca_python-0.1.2/tests/factory → scaffold_ca_python-0.1.3/tests/core}/__init__.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/core/test_file_writer.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/core/test_name_utils.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/core/test_project_detector.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/core/test_pyproject_writer.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/core/test_structure_validator.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/core/test_template_renderer.py +0 -0
- {scaffold_ca_python-0.1.2/tests/factory/driven_adapters → scaffold_ca_python-0.1.3/tests/factory}/__init__.py +0 -0
- {scaffold_ca_python-0.1.2/tests/factory/entry_points → scaffold_ca_python-0.1.3/tests/factory/driven_adapters}/__init__.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/factory/driven_adapters/test_da_generic.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/factory/driven_adapters/test_da_rest_consumer.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/factory/driven_adapters/test_da_secrets.py +0 -0
- {scaffold_ca_python-0.1.2/tests/factory/simple → scaffold_ca_python-0.1.3/tests/factory/entry_points}/__init__.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/factory/entry_points/test_ep_agent.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/factory/entry_points/test_ep_generic.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/factory/entry_points/test_ep_mcp.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/factory/entry_points/test_ep_restapi.py +0 -0
- {scaffold_ca_python-0.1.2/tests/models → scaffold_ca_python-0.1.3/tests/factory/simple}/__init__.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/factory/simple/test_delete_module_factory.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/factory/simple/test_helper_factory.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/factory/simple/test_model_factory.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/factory/simple/test_use_case_factory.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/factory/test_module_builder.py +0 -0
- {scaffold_ca_python-0.1.2/tests/templates → scaffold_ca_python-0.1.3/tests/models}/__init__.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/models/test_context.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/models/test_file_operation.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/models/test_layer.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/models/test_violation.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/templates/test_di_config_templates.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/templates/test_docker_templates.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/templates/test_driven_adapter_templates.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/templates/test_entry_point_templates.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/templates/test_entrypoint_main_templates.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/templates/test_helper_templates.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/templates/test_model_templates.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/templates/test_pipeline_templates.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/templates/test_project_templates.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/templates/test_use_case_templates.py +0 -0
- {scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/uv.lock +0 -0
{scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/.github/agents/copilot-instructions.md
RENAMED
|
@@ -7,7 +7,7 @@ Auto-generated from all feature plans. Last updated: 2026-04-20
|
|
|
7
7
|
- N/A — file I/O only via `FileWriter` / `TemplateRenderer` (008-fastapi-entrypoint-baseline)
|
|
8
8
|
- Python 3.13 + FastAPI ≥ 0.135.2, uvicorn[standard] ≥ 0.20, dependency-injector ≥ 4.49.0, pydantic-settings ≥ 2.13.1, Jinja2 ≥ 3.1, pydantic ≥ 2.0, typer ≥ 0.16, rich ≥ 14.1 (009-app-factory-split)
|
|
9
9
|
- N/A (code-generation tool; no database) (009-app-factory-split)
|
|
10
|
-
- Python 3.13 +
|
|
10
|
+
- Python 3.13 + Typer, Rich (CLI); tomllib + tomli_w (TOML read/write); pytest + pytest-cov (testing); ruff (lint/format); mypy strict (types) (011-fix-restapi-cleanup)
|
|
11
11
|
- Local filesystem — `pyproject.toml` (TOML), `main.py` (plain file delete) (011-fix-restapi-cleanup)
|
|
12
12
|
- Python 3.13 + Jinja2 (template rendering), Pydantic v2 (generated schema model), FastAPI + Starlette (generated test client), pytest + pytest-cov (testing), ruff (lint/format), mypy strict (types), uv (package management) (012-fix-restapi-test-templates)
|
|
13
13
|
- Local filesystem — Jinja2 `.jinja2` template files (012-fix-restapi-test-templates)
|
|
@@ -15,9 +15,9 @@ Auto-generated from all feature plans. Last updated: 2026-04-20
|
|
|
15
15
|
- Local filesystem — Path operations only (014-tests-in-src)
|
|
16
16
|
- Python 3.13 + Typer ≥ 0.16, Rich ≥ 14.1, Jinja2 ≥ 3.1, Pydantic v2, uv (015-factory-builder-refactor)
|
|
17
17
|
- File system only (pyproject.toml + generated project files) (015-factory-builder-refactor)
|
|
18
|
-
- Python 3.13+ +
|
|
18
|
+
- Python 3.13+ + Typer>=0.16.0, rich>=14.1.0; ruff (linter/formatter), mypy strict (type checker) (016-dedup-command-aliases)
|
|
19
19
|
- N/A — CLI tool, no database (016-dedup-command-aliases)
|
|
20
|
-
- Python 3.13+ +
|
|
20
|
+
- Python 3.13+ + Typer ≥ 0.16, pydantic ≥ 2.0, rich ≥ 14.1, jinja2 ≥ 3.1 (017-pep8-naming-validation)
|
|
21
21
|
- N/A (file generation only) (017-pep8-naming-validation)
|
|
22
22
|
- Python 3.13+ + Typer (CLI), Rich (output), Jinja2 (templates), Pydantic v2 (context models), `mcp>=1.0` (generated project dep), `starlette` (generated project dep), `uvicorn` (generated project dep), `dependency-injector` (generated project dep) (019-mcp-entry-point-restructure)
|
|
23
23
|
- N/A — file system writes only (019-mcp-entry-point-restructure)
|
|
@@ -35,7 +35,9 @@ tests/
|
|
|
35
35
|
|
|
36
36
|
## Commands
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
uv run pytest
|
|
39
|
+
uv run ruff check src tests
|
|
40
|
+
uv run mypy src
|
|
39
41
|
|
|
40
42
|
## Code Style
|
|
41
43
|
|
|
@@ -44,7 +46,7 @@ Python 3.13: Follow standard conventions
|
|
|
44
46
|
## Recent Changes
|
|
45
47
|
- 020-pypi-publish-readme: Added Python 3.13+ + hatchling (build backend), uv-dynamic-versioning (git-tag versioning, PEP 440), uv (build + publish)
|
|
46
48
|
- 019-mcp-entry-point-restructure: Added Python 3.13+ + Typer (CLI), Rich (output), Jinja2 (templates), Pydantic v2 (context models), `mcp>=1.0` (generated project dep), `starlette` (generated project dep), `uvicorn` (generated project dep), `dependency-injector` (generated project dep)
|
|
47
|
-
- 017-pep8-naming-validation: Added Python 3.13+ +
|
|
49
|
+
- 017-pep8-naming-validation: Added Python 3.13+ + Typer ≥ 0.16, pydantic ≥ 2.0, rich ≥ 14.1, jinja2 ≥ 3.1
|
|
48
50
|
|
|
49
51
|
|
|
50
52
|
<!-- MANUAL ADDITIONS START -->
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# See https://pre-commit.com for more information
|
|
2
2
|
# See https://pre-commit.com/hooks.html for more hooks
|
|
3
|
+
|
|
4
|
+
# SDD documentation and Spec-Kit tooling are authored artifacts, not source code:
|
|
5
|
+
# keep the fixer/formatter hooks out of them so runs stay scoped to code changes.
|
|
6
|
+
exclude: '^(\.specify/|specs/|\.github/agents/)'
|
|
7
|
+
|
|
3
8
|
repos:
|
|
4
9
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
5
10
|
rev: v5.0.0
|
|
@@ -258,4 +258,4 @@ dependencies listed in Principle III, installed via `uv` at generation time.
|
|
|
258
258
|
- Compliance reviews MUST occur at the start of each new feature branch and before
|
|
259
259
|
merging to `main`.
|
|
260
260
|
|
|
261
|
-
**Version**:
|
|
261
|
+
**Version**: 2.0.3 | **Ratified**: 2026-03-25 | **Last Amended**: 2026-04-10
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.3](https://github.com/bancolombia/scaffold-clean-architecture-py/compare/v0.1.2...v0.1.3) (2026-09-17)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Documentation
|
|
7
|
+
|
|
8
|
+
* clean up SDD specification audit artifacts ([1a0374e](https://github.com/bancolombia/scaffold-clean-architecture-py/commit/1a0374e5895864718b9c6ee7b0990023942441fa))
|
|
9
|
+
|
|
3
10
|
## [0.1.2](https://github.com/bancolombia/scaffold-clean-architecture-py/compare/v0.1.1...v0.1.2) (2026-09-16)
|
|
4
11
|
|
|
5
12
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: scaffold-ca-python
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: Scaffolder to generate Clean Architecture apps
|
|
5
5
|
Project-URL: Homepage, https://github.com/bancolombia/scaffold-clean-architecture-py
|
|
6
6
|
Project-URL: Repository, https://github.com/bancolombia/scaffold-clean-architecture-py
|
|
@@ -217,8 +217,8 @@ scaffold update-project --dry-run
|
|
|
217
217
|
|----------------|---------|------|
|
|
218
218
|
| Python | >=3.13 | Runtime |
|
|
219
219
|
| uv | latest | Dependency management, build, and publish |
|
|
220
|
-
| Typer | >=0.
|
|
221
|
-
| Rich | >=
|
|
220
|
+
| Typer | >=0.25.1 | CLI framework |
|
|
221
|
+
| Rich | >=15.0.0 | Terminal output formatting |
|
|
222
222
|
| Jinja2 | >=3.1 | Template engine for code generation |
|
|
223
223
|
| Pydantic v2 | >=2.0 | Runtime validation of template context |
|
|
224
224
|
| hatchling | latest | Build backend |
|
|
@@ -248,12 +248,12 @@ scaffold update-project --dry-run
|
|
|
248
248
|
|
|
249
249
|
## Contributing
|
|
250
250
|
|
|
251
|
-
1. Fork the upstream repository on GitHub: https://github.com/
|
|
251
|
+
1. Fork the upstream repository on GitHub: https://github.com/bancolombia/scaffold-clean-architecture-py
|
|
252
252
|
2. Clone your fork.
|
|
253
253
|
|
|
254
254
|
```bash
|
|
255
|
-
git clone https://github.com/YOUR-USER/scaffold-
|
|
256
|
-
cd scaffold-
|
|
255
|
+
git clone https://github.com/YOUR-USER/scaffold-clean-architecture-py.git
|
|
256
|
+
cd scaffold-clean-architecture-py
|
|
257
257
|
```
|
|
258
258
|
|
|
259
259
|
3. Set up the development environment.
|
|
@@ -186,8 +186,8 @@ scaffold update-project --dry-run
|
|
|
186
186
|
|----------------|---------|------|
|
|
187
187
|
| Python | >=3.13 | Runtime |
|
|
188
188
|
| uv | latest | Dependency management, build, and publish |
|
|
189
|
-
| Typer | >=0.
|
|
190
|
-
| Rich | >=
|
|
189
|
+
| Typer | >=0.25.1 | CLI framework |
|
|
190
|
+
| Rich | >=15.0.0 | Terminal output formatting |
|
|
191
191
|
| Jinja2 | >=3.1 | Template engine for code generation |
|
|
192
192
|
| Pydantic v2 | >=2.0 | Runtime validation of template context |
|
|
193
193
|
| hatchling | latest | Build backend |
|
|
@@ -217,12 +217,12 @@ scaffold update-project --dry-run
|
|
|
217
217
|
|
|
218
218
|
## Contributing
|
|
219
219
|
|
|
220
|
-
1. Fork the upstream repository on GitHub: https://github.com/
|
|
220
|
+
1. Fork the upstream repository on GitHub: https://github.com/bancolombia/scaffold-clean-architecture-py
|
|
221
221
|
2. Clone your fork.
|
|
222
222
|
|
|
223
223
|
```bash
|
|
224
|
-
git clone https://github.com/YOUR-USER/scaffold-
|
|
225
|
-
cd scaffold-
|
|
224
|
+
git clone https://github.com/YOUR-USER/scaffold-clean-architecture-py.git
|
|
225
|
+
cd scaffold-clean-architecture-py
|
|
226
226
|
```
|
|
227
227
|
|
|
228
228
|
3. Set up the development environment.
|
{scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/015-factory-builder-refactor/tasks.md
RENAMED
|
@@ -78,8 +78,8 @@ command tests pass with no modifications.
|
|
|
78
78
|
[x] T027 [P] [US2] Implement `DrivenAdapterSecrets` in `src/scaffold_ca_python/factory/driven_adapters/da_secrets.py`
|
|
79
79
|
[x] T028 [P] [US2] Write failing tests for `DrivenAdapterGeneric.build()` in `tests/factory/driven_adapters/test_da_generic.py`
|
|
80
80
|
[x] T029 [P] [US2] Implement `DrivenAdapterGeneric` in `src/scaffold_ca_python/factory/driven_adapters/da_generic.py`
|
|
81
|
-
- [
|
|
82
|
-
- [
|
|
81
|
+
- [x] T030 [US2] Refactor `src/scaffold_ca_python/commands/generate_driven_adapter.py` to thin + `_REGISTRY`; remove FileWriter/TemplateRenderer/pyproject_writer imports
|
|
82
|
+
- [x] T031 [US2] Run `uv run pytest tests/commands/ --no-cov -q` and confirm zero regressions (no test file modified)
|
|
83
83
|
|
|
84
84
|
---
|
|
85
85
|
|
|
@@ -111,20 +111,20 @@ command in scope uses only `ModuleBuilder`. After this phase, no command file im
|
|
|
111
111
|
|
|
112
112
|
**Independent test**: `uv run pytest tests/factory/test_registry.py tests/factory/test_dry_run_parity.py --no-cov -q`
|
|
113
113
|
|
|
114
|
-
- [
|
|
115
|
-
- [
|
|
116
|
-
- [
|
|
114
|
+
- [x] T042 [US4] Write `tests/factory/test_registry.py` — assert `_REGISTRY` for `gep` contains exactly {restapi, agent, mcp, generic}; assert `_REGISTRY` for `gda` contains exactly {rest-consumer, secrets, generic}; assert all 6 simple commands have `_REGISTRY` with their respective types; assert unknown type lookup produces error listing valid keys
|
|
115
|
+
- [x] T043 [US4] Write `tests/factory/test_dry_run_parity.py` — for each type in both commands, compare dry-run preview path set against a captured pre-refactor baseline fixture
|
|
116
|
+
- [x] T044 [US4] Write SC-002 extensibility proof test in `tests/factory/test_extensibility.py` — define a stub factory inline, register it under a new key in a patched `_REGISTRY`, invoke the command with the stub type, assert factory was called; zero existing command files modified
|
|
117
117
|
|
|
118
118
|
---
|
|
119
119
|
|
|
120
120
|
## Phase 7 — Polish & Quality Gates
|
|
121
121
|
|
|
122
|
-
- [
|
|
123
|
-
- [
|
|
124
|
-
- [
|
|
125
|
-
- [
|
|
126
|
-
- [
|
|
127
|
-
- [
|
|
122
|
+
- [x] T045 Run `uv run pytest` and confirm all tests pass with ≥ 95% coverage
|
|
123
|
+
- [x] T045b Assert template immutability: `git diff HEAD -- src/scaffold_ca_python/templates/` must be empty — no template file modified during implementation (FR-009)
|
|
124
|
+
- [x] T045c Assert model immutability: confirm no new files exist under `src/scaffold_ca_python/models/` beyond the pre-refactor baseline (FR-010)
|
|
125
|
+
- [x] T046 [P] Run `uv run ruff check src/ tests/` and fix any violations
|
|
126
|
+
- [x] T047 [P] Run `uv run ruff format src/ tests/` to normalise formatting
|
|
127
|
+
- [x] T048 [P] Run `uv run mypy src/` and confirm 0 new errors under strict mode
|
|
128
128
|
|
|
129
129
|
---
|
|
130
130
|
|
{scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/specs/019-mcp-entry-point-restructure/plan.md
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Implementation Plan: MCP Entry Point Restructure
|
|
2
2
|
|
|
3
|
-
**Branch**: `019-mcp-entry-point-restructure` | **Date**: 2026-04-16 | **Spec**: [spec.md](
|
|
4
|
-
**Input**: Feature specification from `/specs/
|
|
3
|
+
**Branch**: `019-mcp-entry-point-restructure` | **Date**: 2026-04-16 | **Spec**: [spec.md](spec.md)
|
|
4
|
+
**Input**: Feature specification from `/specs/019-mcp-entry-point-restructure/spec.md`
|
|
5
5
|
|
|
6
6
|
## Summary
|
|
7
7
|
|
{scaffold_ca_python-0.1.2 → scaffold_ca_python-0.1.3}/tests/factory/fixtures/dry_run_baseline.json
RENAMED
|
@@ -18,17 +18,24 @@
|
|
|
18
18
|
"src/my_app/infrastructure/entry_points/agent/__init__.py",
|
|
19
19
|
"src/my_app/infrastructure/entry_points/agent/agent.py",
|
|
20
20
|
"src/my_app/infrastructure/entry_points/agent/card.py",
|
|
21
|
+
"src/my_app/main.py",
|
|
21
22
|
"src/tests/infrastructure/entry_points/agent/test_agent.py"
|
|
22
23
|
],
|
|
23
24
|
"gep:generic": [
|
|
24
25
|
"src/my_app/infrastructure/entry_points/generic/__init__.py",
|
|
25
26
|
"src/my_app/infrastructure/entry_points/generic/entry_point.py",
|
|
27
|
+
"src/my_app/main.py",
|
|
26
28
|
"src/tests/infrastructure/entry_points/generic/test_entry_point.py"
|
|
27
29
|
],
|
|
28
30
|
"gep:mcp": [
|
|
31
|
+
"src/my_app/application/app.py",
|
|
32
|
+
"src/my_app/application/config/config.py",
|
|
29
33
|
"src/my_app/infrastructure/entry_points/mcp_server/__init__.py",
|
|
30
|
-
"src/my_app/infrastructure/entry_points/mcp_server/
|
|
31
|
-
"src/
|
|
34
|
+
"src/my_app/infrastructure/entry_points/mcp_server/tools.py",
|
|
35
|
+
"src/my_app/main.py",
|
|
36
|
+
"src/my_app/server.py",
|
|
37
|
+
"src/tests/infrastructure/entry_points/mcp_server/test_app.py",
|
|
38
|
+
"src/tests/infrastructure/entry_points/mcp_server/test_tools.py"
|
|
32
39
|
],
|
|
33
40
|
"gep:restapi": [
|
|
34
41
|
"src/my_app/application/app.py",
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"""Dry-run path parity against the captured baseline (T043 / SC-005).
|
|
2
|
+
|
|
3
|
+
For each type of both entry-point (`gep`) and driven-adapter (`gda`) commands, the set
|
|
4
|
+
of paths a dry-run would touch must match a golden baseline fixture. The baseline is
|
|
5
|
+
regenerated from the real factory output and pins the file-generation contract; an
|
|
6
|
+
accidental change to any factory's queued paths breaks these tests, prompting a
|
|
7
|
+
deliberate baseline refresh.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import json
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
import pytest
|
|
16
|
+
from typer.testing import CliRunner
|
|
17
|
+
|
|
18
|
+
from scaffold_ca_python.cli import app
|
|
19
|
+
from scaffold_ca_python.commands import generate_driven_adapter, generate_entry_point
|
|
20
|
+
from scaffold_ca_python.core.module_builder import ModuleBuilder
|
|
21
|
+
from scaffold_ca_python.factory import ModuleFactory
|
|
22
|
+
from scaffold_ca_python.models.context import ModuleContext, ProjectContext
|
|
23
|
+
from scaffold_ca_python.models.layer import Layer
|
|
24
|
+
|
|
25
|
+
runner = CliRunner()
|
|
26
|
+
|
|
27
|
+
_BASELINE: dict[str, list[str]] = json.loads(
|
|
28
|
+
(Path(__file__).parent / "fixtures" / "dry_run_baseline.json").read_text(encoding="utf-8")
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# Flags the gep command always attaches to the builder before invoking a factory.
|
|
32
|
+
_GEP_PARAMS = {
|
|
33
|
+
"routes": [],
|
|
34
|
+
"enable_kafka": False,
|
|
35
|
+
"enable_mcp_client": False,
|
|
36
|
+
"with_resources": False,
|
|
37
|
+
"with_prompts": False,
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@pytest.fixture()
|
|
42
|
+
def project_root(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path:
|
|
43
|
+
"""Scaffold a real `my-app` project (package `my_app`) inside tmp_path."""
|
|
44
|
+
monkeypatch.chdir(tmp_path)
|
|
45
|
+
runner.invoke(app, ["ca", "--name", "my-app"], catch_exceptions=False)
|
|
46
|
+
project_dir = tmp_path / "my-app"
|
|
47
|
+
monkeypatch.chdir(project_dir)
|
|
48
|
+
return project_dir
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _preview(
|
|
52
|
+
root: Path,
|
|
53
|
+
module_ctx: ModuleContext,
|
|
54
|
+
factory_cls: type[ModuleFactory],
|
|
55
|
+
params: dict[str, object] | None = None,
|
|
56
|
+
) -> list[str]:
|
|
57
|
+
"""Return the sorted relative paths a factory dry-run would touch."""
|
|
58
|
+
builder = ModuleBuilder(
|
|
59
|
+
project_root=root,
|
|
60
|
+
project_ctx=ProjectContext(name="my-app"),
|
|
61
|
+
module_ctx=module_ctx,
|
|
62
|
+
dry_run=True,
|
|
63
|
+
)
|
|
64
|
+
for key, value in (params or {}).items():
|
|
65
|
+
builder.add_param(key, value)
|
|
66
|
+
factory_cls().build(builder)
|
|
67
|
+
return sorted(p.relative_to(root).as_posix() for p in builder.persist())
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
@pytest.mark.parametrize("type_", ["restapi", "agent", "mcp", "generic"])
|
|
71
|
+
def test_gep_dry_run_parity(project_root: Path, type_: str) -> None:
|
|
72
|
+
module_ctx = ModuleContext(
|
|
73
|
+
name=type_.replace("-", "_"),
|
|
74
|
+
layer=Layer.ENTRY_POINTS,
|
|
75
|
+
project=ProjectContext(name="my-app"),
|
|
76
|
+
subtype=type_,
|
|
77
|
+
)
|
|
78
|
+
preview = _preview(project_root, module_ctx, generate_entry_point._REGISTRY[type_], _GEP_PARAMS)
|
|
79
|
+
assert preview == _BASELINE[f"gep:{type_}"]
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
@pytest.mark.parametrize(
|
|
83
|
+
("type_", "name"),
|
|
84
|
+
[("rest-consumer", None), ("secrets", None), ("generic", "my-adapter")],
|
|
85
|
+
)
|
|
86
|
+
def test_gda_dry_run_parity(project_root: Path, type_: str, name: str | None) -> None:
|
|
87
|
+
proj = ProjectContext(name="my-app")
|
|
88
|
+
if type_ == "rest-consumer":
|
|
89
|
+
module_ctx = ModuleContext(name="rest_consumer", layer=Layer.DRIVEN_ADAPTERS, project=proj)
|
|
90
|
+
elif type_ == "secrets":
|
|
91
|
+
module_ctx = ModuleContext(name="secrets", layer=Layer.DRIVEN_ADAPTERS, project=proj)
|
|
92
|
+
else:
|
|
93
|
+
assert name is not None
|
|
94
|
+
module_ctx = ModuleContext(name=name, layer=Layer.DRIVEN_ADAPTERS, project=proj)
|
|
95
|
+
preview = _preview(project_root, module_ctx, generate_driven_adapter._REGISTRY[type_])
|
|
96
|
+
assert preview == _BASELINE[f"gda:{type_}"]
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"""Extensibility proof for factory registries (T044 / SC-002).
|
|
2
|
+
|
|
3
|
+
A new module type must be addable by registering a ModuleFactory under a fresh key in
|
|
4
|
+
a command's `_REGISTRY`, with no edits to the command file itself. Here a stub factory
|
|
5
|
+
is registered under a new key and the command is shown to dispatch to it.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
|
|
12
|
+
import pytest
|
|
13
|
+
from typer.testing import CliRunner
|
|
14
|
+
|
|
15
|
+
from scaffold_ca_python.cli import app
|
|
16
|
+
from scaffold_ca_python.commands import generate_entry_point
|
|
17
|
+
from scaffold_ca_python.core.module_builder import ModuleBuilder
|
|
18
|
+
|
|
19
|
+
runner = CliRunner()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@pytest.fixture()
|
|
23
|
+
def project_root(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path:
|
|
24
|
+
"""Scaffold a real `my-app` project inside tmp_path."""
|
|
25
|
+
monkeypatch.chdir(tmp_path)
|
|
26
|
+
runner.invoke(app, ["ca", "--name", "my-app"], catch_exceptions=False)
|
|
27
|
+
project_dir = tmp_path / "my-app"
|
|
28
|
+
monkeypatch.chdir(project_dir)
|
|
29
|
+
return project_dir
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_new_type_routes_to_registered_factory(project_root: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
33
|
+
"""Registering a new ModuleFactory key routes `gep` to it without editing the command."""
|
|
34
|
+
calls: list[str] = []
|
|
35
|
+
|
|
36
|
+
class _StubFactory:
|
|
37
|
+
def build(self, builder: ModuleBuilder) -> None:
|
|
38
|
+
calls.append("built")
|
|
39
|
+
|
|
40
|
+
# Add a brand-new type key; monkeypatch reverts the registry after the test.
|
|
41
|
+
monkeypatch.setitem(generate_entry_point._REGISTRY, "stub", _StubFactory)
|
|
42
|
+
|
|
43
|
+
result = runner.invoke(app, ["gep", "--type", "stub", "--dry-run"], catch_exceptions=False)
|
|
44
|
+
|
|
45
|
+
assert result.exit_code == 0
|
|
46
|
+
assert calls == ["built"], "Registered stub factory's build() was not invoked"
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Tests for the command _REGISTRY dispatch tables (T042 / 015-factory-builder-refactor).
|
|
2
|
+
|
|
3
|
+
Verifies each command exposes a factory registry keyed by its supported types, and
|
|
4
|
+
that dispatching an unknown type fails with an error that lists the valid keys.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typer.testing import CliRunner
|
|
10
|
+
|
|
11
|
+
from scaffold_ca_python.cli import app
|
|
12
|
+
from scaffold_ca_python.commands import (
|
|
13
|
+
delete_module,
|
|
14
|
+
generate_driven_adapter,
|
|
15
|
+
generate_entry_point,
|
|
16
|
+
generate_helper,
|
|
17
|
+
generate_model,
|
|
18
|
+
generate_use_case,
|
|
19
|
+
)
|
|
20
|
+
from tests.conftest import strip_ansi
|
|
21
|
+
|
|
22
|
+
runner = CliRunner()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_entry_point_registry_keys() -> None:
|
|
26
|
+
assert set(generate_entry_point._REGISTRY) == {"restapi", "agent", "mcp", "generic"}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_driven_adapter_registry_keys() -> None:
|
|
30
|
+
assert set(generate_driven_adapter._REGISTRY) == {"rest-consumer", "secrets", "generic"}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_simple_command_registries_expose_single_key() -> None:
|
|
34
|
+
assert set(generate_model._REGISTRY) == {"model"}
|
|
35
|
+
assert set(generate_use_case._REGISTRY) == {"use_case"}
|
|
36
|
+
assert set(generate_helper._REGISTRY) == {"helper"}
|
|
37
|
+
assert set(delete_module._REGISTRY) == {"delete"}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_gep_unknown_type_lists_valid_keys() -> None:
|
|
41
|
+
result = runner.invoke(app, ["gep", "--type", "bogus"], catch_exceptions=False)
|
|
42
|
+
assert result.exit_code == 1
|
|
43
|
+
# Flatten soft-wrapped console output so key tokens stay intact.
|
|
44
|
+
out = strip_ansi(result.output).replace("\n", " ")
|
|
45
|
+
for key in generate_entry_point._REGISTRY:
|
|
46
|
+
assert key in out, f"Expected valid key '{key}' listed in error output"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def test_gda_unknown_type_lists_valid_keys() -> None:
|
|
50
|
+
result = runner.invoke(app, ["gda", "--type", "bogus"], catch_exceptions=False)
|
|
51
|
+
assert result.exit_code == 1
|
|
52
|
+
out = strip_ansi(result.output).replace("\n", " ")
|
|
53
|
+
for key in generate_driven_adapter._REGISTRY:
|
|
54
|
+
assert key in out, f"Expected valid key '{key}' listed in error output"
|
|
File without changes
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# Specification Quality Checklist: Fix RestAPI Entry Point Cleanup
|
|
2
|
-
|
|
3
|
-
**Purpose**: Validate specification completeness and quality before proceeding to planning
|
|
4
|
-
**Created**: 2026-04-10
|
|
5
|
-
**Feature**: [spec.md](../spec.md)
|
|
6
|
-
|
|
7
|
-
## Content Quality
|
|
8
|
-
|
|
9
|
-
- [X] No implementation details (languages, frameworks, APIs)
|
|
10
|
-
- [X] Focused on user value and business needs
|
|
11
|
-
- [X] Written for non-technical stakeholders
|
|
12
|
-
- [X] All mandatory sections completed
|
|
13
|
-
|
|
14
|
-
## Requirement Completeness
|
|
15
|
-
|
|
16
|
-
- [X] No [NEEDS CLARIFICATION] markers remain
|
|
17
|
-
- [X] Requirements are testable and unambiguous
|
|
18
|
-
- [X] Success criteria are measurable
|
|
19
|
-
- [X] Success criteria are technology-agnostic (no implementation details)
|
|
20
|
-
- [X] All acceptance scenarios are defined
|
|
21
|
-
- [X] Edge cases are identified
|
|
22
|
-
- [X] Scope is clearly bounded
|
|
23
|
-
- [X] Dependencies and assumptions identified
|
|
24
|
-
|
|
25
|
-
## Feature Readiness
|
|
26
|
-
|
|
27
|
-
- [X] All functional requirements have clear acceptance criteria
|
|
28
|
-
- [X] User scenarios cover primary flows
|
|
29
|
-
- [X] Feature meets measurable outcomes defined in Success Criteria
|
|
30
|
-
- [X] No implementation details leak into specification
|
|
31
|
-
|
|
32
|
-
## Notes
|
|
33
|
-
|
|
34
|
-
- All items pass. Spec is ready for `/speckit.plan`.
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
# Feature Specification: Fix RestAPI Entry Point Cleanup
|
|
2
|
-
|
|
3
|
-
**Feature Branch**: `010-fix-restapi-cleanup`
|
|
4
|
-
**Created**: 2026-04-10
|
|
5
|
-
**Status**: Draft
|
|
6
|
-
**Input**: User description: "fix some issues when create a restapi entry point: 1. Delete main.py file because restapi entry point creates a server.py module to execute the app. 2. Update pyproject.toml [project.scripts] to point to server:start_server"
|
|
7
|
-
|
|
8
|
-
## User Scenarios & Testing *(mandatory)*
|
|
9
|
-
|
|
10
|
-
### User Story 1 - `main.py` Is Removed When a RestAPI Entry Point Is Scaffolded (Priority: P1)
|
|
11
|
-
|
|
12
|
-
A developer runs `scaffold ca` which creates a default `main.py`. Later they run `gep --type restapi`, which sets up a FastAPI application and a `server.py` entry point. The old `main.py` is now irrelevant and misleading — the project should no longer contain it after the restapi setup completes.
|
|
13
|
-
|
|
14
|
-
**Why this priority**: `main.py` left behind after `gep --type restapi` causes confusion: the project has two apparent entry points. Removing it is the single most visible correctness fix and is the prerequisite for the `pyproject.toml` scripts update to mean anything.
|
|
15
|
-
|
|
16
|
-
**Independent Test**: Run `scaffold ca --name MyApp`, then `gep --type restapi`. Assert that `src/my_app/main.py` does **not** exist immediately after the command completes.
|
|
17
|
-
|
|
18
|
-
**Acceptance Scenarios**:
|
|
19
|
-
|
|
20
|
-
1. **Given** a fresh CA project with `main.py` created by `scaffold ca`, **When** `gep --type restapi` runs, **Then** `src/<package>/main.py` no longer exists on disk.
|
|
21
|
-
2. **Given** a project where `main.py` was already manually deleted, **When** `gep --type restapi` runs, **Then** the command completes successfully without error (no-op delete).
|
|
22
|
-
3. **Given** a project with a restapi entry point already present, **When** `gep --type restapi` is run a second time, **Then** the command exits with an error (duplicate guard) and `main.py` is not re-created.
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
### User Story 2 - `pyproject.toml` `[project.scripts]` Points to `server:start_server` After RestAPI Scaffolding (Priority: P1)
|
|
27
|
-
|
|
28
|
-
After `gep --type restapi` runs, the executable entry point registered in `pyproject.toml` must call `start_server()` from `server.py` (not `main()` from `main.py`, which no longer exists). A developer must be able to install the package and run the project CLI command immediately.
|
|
29
|
-
|
|
30
|
-
**Why this priority**: Without this fix the installed CLI command points to a deleted module and crashes on every invocation. Equal priority to US1 — both are correctness bugs.
|
|
31
|
-
|
|
32
|
-
**Independent Test**: Run `scaffold ca --name MyApp`, then `gep --type restapi`. Inspect `pyproject.toml` — the `[project.scripts]` entry must read `my_app = "my_app.server:start_server"`.
|
|
33
|
-
|
|
34
|
-
**Acceptance Scenarios**:
|
|
35
|
-
|
|
36
|
-
1. **Given** a fresh CA project with `[project.scripts]` pointing to `main:main`, **When** `gep --type restapi` runs, **Then** `[project.scripts]` in `pyproject.toml` reads `<package> = "<package>.server:start_server"`.
|
|
37
|
-
2. **Given** `gep --type restapi --dry-run` is run, **Then** the output indicates the `pyproject.toml` scripts entry would be updated, but the file is not modified.
|
|
38
|
-
3. **Given** a project using any other entry point type (agent, mcp, generic), **When** the corresponding `gep --type <other>` runs, **Then** `[project.scripts]` is **not** changed (only the restapi type triggers this update).
|
|
39
|
-
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
### Edge Cases
|
|
43
|
-
|
|
44
|
-
- What if `pyproject.toml` does not contain a `[project.scripts]` section at all? → The section and entry must be created.
|
|
45
|
-
- What if the existing `[project.scripts]` entry already points to `server:start_server`? → No duplicate is written; the file remains unchanged.
|
|
46
|
-
- What if `main.py` does not exist when `gep --type restapi` runs (already deleted manually)? → The delete step is silently skipped; command succeeds.
|
|
47
|
-
|
|
48
|
-
## Requirements *(mandatory)*
|
|
49
|
-
|
|
50
|
-
### Functional Requirements
|
|
51
|
-
|
|
52
|
-
- **FR-001**: When `gep --type restapi` executes, the tool MUST delete `src/<package>/main.py` if it exists.
|
|
53
|
-
- **FR-002**: When `gep --type restapi` executes, the tool MUST update `[project.scripts]` in `pyproject.toml` so the package CLI entry reads `<package> = "<package>.server:start_server"`, replacing any prior value.
|
|
54
|
-
- **FR-003**: The `pyproject_toml.jinja2` template MUST NOT be changed to reference `server:start_server` — the update is applied at runtime by `gep --type restapi`, not at project creation time (project creation still generates `main:main`).
|
|
55
|
-
- **FR-004**: When `gep --type restapi --dry-run` is invoked, the tool MUST report the scripts update in its preview output without modifying `pyproject.toml`.
|
|
56
|
-
- **FR-005**: `gep` commands for non-restapi types (agent, mcp, generic) MUST NOT modify `[project.scripts]`.
|
|
57
|
-
- **FR-006**: If `main.py` is absent when `gep --type restapi` runs, the command MUST complete successfully (silent no-op for the delete step).
|
|
58
|
-
- **FR-007**: All other entry-point types continue to overwrite `main.py` as they do today; only the restapi type deletes it.
|
|
59
|
-
|
|
60
|
-
## Success Criteria *(mandatory)*
|
|
61
|
-
|
|
62
|
-
### Measurable Outcomes
|
|
63
|
-
|
|
64
|
-
- **SC-001**: After `gep --type restapi` completes, `src/<package>/main.py` does not exist in 100% of test runs.
|
|
65
|
-
- **SC-002**: After `gep --type restapi` completes, `pyproject.toml` contains exactly one `[project.scripts]` entry pointing to `<package>.server:start_server` — verified by test assertion.
|
|
66
|
-
- **SC-003**: All existing tests continue to pass (no regressions); the overall test count increases by the number of new tests added for this feature.
|
|
67
|
-
- **SC-004**: `gep --type agent`, `gep --type mcp`, and `gep --type generic` each still overwrite `main.py` and leave `[project.scripts]` pointing to `main:main`.
|
|
68
|
-
- **SC-005**: `gep --type restapi --dry-run` does not modify any file on disk.
|
|
69
|
-
|
|
70
|
-
## Assumptions
|
|
71
|
-
|
|
72
|
-
- The `scaffold ca` command always creates `main.py` when scaffolding a new project; `gep --type restapi` is always run in a project that originally had `main.py`.
|
|
73
|
-
- The `pyproject.toml` file always contains a `[project.scripts]` section after `scaffold ca` runs, because that section is included in the current `pyproject_toml.jinja2` template.
|
|
74
|
-
- The `server.py` module (thin wrapper calling `start_server()`) is already emitted by `gep --type restapi` as of feature 009; this feature assumes that is complete.
|
|
75
|
-
- The `start_server()` function is defined in `server.py` by the time `pyproject.toml` is updated; no further template changes to `server.py.jinja2` are needed.
|
|
76
|
-
- Non-restapi entry-point types are out of scope for both the delete and the scripts-update steps.
|