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.
Files changed (223) hide show
  1. {codd_dev-1.35.0 → codd_dev-1.36.0}/PKG-INFO +1 -1
  2. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/cli.py +17 -11
  3. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/extract_ai.py +57 -3
  4. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/extractor.py +65 -25
  5. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/parsing.py +390 -0
  6. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/git_patcher.py +15 -12
  7. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/llm_repair_engine.py +105 -27
  8. codd_dev-1.36.0/codd/repair/templates/repair_strategy_meta.md +44 -0
  9. {codd_dev-1.35.0 → codd_dev-1.36.0}/pyproject.toml +1 -1
  10. {codd_dev-1.35.0 → codd_dev-1.36.0}/.gitignore +0 -0
  11. {codd_dev-1.35.0 → codd_dev-1.36.0}/LICENSE +0 -0
  12. {codd_dev-1.35.0 → codd_dev-1.36.0}/README.md +0 -0
  13. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/__init__.py +0 -0
  14. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/__main__.py +0 -0
  15. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/_git_helper.py +0 -0
  16. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/ask_user_question_adapter.py +0 -0
  17. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/assembler.py +0 -0
  18. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/bridge.py +0 -0
  19. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/clustering.py +0 -0
  20. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/coherence_adapters.py +0 -0
  21. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/coherence_engine.py +0 -0
  22. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/config.py +0 -0
  23. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/contracts.py +0 -0
  24. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/coverage_auditor.py +0 -0
  25. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/coverage_metrics.py +0 -0
  26. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/__init__.py +0 -0
  27. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/builder.py +0 -0
  28. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/__init__.py +0 -0
  29. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/depends_on_consistency.py +0 -0
  30. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/deployment_completeness.py +0 -0
  31. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/edge_validity.py +0 -0
  32. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/environment_coverage.py +0 -0
  33. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/implementation_coverage.py +0 -0
  34. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/node_completeness.py +0 -0
  35. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/task_completion.py +0 -0
  36. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/transitive_closure.py +0 -0
  37. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/checks/user_journey_coherence.py +0 -0
  38. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/coverage_axes.py +0 -0
  39. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/cli.yaml +0 -0
  40. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/cpp_embedded.yaml +0 -0
  41. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/csharp.yaml +0 -0
  42. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/elixir.yaml +0 -0
  43. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/generic.yaml +0 -0
  44. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/iot.yaml +0 -0
  45. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/java.yaml +0 -0
  46. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/kotlin.yaml +0 -0
  47. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/mobile.yaml +0 -0
  48. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/ruby.yaml +0 -0
  49. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/rust.yaml +0 -0
  50. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/scala.yaml +0 -0
  51. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/swift.yaml +0 -0
  52. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/test_frameworks.yaml +0 -0
  53. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/defaults/web.yaml +0 -0
  54. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/extractor.py +0 -0
  55. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/dag/runner.py +0 -0
  56. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/defaults.yaml +0 -0
  57. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deploy_targets/__init__.py +0 -0
  58. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deploy_targets/app_service.py +0 -0
  59. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deploy_targets/base.py +0 -0
  60. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deploy_targets/docker_compose.py +0 -0
  61. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployer.py +0 -0
  62. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/__init__.py +0 -0
  63. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/checks/__init__.py +0 -0
  64. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/defaults/deploy_targets.yaml +0 -0
  65. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/defaults/runtime_capability_inference.yaml +0 -0
  66. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/defaults/schema_providers.yaml +0 -0
  67. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/defaults/verification_templates.yaml +0 -0
  68. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/extractor.py +0 -0
  69. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/__init__.py +0 -0
  70. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/ai_command.py +0 -0
  71. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/llm_consideration.py +0 -0
  72. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/schema/__init__.py +0 -0
  73. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/schema/prisma.py +0 -0
  74. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/target/__init__.py +0 -0
  75. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/target/docker_compose.py +0 -0
  76. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/__init__.py +0 -0
  77. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/assertion_handlers.py +0 -0
  78. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/cdp_browser.py +0 -0
  79. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/cdp_engines.py +0 -0
  80. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/cdp_launchers.py +0 -0
  81. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/cdp_wire.py +0 -0
  82. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/curl.py +0 -0
  83. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/form_strategies.py +0 -0
  84. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/means_catalog.py +0 -0
  85. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/deployment/providers/verification/playwright.py +0 -0
  86. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/design_md.py +0 -0
  87. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/diff/__init__.py +0 -0
  88. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/diff/apply.py +0 -0
  89. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/diff/engine.py +0 -0
  90. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/diff/persistence.py +0 -0
  91. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/diff/templates/diff_prompt.md +0 -0
  92. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/drift.py +0 -0
  93. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/e2e_extractor.py +0 -0
  94. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/e2e_generator.py +0 -0
  95. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/e2e_runner.py +0 -0
  96. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/__init__.py +0 -0
  97. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/apply.py +0 -0
  98. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/engine.py +0 -0
  99. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/finding.py +0 -0
  100. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/formatters/__init__.py +0 -0
  101. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/formatters/base.py +0 -0
  102. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/formatters/interactive.py +0 -0
  103. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/formatters/json_fmt.py +0 -0
  104. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/formatters/md.py +0 -0
  105. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/lexicon_loader.py +0 -0
  106. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/persistence.py +0 -0
  107. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/elicit/templates/elicit_prompt_L0.md +0 -0
  108. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/env_refs.py +0 -0
  109. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/fixer.py +0 -0
  110. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/fixup_drift.py +0 -0
  111. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/fixup_drift_strategies/__init__.py +0 -0
  112. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/fixup_drift_strategies/design_token_drift.py +0 -0
  113. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/fixup_drift_strategies/lexicon_violation.py +0 -0
  114. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/fixup_drift_strategies/url_drift.py +0 -0
  115. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/generator.py +0 -0
  116. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/graph.py +0 -0
  117. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/hitl_session.py +0 -0
  118. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/hooks/__init__.py +0 -0
  119. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/hooks/pre-commit +0 -0
  120. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/hooks/recipes/claude_settings_example.json +0 -0
  121. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/hooks/recipes/codex_hook.sh +0 -0
  122. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/hooks/recipes/git_post_commit.sh +0 -0
  123. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/hooks/recipes/git_pre_commit.sh +0 -0
  124. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/implementer/__init__.py +0 -0
  125. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/implementer/chunked_runner.py +0 -0
  126. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/implementer/typecheck_loop.py +0 -0
  127. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/implementer.py +0 -0
  128. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/inheritance.py +0 -0
  129. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/knowledge_fetcher.py +0 -0
  130. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/lexicon.py +0 -0
  131. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/__init__.py +0 -0
  132. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/approval.py +0 -0
  133. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/best_practice_augmenter.py +0 -0
  134. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/criteria_expander.py +0 -0
  135. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/design_doc_extractor.py +0 -0
  136. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/impl_step_deriver.py +0 -0
  137. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/means_catalog_loader.py +0 -0
  138. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/parser.py +0 -0
  139. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/plan_deriver.py +0 -0
  140. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/prompt_builder.py +0 -0
  141. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/strategy_validator.py +0 -0
  142. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/templates/best_practice_augment_meta.md +0 -0
  143. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/templates/criteria_expand_meta.md +0 -0
  144. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/templates/design_doc_extract_meta.md +0 -0
  145. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/templates/impl_step_derive_meta.md +0 -0
  146. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/templates/implementation_step_catalog.yaml +0 -0
  147. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/templates/meta_instruction.md +0 -0
  148. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/templates/plan_derive_meta.md +0 -0
  149. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/llm/templates/verification_means_catalog.yaml +0 -0
  150. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/mcp_server.py +0 -0
  151. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/measure.py +0 -0
  152. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/planner.py +0 -0
  153. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/policy.py +0 -0
  154. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/preflight/__init__.py +0 -0
  155. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/preflight/defaults/cli.yaml +0 -0
  156. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/preflight/defaults/iot.yaml +0 -0
  157. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/preflight/defaults/mobile.yaml +0 -0
  158. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/preflight/defaults/web.yaml +0 -0
  159. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/propagate.py +0 -0
  160. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/propagator.py +0 -0
  161. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/registry.py +0 -0
  162. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/__init__.py +0 -0
  163. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/approval_repair.py +0 -0
  164. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/engine.py +0 -0
  165. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/history.py +0 -0
  166. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/loop.py +0 -0
  167. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/primary_picker.py +0 -0
  168. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/proof_breaks.py +0 -0
  169. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/repair_result.py +0 -0
  170. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/repairability_classifier.py +0 -0
  171. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/schema.py +0 -0
  172. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/templates/analyze_meta.md +0 -0
  173. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/templates/propose_meta.md +0 -0
  174. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/templates/repairability_meta.md +0 -0
  175. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair/verify_runner.py +0 -0
  176. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/repair_slice.py +0 -0
  177. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/require.py +0 -0
  178. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/require_plugins.py +0 -0
  179. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/require_propagate.py +0 -0
  180. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/required_artifacts/defaults/cli.yaml +0 -0
  181. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/required_artifacts/defaults/iot.yaml +0 -0
  182. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/required_artifacts/defaults/mobile.yaml +0 -0
  183. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/required_artifacts/defaults/web.yaml +0 -0
  184. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/required_artifacts_deriver.py +0 -0
  185. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/requirement_completeness/defaults/cli.yaml +0 -0
  186. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/requirement_completeness/defaults/iot.yaml +0 -0
  187. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/requirement_completeness/defaults/mobile.yaml +0 -0
  188. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/requirement_completeness/defaults/web.yaml +0 -0
  189. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/requirement_completeness_auditor.py +0 -0
  190. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/restore.py +0 -0
  191. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/routes_extractor.py +0 -0
  192. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/scanner.py +0 -0
  193. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/schema_refs.py +0 -0
  194. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/screen_flow_validator.py +0 -0
  195. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/screen_transition_extractor.py +0 -0
  196. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/screen_transitions/defaults.yaml +0 -0
  197. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/synth.py +0 -0
  198. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/codd.yaml.tmpl +0 -0
  199. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/conventions.yaml.tmpl +0 -0
  200. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/data_dependencies.yaml.tmpl +0 -0
  201. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/doc_links.yaml.tmpl +0 -0
  202. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/extract_ai_prompt_baseline.md +0 -0
  203. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/extracted/api-contract.md.j2 +0 -0
  204. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/extracted/architecture-overview.md.j2 +0 -0
  205. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/extracted/module-detail.md.j2 +0 -0
  206. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/extracted/schema-design.md.j2 +0 -0
  207. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/extracted/system-context.md.j2 +0 -0
  208. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/gitignore.tmpl +0 -0
  209. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/lexicon_questions.md +0 -0
  210. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/lexicon_schema.yaml +0 -0
  211. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/templates/overrides.yaml.tmpl +0 -0
  212. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/traceability.py +0 -0
  213. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/validator.py +0 -0
  214. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/watch/__init__.py +0 -0
  215. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/watch/events.py +0 -0
  216. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/watch/propagation_log.py +0 -0
  217. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/watch/propagation_pipeline.py +0 -0
  218. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/watch/test_runner.py +0 -0
  219. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/watch/watcher.py +0 -0
  220. {codd_dev-1.35.0 → codd_dev-1.36.0}/codd/wiring.py +0 -0
  221. {codd_dev-1.35.0 → codd_dev-1.36.0}/docs/cookbook/cdp_browser/README.md +0 -0
  222. {codd_dev-1.35.0 → codd_dev-1.36.0}/docs/requirements/README.md +0 -0
  223. {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.35.0
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
- if default_dir.exists():
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: <config-dir>/extracted/)")
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 the discovered CoDD config dir as draft documents
2253
- (`codd/extracted/` or `.codd/extracted/`). Review and promote
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 bootstrap_codd_dir / "extracted"
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 = [f for f in found if not any(s in f.parts for s in SKIP_DIRS)]
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}/codd/extracted/).
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" / "extracted"
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
- frameworks = {
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
- for key, name in frameworks.items():
712
- if key in content.lower():
713
- facts.detected_frameworks.append(name)
714
- for key, name in orms.items():
715
- if key in content.lower() and not facts.detected_orm:
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) -> ExtractResult:
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" / "extracted"
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,