codd-dev 1.35.0__tar.gz → 1.36.0__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.
- {codd_dev-1.35.0 → codd_dev-1.36.0}/PKG-INFO +1 -1
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/cli.py +17 -11
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/extract_ai.py +57 -3
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/extractor.py +65 -25
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/parsing.py +390 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/git_patcher.py +15 -12
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/llm_repair_engine.py +105 -27
- codd_dev-1.36.0/codd/repair/templates/repair_strategy_meta.md +44 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/pyproject.toml +1 -1
- {codd_dev-1.35.0 → codd_dev-1.36.0}/.gitignore +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/LICENSE +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/README.md +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/__main__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/_git_helper.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/ask_user_question_adapter.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/assembler.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/bridge.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/clustering.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/coherence_adapters.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/coherence_engine.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/config.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/contracts.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/coverage_auditor.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/coverage_metrics.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/builder.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/depends_on_consistency.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/deployment_completeness.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/edge_validity.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/environment_coverage.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/implementation_coverage.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/node_completeness.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/task_completion.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/transitive_closure.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/user_journey_coherence.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/coverage_axes.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/cli.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/cpp_embedded.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/csharp.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/elixir.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/generic.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/iot.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/java.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/kotlin.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/mobile.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/ruby.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/rust.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/scala.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/swift.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/test_frameworks.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/web.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/extractor.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/runner.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/defaults.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deploy_targets/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deploy_targets/app_service.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deploy_targets/base.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deploy_targets/docker_compose.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployer.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/checks/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/defaults/deploy_targets.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/defaults/runtime_capability_inference.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/defaults/schema_providers.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/defaults/verification_templates.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/extractor.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/ai_command.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/llm_consideration.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/schema/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/schema/prisma.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/target/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/target/docker_compose.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/assertion_handlers.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/cdp_browser.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/cdp_engines.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/cdp_launchers.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/cdp_wire.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/curl.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/form_strategies.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/means_catalog.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/playwright.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/design_md.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/diff/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/diff/apply.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/diff/engine.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/diff/persistence.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/diff/templates/diff_prompt.md +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/drift.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/e2e_extractor.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/e2e_generator.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/e2e_runner.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/apply.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/engine.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/finding.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/formatters/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/formatters/base.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/formatters/interactive.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/formatters/json_fmt.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/formatters/md.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/lexicon_loader.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/persistence.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/templates/elicit_prompt_L0.md +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/env_refs.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/fixer.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/fixup_drift.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/fixup_drift_strategies/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/fixup_drift_strategies/design_token_drift.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/fixup_drift_strategies/lexicon_violation.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/fixup_drift_strategies/url_drift.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/generator.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/graph.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/hitl_session.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/hooks/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/hooks/pre-commit +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/hooks/recipes/claude_settings_example.json +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/hooks/recipes/codex_hook.sh +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/hooks/recipes/git_post_commit.sh +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/hooks/recipes/git_pre_commit.sh +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/implementer/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/implementer/chunked_runner.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/implementer/typecheck_loop.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/implementer.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/inheritance.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/knowledge_fetcher.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/lexicon.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/approval.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/best_practice_augmenter.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/criteria_expander.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/design_doc_extractor.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/impl_step_deriver.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/means_catalog_loader.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/parser.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/plan_deriver.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/prompt_builder.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/strategy_validator.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/templates/best_practice_augment_meta.md +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/templates/criteria_expand_meta.md +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/templates/design_doc_extract_meta.md +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/templates/impl_step_derive_meta.md +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/templates/implementation_step_catalog.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/templates/meta_instruction.md +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/templates/plan_derive_meta.md +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/templates/verification_means_catalog.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/mcp_server.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/measure.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/planner.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/policy.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/preflight/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/preflight/defaults/cli.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/preflight/defaults/iot.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/preflight/defaults/mobile.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/preflight/defaults/web.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/propagate.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/propagator.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/registry.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/approval_repair.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/engine.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/history.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/loop.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/primary_picker.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/proof_breaks.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/repair_result.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/repairability_classifier.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/schema.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/templates/analyze_meta.md +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/templates/propose_meta.md +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/templates/repairability_meta.md +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/verify_runner.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair_slice.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/require.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/require_plugins.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/require_propagate.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/required_artifacts/defaults/cli.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/required_artifacts/defaults/iot.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/required_artifacts/defaults/mobile.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/required_artifacts/defaults/web.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/required_artifacts_deriver.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/requirement_completeness/defaults/cli.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/requirement_completeness/defaults/iot.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/requirement_completeness/defaults/mobile.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/requirement_completeness/defaults/web.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/requirement_completeness_auditor.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/restore.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/routes_extractor.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/scanner.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/schema_refs.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/screen_flow_validator.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/screen_transition_extractor.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/screen_transitions/defaults.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/synth.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/codd.yaml.tmpl +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/conventions.yaml.tmpl +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/data_dependencies.yaml.tmpl +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/doc_links.yaml.tmpl +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/extract_ai_prompt_baseline.md +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/extracted/api-contract.md.j2 +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/extracted/architecture-overview.md.j2 +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/extracted/module-detail.md.j2 +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/extracted/schema-design.md.j2 +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/extracted/system-context.md.j2 +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/gitignore.tmpl +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/lexicon_questions.md +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/lexicon_schema.yaml +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/overrides.yaml.tmpl +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/traceability.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/validator.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/watch/__init__.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/watch/events.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/watch/propagation_log.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/watch/propagation_pipeline.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/watch/test_runner.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/watch/watcher.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/wiring.py +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/docs/cookbook/cdp_browser/README.md +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/docs/requirements/README.md +0 -0
- {codd_dev-1.35.0 → codd_dev-1.36.0}/tests/integration/standalone_repair_skeleton/README.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codd-dev
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.36.0
|
|
4
4
|
Summary: CoDD: Coherence-Driven Development — cross-artifact change impact analysis
|
|
5
5
|
Project-URL: Homepage, https://github.com/yohey-w/codd-dev
|
|
6
6
|
Project-URL: Repository, https://github.com/yohey-w/codd-dev
|
|
@@ -288,13 +288,9 @@ def _resolve_bootstrap_codd_dir(project_root: Path) -> Path:
|
|
|
288
288
|
return existing
|
|
289
289
|
|
|
290
290
|
hidden_dir = project_root / ".codd"
|
|
291
|
-
default_dir = project_root / "codd"
|
|
292
291
|
if hidden_dir.exists():
|
|
293
292
|
return hidden_dir
|
|
294
|
-
|
|
295
|
-
# Avoid writing config into projects whose source package is already named codd/.
|
|
296
|
-
return hidden_dir
|
|
297
|
-
return default_dir
|
|
293
|
+
return hidden_dir
|
|
298
294
|
|
|
299
295
|
|
|
300
296
|
def _format_yaml_list(items: list[str], *, indent: int = 4) -> str:
|
|
@@ -2203,7 +2199,8 @@ def e2e_generate_legacy(path: str, base_url: str, output: str | None, framework:
|
|
|
2203
2199
|
@click.option("--path", default=".", help="Project root directory")
|
|
2204
2200
|
@click.option("--language", default=None, help="Override language detection (python/typescript/javascript/go — full support; java — symbols only)")
|
|
2205
2201
|
@click.option("--source-dirs", default=None, help="Comma-separated source directories (default: auto-detect)")
|
|
2206
|
-
@click.option("--output", default=None, help="Output directory (default: <
|
|
2202
|
+
@click.option("--output", default=None, help="Output directory (default: <project-root>/.codd/extract/)")
|
|
2203
|
+
@click.option("--init", "initialize", is_flag=True, help="Add brownfield init metadata to generated YAML/Markdown")
|
|
2207
2204
|
@click.option("--ai", is_flag=True, default=False, help="Use AI-powered extraction (6-layer MECE design docs)")
|
|
2208
2205
|
@click.option(
|
|
2209
2206
|
"--ai-cmd",
|
|
@@ -2237,6 +2234,7 @@ def extract(
|
|
|
2237
2234
|
language: str | None,
|
|
2238
2235
|
source_dirs: str | None,
|
|
2239
2236
|
output: str | None,
|
|
2237
|
+
initialize: bool,
|
|
2240
2238
|
ai: bool,
|
|
2241
2239
|
ai_cmd: str | None,
|
|
2242
2240
|
prompt_file: str | None,
|
|
@@ -2249,9 +2247,8 @@ def extract(
|
|
|
2249
2247
|
Default mode: static analysis (no AI, pure structural facts).
|
|
2250
2248
|
With --ai: AI-powered 6-layer MECE extraction using claude --print.
|
|
2251
2249
|
|
|
2252
|
-
Output goes to
|
|
2253
|
-
|
|
2254
|
-
confirmed docs when ready.
|
|
2250
|
+
Output goes to `.codd/extract/` by default. Review and promote confirmed
|
|
2251
|
+
docs when ready.
|
|
2255
2252
|
"""
|
|
2256
2253
|
if ctx.invoked_subcommand is not None:
|
|
2257
2254
|
return
|
|
@@ -2259,7 +2256,13 @@ def extract(
|
|
|
2259
2256
|
project_root = Path(path).resolve()
|
|
2260
2257
|
bootstrap_codd_dir = _resolve_bootstrap_codd_dir(project_root)
|
|
2261
2258
|
dirs = [d.strip() for d in source_dirs.split(",") if d.strip()] if source_dirs else None
|
|
2262
|
-
output_path = Path(output) if output else
|
|
2259
|
+
output_path = Path(output) if output else project_root / ".codd" / "extract"
|
|
2260
|
+
if output and not output_path.is_absolute():
|
|
2261
|
+
output_path = project_root / output_path
|
|
2262
|
+
init_metadata = None
|
|
2263
|
+
if initialize:
|
|
2264
|
+
from codd.extractor import build_extract_init_metadata
|
|
2265
|
+
init_metadata = build_extract_init_metadata(project_root)
|
|
2263
2266
|
|
|
2264
2267
|
if layer == "routes":
|
|
2265
2268
|
from codd.config import load_project_config
|
|
@@ -2314,6 +2317,9 @@ def extract(
|
|
|
2314
2317
|
except Exception as exc:
|
|
2315
2318
|
click.echo(f"Error: {exc}")
|
|
2316
2319
|
raise SystemExit(1)
|
|
2320
|
+
if init_metadata is not None:
|
|
2321
|
+
from codd.extractor import add_extract_init_frontmatter
|
|
2322
|
+
add_extract_init_frontmatter(result.generated_files, init_metadata)
|
|
2317
2323
|
|
|
2318
2324
|
facts = extract_facts(project_root, language, dirs)
|
|
2319
2325
|
config_path, generated_config = _ensure_bootstrap_codd_yaml(
|
|
@@ -2340,7 +2346,7 @@ def extract(
|
|
|
2340
2346
|
from codd.extractor import run_extract
|
|
2341
2347
|
|
|
2342
2348
|
try:
|
|
2343
|
-
result = run_extract(project_root, language, dirs, str(output_path))
|
|
2349
|
+
result = run_extract(project_root, language, dirs, str(output_path), init_metadata=init_metadata)
|
|
2344
2350
|
except Exception as exc:
|
|
2345
2351
|
click.echo(f"Error: {exc}")
|
|
2346
2352
|
raise SystemExit(1)
|
|
@@ -49,6 +49,12 @@ SCHEMA_PATTERNS = [
|
|
|
49
49
|
"prisma/schema.prisma", "db/schema.rb", "alembic/versions",
|
|
50
50
|
]
|
|
51
51
|
|
|
52
|
+
# Generic source extensions included in the AI context scan. The deterministic
|
|
53
|
+
# parser decides language-specific structure later; this layer keeps raw text.
|
|
54
|
+
SOURCE_EXTENSIONS = {
|
|
55
|
+
".go", ".java", ".js", ".jsx", ".php", ".py", ".rb", ".ts", ".tsx", ".vue",
|
|
56
|
+
}
|
|
57
|
+
|
|
52
58
|
# Max file size to include in prompt (bytes)
|
|
53
59
|
MAX_FILE_SIZE = 50_000
|
|
54
60
|
|
|
@@ -171,9 +177,45 @@ def _find_source_files(root: Path) -> list[Path]:
|
|
|
171
177
|
# Filter out files in skip dirs
|
|
172
178
|
found = [f for f in found if not any(s in f.parts for s in SKIP_DIRS)]
|
|
173
179
|
files.extend(found)
|
|
180
|
+
files.extend(_find_source_files_by_extension(root))
|
|
174
181
|
return sorted(set(files))
|
|
175
182
|
|
|
176
183
|
|
|
184
|
+
def _find_source_files_by_extension(root: Path) -> list[Path]:
|
|
185
|
+
"""Find source files generically by extension, preserving raw text for AI."""
|
|
186
|
+
files: list[Path] = []
|
|
187
|
+
for current, dirs, filenames in os.walk(root):
|
|
188
|
+
dirs[:] = [
|
|
189
|
+
d for d in dirs
|
|
190
|
+
if d not in SKIP_DIRS and not d.startswith(".")
|
|
191
|
+
]
|
|
192
|
+
current_path = Path(current)
|
|
193
|
+
for filename in filenames:
|
|
194
|
+
path = current_path / filename
|
|
195
|
+
if path.suffix not in SOURCE_EXTENSIONS:
|
|
196
|
+
continue
|
|
197
|
+
try:
|
|
198
|
+
rel_parts = path.relative_to(root).parts
|
|
199
|
+
except ValueError:
|
|
200
|
+
continue
|
|
201
|
+
if _is_test_path(rel_parts) or any(part in SKIP_DIRS for part in rel_parts):
|
|
202
|
+
continue
|
|
203
|
+
files.append(path)
|
|
204
|
+
return files
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def _is_test_path(parts: tuple[str, ...]) -> bool:
|
|
208
|
+
if any(part in {"test", "tests", "spec", "__tests__"} for part in parts[:-1]):
|
|
209
|
+
return True
|
|
210
|
+
filename = parts[-1].lower() if parts else ""
|
|
211
|
+
return (
|
|
212
|
+
filename.startswith("test_")
|
|
213
|
+
or filename.endswith(("_test.py", "_spec.rb"))
|
|
214
|
+
or ".test." in filename
|
|
215
|
+
or ".spec." in filename
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
|
|
177
219
|
def _find_iac_files(root: Path) -> list[Path]:
|
|
178
220
|
"""Find IaC and DevOps files."""
|
|
179
221
|
iac: list[Path] = []
|
|
@@ -198,6 +240,8 @@ def _find_iac_files(root: Path) -> list[Path]:
|
|
|
198
240
|
def _find_test_files(root: Path) -> list[Path]:
|
|
199
241
|
"""Find test files (paths only, not contents)."""
|
|
200
242
|
patterns = [
|
|
243
|
+
"tests/test_*.py", "tests/**/test_*.py",
|
|
244
|
+
"test/test_*.py", "test/**/test_*.py",
|
|
201
245
|
"tests/**/*.test.*", "tests/**/*.spec.*",
|
|
202
246
|
"test/**/*.test.*", "test/**/*.spec.*",
|
|
203
247
|
"src/**/*.test.*", "src/**/*.spec.*",
|
|
@@ -206,11 +250,21 @@ def _find_test_files(root: Path) -> list[Path]:
|
|
|
206
250
|
tests: list[Path] = []
|
|
207
251
|
for pattern in patterns:
|
|
208
252
|
found = list(root.glob(pattern))
|
|
209
|
-
found = [
|
|
253
|
+
found = [
|
|
254
|
+
f for f in found
|
|
255
|
+
if not any(s in _relative_parts(root, f) for s in SKIP_DIRS)
|
|
256
|
+
]
|
|
210
257
|
tests.extend(found)
|
|
211
258
|
return sorted(set(tests))
|
|
212
259
|
|
|
213
260
|
|
|
261
|
+
def _relative_parts(root: Path, path: Path) -> tuple[str, ...]:
|
|
262
|
+
try:
|
|
263
|
+
return path.relative_to(root).parts
|
|
264
|
+
except ValueError:
|
|
265
|
+
return path.parts
|
|
266
|
+
|
|
267
|
+
|
|
214
268
|
def pre_scan(project_root: Path) -> PreScanResult:
|
|
215
269
|
"""Phase 1: Deterministic pre-scan of the project."""
|
|
216
270
|
result = PreScanResult(
|
|
@@ -456,11 +510,11 @@ def run_extract_ai(
|
|
|
456
510
|
Args:
|
|
457
511
|
project_root: Path to the project to extract from.
|
|
458
512
|
ai_command: AI CLI command (e.g. 'claude --print --model claude-opus-4-6').
|
|
459
|
-
output_dir: Output directory (default: {project_root}
|
|
513
|
+
output_dir: Output directory (default: {project_root}/.codd/extract/).
|
|
460
514
|
prompt_file: Path to a custom prompt file. Overrides the built-in baseline preset.
|
|
461
515
|
"""
|
|
462
516
|
project_root = project_root.resolve()
|
|
463
|
-
out = Path(output_dir) if output_dir else project_root / "codd" / "
|
|
517
|
+
out = Path(output_dir) if output_dir else project_root / ".codd" / "extract"
|
|
464
518
|
out.mkdir(parents=True, exist_ok=True)
|
|
465
519
|
|
|
466
520
|
# Phase 1: Pre-scan
|
|
@@ -12,6 +12,7 @@ Two-phase architecture:
|
|
|
12
12
|
import os
|
|
13
13
|
import re
|
|
14
14
|
from dataclasses import dataclass, field
|
|
15
|
+
from datetime import datetime
|
|
15
16
|
from pathlib import Path
|
|
16
17
|
from typing import Any
|
|
17
18
|
|
|
@@ -125,6 +126,59 @@ class ExtractResult:
|
|
|
125
126
|
source_dirs: list[str]
|
|
126
127
|
|
|
127
128
|
|
|
129
|
+
def build_extract_init_metadata(project_root: Path, extracted_at: str | None = None) -> dict[str, str]:
|
|
130
|
+
"""Build generic brownfield extraction metadata for generated YAML/Markdown."""
|
|
131
|
+
timestamp = extracted_at or datetime.now().astimezone().replace(microsecond=0).isoformat()
|
|
132
|
+
return {
|
|
133
|
+
"version": "1.0",
|
|
134
|
+
"extracted_at": timestamp,
|
|
135
|
+
"source": project_root.resolve().as_posix(),
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def add_extract_init_frontmatter(paths: list[Path], metadata: dict[str, str]) -> None:
|
|
140
|
+
"""Add codd init metadata to generated Markdown frontmatter or YAML payloads."""
|
|
141
|
+
for path in paths:
|
|
142
|
+
suffix = path.suffix.lower()
|
|
143
|
+
if suffix in {".md", ".markdown"}:
|
|
144
|
+
_upsert_markdown_codd_metadata(path, metadata)
|
|
145
|
+
elif suffix in {".yaml", ".yml"}:
|
|
146
|
+
_upsert_yaml_codd_metadata(path, metadata)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def _merge_codd_metadata(payload: Any, metadata: dict[str, str]) -> dict[str, Any]:
|
|
150
|
+
if not isinstance(payload, dict):
|
|
151
|
+
payload = {}
|
|
152
|
+
codd = payload.get("codd")
|
|
153
|
+
if not isinstance(codd, dict):
|
|
154
|
+
codd = {}
|
|
155
|
+
codd.update(metadata)
|
|
156
|
+
payload["codd"] = codd
|
|
157
|
+
return payload
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def _upsert_markdown_codd_metadata(path: Path, metadata: dict[str, str]) -> None:
|
|
161
|
+
text = path.read_text(encoding="utf-8")
|
|
162
|
+
match = re.match(r"\A---\s*\n(.*?)\n---\s*\n?", text, re.DOTALL)
|
|
163
|
+
if match:
|
|
164
|
+
frontmatter = yaml.safe_load(match.group(1)) or {}
|
|
165
|
+
body = text[match.end():]
|
|
166
|
+
else:
|
|
167
|
+
frontmatter = {}
|
|
168
|
+
body = text
|
|
169
|
+
|
|
170
|
+
payload = _merge_codd_metadata(frontmatter, metadata)
|
|
171
|
+
rendered = yaml.safe_dump(payload, sort_keys=False, allow_unicode=True)
|
|
172
|
+
separator = "" if body.startswith("\n") else "\n"
|
|
173
|
+
path.write_text(f"---\n{rendered}---\n{separator}{body}", encoding="utf-8")
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def _upsert_yaml_codd_metadata(path: Path, metadata: dict[str, str]) -> None:
|
|
177
|
+
payload = yaml.safe_load(path.read_text(encoding="utf-8")) or {}
|
|
178
|
+
merged = _merge_codd_metadata(payload, metadata)
|
|
179
|
+
path.write_text(yaml.safe_dump(merged, sort_keys=False, allow_unicode=True), encoding="utf-8")
|
|
180
|
+
|
|
181
|
+
|
|
128
182
|
# ═══════════════════════════════════════════════════════════
|
|
129
183
|
# Phase 1: Extract Facts (deterministic, no AI)
|
|
130
184
|
# ═══════════════════════════════════════════════════════════
|
|
@@ -695,28 +749,13 @@ def _detect_patterns(facts: ProjectFacts, project_root: Path):
|
|
|
695
749
|
|
|
696
750
|
|
|
697
751
|
def _detect_python_patterns(facts: ProjectFacts, content: str):
|
|
698
|
-
|
|
699
|
-
"fastapi": "FastAPI", "flask": "Flask", "django": "Django",
|
|
700
|
-
"starlette": "Starlette", "tornado": "Tornado", "aiohttp": "aiohttp",
|
|
701
|
-
}
|
|
702
|
-
orms = {
|
|
703
|
-
"sqlalchemy": "SQLAlchemy", "django": "Django ORM",
|
|
704
|
-
"tortoise-orm": "Tortoise ORM", "peewee": "Peewee",
|
|
705
|
-
"sqlmodel": "SQLModel", "prisma": "Prisma",
|
|
706
|
-
}
|
|
707
|
-
test_fw = {
|
|
708
|
-
"pytest": "pytest", "unittest": "unittest", "nose": "nose2",
|
|
709
|
-
}
|
|
752
|
+
"""No-op: framework/ORM/test detection is delegated to LLM (extract --ai).
|
|
710
753
|
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
facts.detected_orm = name
|
|
717
|
-
for key, name in test_fw.items():
|
|
718
|
-
if key in content.lower() and not facts.detected_test_framework:
|
|
719
|
-
facts.detected_test_framework = name
|
|
754
|
+
Removed in v1.36.0 to honor Generality Gate. Hard-coded framework/ORM/test
|
|
755
|
+
dictionaries violated the constraint that CoDD core must remain stack-agnostic.
|
|
756
|
+
The downstream AI extraction path (codd/extract_ai.py) infers these dynamically.
|
|
757
|
+
"""
|
|
758
|
+
return
|
|
720
759
|
|
|
721
760
|
|
|
722
761
|
def _detect_js_patterns(facts: ProjectFacts, content: str):
|
|
@@ -973,7 +1012,8 @@ def synth_architecture(facts: ProjectFacts, output_dir: Path) -> Path:
|
|
|
973
1012
|
|
|
974
1013
|
def run_extract(project_root: Path, language: str | None = None,
|
|
975
1014
|
source_dirs: list[str] | None = None,
|
|
976
|
-
output: str | None = None
|
|
1015
|
+
output: str | None = None,
|
|
1016
|
+
init_metadata: dict[str, str] | None = None) -> ExtractResult:
|
|
977
1017
|
"""Run full extract pipeline: facts → docs."""
|
|
978
1018
|
|
|
979
1019
|
# Try to load config if it exists
|
|
@@ -994,11 +1034,11 @@ def run_extract(project_root: Path, language: str | None = None,
|
|
|
994
1034
|
# Phase 2: Generate docs
|
|
995
1035
|
if output:
|
|
996
1036
|
output_dir = Path(output)
|
|
997
|
-
elif codd_dir is not None:
|
|
998
|
-
output_dir = codd_dir / "extracted"
|
|
999
1037
|
else:
|
|
1000
|
-
output_dir = project_root / "codd" / "
|
|
1038
|
+
output_dir = project_root / ".codd" / "extract"
|
|
1001
1039
|
generated = synth_docs(facts, output_dir)
|
|
1040
|
+
if init_metadata is not None:
|
|
1041
|
+
add_extract_init_frontmatter(generated, init_metadata)
|
|
1002
1042
|
|
|
1003
1043
|
return ExtractResult(
|
|
1004
1044
|
output_dir=output_dir,
|