yaga-cli 0.1.2__tar.gz → 0.2.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 (337) hide show
  1. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/CONTRIBUTING.md +39 -1
  2. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/PKG-INFO +1 -1
  3. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/changelog.md +22 -0
  4. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/ci-adoption.md +6 -0
  5. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/commands.md +2 -1
  6. yaga_cli-0.2.0/docs/commit-policy-direction.md +83 -0
  7. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/commit-policy.md +180 -0
  8. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/configuration.md +30 -1
  9. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/contributing.md +3 -0
  10. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/getting-started.md +1 -1
  11. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/github-actions.md +34 -1
  12. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/pyproject.toml +1 -1
  13. yaga_cli-0.2.0/release-notes.md +21 -0
  14. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commands/commit.py +33 -0
  15. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commands/config.py +11 -3
  16. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commits/checker.py +70 -42
  17. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commits/config.py +136 -20
  18. yaga_cli-0.2.0/src/yaga/commits/config_explain.py +35 -0
  19. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commits/config_init.py +64 -5
  20. yaga_cli-0.2.0/src/yaga/commits/content_policy.py +81 -0
  21. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commits/github_event.py +51 -4
  22. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commits/github_reporting.py +53 -42
  23. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commits/models.py +40 -4
  24. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commits/parser.py +49 -2
  25. yaga_cli-0.2.0/src/yaga/commits/policy.py +16 -0
  26. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commits/reporting.py +25 -1
  27. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commits/service.py +4 -1
  28. yaga_cli-0.2.0/src/yaga/commits/severity.py +54 -0
  29. yaga_cli-0.2.0/src/yaga/commits/template.py +96 -0
  30. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commits/typos.py +2 -1
  31. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/repository/reporting.py +3 -2
  32. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/version_requirement.py +1 -1
  33. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_cli.py +3 -1
  34. yaga_cli-0.2.0/tests/test_commit_body_customization.py +123 -0
  35. yaga_cli-0.2.0/tests/test_commit_content_policy.py +148 -0
  36. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_commit_reporting.py +4 -0
  37. yaga_cli-0.2.0/tests/test_commit_template.py +78 -0
  38. yaga_cli-0.2.0/tests/test_commit_warnings.py +212 -0
  39. yaga_cli-0.2.0/tests/test_config_workflows.py +111 -0
  40. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_consumer_policy_entrypoints.py +66 -1
  41. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_installation.py +2 -2
  42. yaga_cli-0.2.0/tests/test_plain_messages.py +103 -0
  43. yaga_cli-0.2.0/tests/test_pr_proposed_message.py +183 -0
  44. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/uv.lock +1 -1
  45. yaga_cli-0.1.2/release-notes.md +0 -22
  46. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/.gitattributes +0 -0
  47. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/.github/dependabot.yml +0 -0
  48. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/.github/workflows/ci.yml +0 -0
  49. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/.github/workflows/commit-adoption-qualification.yml +0 -0
  50. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/.github/workflows/commit-policy.yml +0 -0
  51. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/.github/workflows/commit-quality.yml +0 -0
  52. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/.github/workflows/docs.yml +0 -0
  53. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/.github/workflows/release.yml +0 -0
  54. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/.gitignore +0 -0
  55. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/.pre-commit-hooks.yaml +0 -0
  56. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/.yaga/branch-policy.toml +0 -0
  57. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/.yaga/change-policy.toml +0 -0
  58. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/.yaga/checks/ci.toml +0 -0
  59. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/.yaga/mode-policy.toml +0 -0
  60. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/.yaga/path-policy.toml +0 -0
  61. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/.yaga/size-policy.toml +0 -0
  62. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/.yaga/tree-policy.toml +0 -0
  63. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/AGENTS.md +0 -0
  64. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/CHANGELOG.md +0 -0
  65. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/LICENSE +0 -0
  66. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/Makefile +0 -0
  67. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/README.md +0 -0
  68. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/SECURITY.md +0 -0
  69. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/action.yml +0 -0
  70. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/actions/commit-check/action.yml +0 -0
  71. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/agent-review-gate.md +0 -0
  72. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/assets/branding/isometric_terminal_y_logo.png +0 -0
  73. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/assets/branding/isometric_terminal_y_logo_transparent.png +0 -0
  74. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/assets/branding/yaga_cli_brand_concept_board.png +0 -0
  75. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/branch-policy.md +0 -0
  76. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/change-policy.md +0 -0
  77. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/commit-quality.md +0 -0
  78. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/github-review-adapter.md +0 -0
  79. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/index.md +0 -0
  80. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/install.ps1 +0 -0
  81. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/install.sh +0 -0
  82. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/mode-policy.md +0 -0
  83. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/path-policy.md +0 -0
  84. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/recipes.md +0 -0
  85. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/releasing.md +0 -0
  86. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/repository-checks.md +0 -0
  87. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/repository-plans.md +0 -0
  88. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/security.md +0 -0
  89. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/size-policy.md +0 -0
  90. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/stylesheets/extra.css +0 -0
  91. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/tree-policy.md +0 -0
  92. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/troubleshooting.md +0 -0
  93. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/usage.md +0 -0
  94. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/docs/workflow-checks.md +0 -0
  95. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/examples/agent-review-policy.toml +0 -0
  96. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/examples/agent-review-results.json +0 -0
  97. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/examples/agent-review.yml +0 -0
  98. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/examples/commit-policy.yml +0 -0
  99. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/examples/review-policy.yml +0 -0
  100. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/overrides/404.html +0 -0
  101. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/scripts/check_build.py +0 -0
  102. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/scripts/check_description.py +0 -0
  103. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/scripts/check_docs.py +0 -0
  104. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/scripts/check_release.py +0 -0
  105. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/scripts/composite_smoke_python +0 -0
  106. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/scripts/prepare_commit_action_control.py +0 -0
  107. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/__init__.py +0 -0
  108. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/__main__.py +0 -0
  109. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/_update_worker.py +0 -0
  110. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/action.py +0 -0
  111. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/action_cli.py +0 -0
  112. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/agent_review/__init__.py +0 -0
  113. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/agent_review/evaluation.py +0 -0
  114. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/agent_review/github/__init__.py +0 -0
  115. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/agent_review/github/boundary.py +0 -0
  116. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/agent_review/github/candidate.py +0 -0
  117. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/agent_review/github/constants.py +0 -0
  118. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/agent_review/github/events.py +0 -0
  119. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/agent_review/github/evidence.py +0 -0
  120. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/agent_review/github/gate.py +0 -0
  121. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/agent_review/github/publication.py +0 -0
  122. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/agent_review/github/requests.py +0 -0
  123. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/agent_review/github/runs.py +0 -0
  124. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/agent_review/github/runtime.py +0 -0
  125. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/agent_review/plan.py +0 -0
  126. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/agent_review/policy.py +0 -0
  127. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/agent_review/results.py +0 -0
  128. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/agent_review/runtime.py +0 -0
  129. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/branches/__init__.py +0 -0
  130. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/branches/checker.py +0 -0
  131. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/branches/models.py +0 -0
  132. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/branches/patterns.py +0 -0
  133. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/branches/policy.py +0 -0
  134. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/branches/reporting.py +0 -0
  135. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/branches/service.py +0 -0
  136. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/changes/__init__.py +0 -0
  137. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/changes/checker.py +0 -0
  138. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/changes/git.py +0 -0
  139. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/changes/models.py +0 -0
  140. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/changes/patterns.py +0 -0
  141. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/changes/policy.py +0 -0
  142. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/changes/reporting.py +0 -0
  143. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/changes/service.py +0 -0
  144. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/cli.py +0 -0
  145. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commands/__init__.py +0 -0
  146. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commands/branch.py +0 -0
  147. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commands/change.py +0 -0
  148. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commands/gate.py +0 -0
  149. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commands/github.py +0 -0
  150. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commands/mode.py +0 -0
  151. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commands/path.py +0 -0
  152. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commands/repo.py +0 -0
  153. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commands/self_manage.py +0 -0
  154. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commands/size.py +0 -0
  155. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commands/tree.py +0 -0
  156. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commands/workflow.py +0 -0
  157. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commit_action_cli.py +0 -0
  158. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commit_action_runtime.py +0 -0
  159. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commits/__init__.py +0 -0
  160. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commits/git.py +0 -0
  161. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commits/quality.py +0 -0
  162. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commits/sources.py +0 -0
  163. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/commits/trusted_policy.py +0 -0
  164. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/config_scope.py +0 -0
  165. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/errors.py +0 -0
  166. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/files.py +0 -0
  167. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/git/__init__.py +0 -0
  168. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/git/process.py +0 -0
  169. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/git/runtime.py +0 -0
  170. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/git/tree.py +0 -0
  171. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/github.py +0 -0
  172. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/models.py +0 -0
  173. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/modes/__init__.py +0 -0
  174. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/modes/checker.py +0 -0
  175. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/modes/git.py +0 -0
  176. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/modes/models.py +0 -0
  177. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/modes/patterns.py +0 -0
  178. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/modes/policy.py +0 -0
  179. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/modes/reporting.py +0 -0
  180. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/modes/service.py +0 -0
  181. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/paths/__init__.py +0 -0
  182. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/paths/checker.py +0 -0
  183. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/paths/git.py +0 -0
  184. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/paths/models.py +0 -0
  185. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/paths/policy.py +0 -0
  186. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/paths/reporting.py +0 -0
  187. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/paths/service.py +0 -0
  188. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/repository/__init__.py +0 -0
  189. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/repository/checker.py +0 -0
  190. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/repository/models.py +0 -0
  191. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/repository/plan.py +0 -0
  192. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/self_update.py +0 -0
  193. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/sizes/__init__.py +0 -0
  194. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/sizes/checker.py +0 -0
  195. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/sizes/git.py +0 -0
  196. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/sizes/models.py +0 -0
  197. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/sizes/patterns.py +0 -0
  198. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/sizes/policy.py +0 -0
  199. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/sizes/reporting.py +0 -0
  200. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/sizes/service.py +0 -0
  201. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/status.py +0 -0
  202. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/trees/__init__.py +0 -0
  203. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/trees/checker.py +0 -0
  204. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/trees/git.py +0 -0
  205. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/trees/models.py +0 -0
  206. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/trees/patterns.py +0 -0
  207. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/trees/policy.py +0 -0
  208. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/trees/reporting.py +0 -0
  209. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/trees/service.py +0 -0
  210. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/workflows/__init__.py +0 -0
  211. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/workflows/actionlint_runtime.py +0 -0
  212. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/workflows/actionlint_snapshot.py +0 -0
  213. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/workflows/checker.py +0 -0
  214. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/workflows/inputs.py +0 -0
  215. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/workflows/lint.py +0 -0
  216. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/workflows/models.py +0 -0
  217. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/workflows/parser.py +0 -0
  218. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/workflows/references.py +0 -0
  219. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/workflows/reporting.py +0 -0
  220. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/workflows/security.py +0 -0
  221. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/workflows/security_facts.py +0 -0
  222. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/workflows/security_models.py +0 -0
  223. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/workflows/security_reporting.py +0 -0
  224. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/workflows/security_rules.py +0 -0
  225. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/src/yaga/workflows/yaml.py +0 -0
  226. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/__init__.py +0 -0
  227. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/codex_support.py +0 -0
  228. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/fixtures/commit_consumer_parity.json +0 -0
  229. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_action.py +0 -0
  230. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_agent_review_cli.py +0 -0
  231. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_agent_review_evaluation.py +0 -0
  232. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_agent_review_plan.py +0 -0
  233. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_agent_review_policy.py +0 -0
  234. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_agent_review_results.py +0 -0
  235. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_branch_checker.py +0 -0
  236. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_branch_cli.py +0 -0
  237. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_branch_models.py +0 -0
  238. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_branch_patterns.py +0 -0
  239. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_branch_policy.py +0 -0
  240. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_branch_reporting.py +0 -0
  241. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_branch_service.py +0 -0
  242. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_change_checker.py +0 -0
  243. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_change_cli.py +0 -0
  244. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_change_git.py +0 -0
  245. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_change_patterns.py +0 -0
  246. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_change_policy.py +0 -0
  247. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_change_reporting.py +0 -0
  248. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_codex_events.py +0 -0
  249. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_codex_evidence.py +0 -0
  250. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_codex_evidence_literals.py +0 -0
  251. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_codex_gate.py +0 -0
  252. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_codex_publication.py +0 -0
  253. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_codex_requests.py +0 -0
  254. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_codex_runs.py +0 -0
  255. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_codex_runtime.py +0 -0
  256. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_commit_action.py +0 -0
  257. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_commit_action_controls.py +0 -0
  258. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_commit_checker.py +0 -0
  259. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_commit_config.py +0 -0
  260. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_commit_consumer_policy.py +0 -0
  261. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_commit_explicit_inputs.py +0 -0
  262. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_commit_git.py +0 -0
  263. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_commit_parser.py +0 -0
  264. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_commit_quality.py +0 -0
  265. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_commit_quality_workflow.py +0 -0
  266. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_commit_service.py +0 -0
  267. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_commit_sources.py +0 -0
  268. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_commit_trusted_policy.py +0 -0
  269. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_commit_typos.py +0 -0
  270. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_config_init.py +0 -0
  271. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_description.py +0 -0
  272. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_docs_links.py +0 -0
  273. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_files.py +0 -0
  274. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_git_runtime.py +0 -0
  275. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_git_tree.py +0 -0
  276. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_github.py +0 -0
  277. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_github_pull_request.py +0 -0
  278. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_github_reporting.py +0 -0
  279. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_installers.py +0 -0
  280. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_mode_checker.py +0 -0
  281. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_mode_cli.py +0 -0
  282. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_mode_git.py +0 -0
  283. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_mode_models.py +0 -0
  284. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_mode_patterns.py +0 -0
  285. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_mode_policy.py +0 -0
  286. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_mode_reporting.py +0 -0
  287. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_mode_service.py +0 -0
  288. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_models.py +0 -0
  289. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_path_checker.py +0 -0
  290. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_path_cli.py +0 -0
  291. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_path_git.py +0 -0
  292. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_path_models.py +0 -0
  293. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_path_policy.py +0 -0
  294. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_path_reporting.py +0 -0
  295. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_path_service.py +0 -0
  296. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_release.py +0 -0
  297. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_repo_cli.py +0 -0
  298. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_repository_checker.py +0 -0
  299. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_repository_contract.py +0 -0
  300. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_repository_models.py +0 -0
  301. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_repository_plan.py +0 -0
  302. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_repository_reporting.py +0 -0
  303. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_size_checker.py +0 -0
  304. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_size_cli.py +0 -0
  305. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_size_git.py +0 -0
  306. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_size_models.py +0 -0
  307. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_size_patterns.py +0 -0
  308. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_size_policy.py +0 -0
  309. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_size_reporting.py +0 -0
  310. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_size_service.py +0 -0
  311. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_status.py +0 -0
  312. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_tooling.py +0 -0
  313. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_tree_checker.py +0 -0
  314. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_tree_cli.py +0 -0
  315. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_tree_git.py +0 -0
  316. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_tree_models.py +0 -0
  317. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_tree_patterns.py +0 -0
  318. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_tree_policy.py +0 -0
  319. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_tree_reporting.py +0 -0
  320. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_tree_service.py +0 -0
  321. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_workflow_checker.py +0 -0
  322. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_workflow_inputs.py +0 -0
  323. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_workflow_lint.py +0 -0
  324. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_workflow_lint_hardening.py +0 -0
  325. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_workflow_lint_reporting.py +0 -0
  326. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_workflow_provider_inputs.py +0 -0
  327. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_workflow_references.py +0 -0
  328. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_workflow_reporting.py +0 -0
  329. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_workflow_security_cli.py +0 -0
  330. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_workflow_security_facts.py +0 -0
  331. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_workflow_security_models.py +0 -0
  332. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_workflow_security_reporting.py +0 -0
  333. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_workflow_security_rules.py +0 -0
  334. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_workflow_security_selection.py +0 -0
  335. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_workflow_security_service.py +0 -0
  336. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/tests/test_workflow_yaml.py +0 -0
  337. {yaga_cli-0.1.2 → yaga_cli-0.2.0}/zensical.toml +0 -0
@@ -95,8 +95,14 @@ complete commit messages: the pull-request title adapter deliberately uses the h
95
95
  `body-min-words` is a schema-v1 integer from zero through 100000 with a zero default. It counts only
96
96
  Unicode-whitespace-delimited prose-body tokens containing a Unicode alphanumeric character;
97
97
  recognized final footers and punctuation-only or emoji-only tokens are excluded. A nonzero value
98
- does not require an absent optional body, and it is invalid with a forbidden body. Keep its
98
+ does not require an absent optional body, and it is invalid when every reachable body policy
99
+ is forbidden. Per-type forbidden bodies do not receive additional minimum findings. Keep its
99
100
  `body.word-count` diagnostic stable across text, JSON, and GitHub reports.
101
+ `body-policy-by-type` is an empty-default schema-v1 mapping with the same bounded, case-insensitive
102
+ type-key validation as scope overrides. It replaces body presence only; all other checks remain
103
+ independent. `body-max-length` is an optional 1-through-100000 total prose limit in the configured
104
+ length unit, excluding recognized final footers. Reject impossible length/word-minimum bounds,
105
+ preserve `body.length`, and keep all body policies out of title-only checks.
100
106
  `required-footer-tokens` and `forbidden-footer-tokens` are schema-v1 presence policies for complete
101
107
  commits only; pull-request titles remain header-only. Match exact tokens case-insensitively in both
102
108
  `Token: value` and `Token #value` forms, allow repeats, and do not infer identity, DCO compliance,
@@ -447,3 +453,35 @@ triggers, fixed environment names, action SHA, and absence of legacy writers.
447
453
  Run `uv run make ci` before every push. Use Conventional Commit subjects. Preserve behavior,
448
454
  motivation, security boundary, failure mode, migration impact, and validation in the retained commit
449
455
  and PR. Fold review fixes and CI repairs into the logical commit they correct.
456
+
457
+ Keep `pull-request-message` closed to `title-only` (default) and `title-and-body`. The opt-in
458
+ GitHub event check composes literal title, blank line, and bounded UTF-8 body; null/missing bodies
459
+ are empty. Preserve the independent title result, optional schema-v1 `proposed_message` result,
460
+ full policy and spelling checks, body-edit wakes, and pre-exemption event/range validation.
461
+ Do not infer merge settings or claim the proposed text is the final merged commit.
462
+
463
+ Keep config starter names frozen and the no-option recommended-v1 bytes unchanged. New starters
464
+ must pass the normal loader and preserve atomic no-overwrite publication, race checks, and dry-run
465
+ cleanup. Type explanations must share override resolution with validation, remain bounded and
466
+ sanitized, and never imply that list membership alone proves a message valid.
467
+
468
+ Keep required-issue-prefixes and footer-values empty by default and full-message-only. References
469
+ are bounded standalone prefix-plus-positive-ASCII-ID tokens, never unrestricted regexes or network
470
+ lookups. Footer values reuse the parser's final suffix and token boundaries, check every occurrence,
471
+ trim outer whitespace, compare values exactly, and emit at most one footer.value finding per token.
472
+ Presence remains separate. Preserve configuration bounds and reject forbidden/breaking token
473
+ constraints; neither reference syntax nor footer labels prove external state or identity.
474
+
475
+ Keep warning-rules empty by default and closed to the documented configurable diagnostic codes.
476
+ Never demote syntax/resource/merge-selection failures or operational errors. Commit reports always use
477
+ schema v1 with explicit diagnostic severity and warning_count, including clean, empty, and skipped
478
+ results. Diagnostic identity/order is stable, warning-only targets pass, and warning_count counts findings,
479
+ not targets. Preserve severity through spelling, PR checks, and aggregate repository annotations;
480
+ repository/error/config/quality envelopes retain their independent existing schema contracts.
481
+
482
+ Keep message-format explicit and default conventional. Plain headers use a separate parser with no
483
+ invented type/scope/breaking marker, sharing only content/footer parsing and applicable policy.
484
+ Reject conventional-only config and warnings in plain mode. Message templates must remain stdout-only
485
+ and deliberately incomplete, with explicit conventional components, no invented description or
486
+ footer values, and an explicit supported editor comment character. Validate component input before
487
+ ignored-header policy can bypass it; never modify Git configuration or commit history.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: yaga-cli
3
- Version: 0.1.2
3
+ Version: 0.2.0
4
4
  Summary: Configurable developer workflow checks for local use and GitHub Actions
5
5
  Project-URL: Documentation, https://dariuszpanas.github.io/yaga/
6
6
  Project-URL: Changelog, https://dariuszpanas.github.io/yaga/changelog.html
@@ -2,6 +2,28 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.2.0] - 2026-09-20
6
+
7
+ ### Added
8
+
9
+ - Support explicit plain-message policy and a frozen `plain-v1` starter; print incomplete,
10
+ policy-guided drafts with `commit template` without changing files or Git.
11
+
12
+ - Introduce opt-in `warning-rules` for gradual policy adoption, with consistent schema-v1 commit
13
+ reports containing severity and warning counts, and nonblocking annotations.
14
+
15
+ - Require bounded work-item references and constrain exact footer values through opt-in
16
+ `required-issue-prefixes` and `footer-values` settings.
17
+
18
+ - Add frozen editable workflow starters and `config show --type` explanations of effective
19
+ body/scope overrides, preserving the existing default starter.
20
+
21
+ - Validate proposed PR title-plus-description messages with opt-in `pull-request-message`,
22
+ reusing full commit policy and reporting the proposed message separately.
23
+
24
+ - Allow per-type body requirements with `body-policy-by-type` and cap total prose with
25
+ `body-max-length`, preserving existing defaults and independent title checks.
26
+
5
27
  ## [0.1.2] - 2026-09-20
6
28
 
7
29
  ### Fixed
@@ -36,6 +36,12 @@ Inspect the target repository's existing policy before creating one. Run the sel
36
36
  known good and known failing inputs. Review findings and agree on policy before requiring the job.
37
37
  The [adoption recipes](recipes.md) provide concrete commands and policy examples.
38
38
 
39
+ For commit adoption, choose a [workflow starter](commit-policy.md#workflow-starters-and-type-explanations)
40
+ that matches how changes reach the main branch. Plain messages and Conventional Commits are explicit
41
+ choices. Selected policy findings can begin as [warnings](commit-policy.md#gradual-enforcement) while
42
+ input and operational failures remain blocking. If PR descriptions become merge messages, enable
43
+ [proposed-message checks](github-actions.md#proposed-merge-messages) as well.
44
+
39
45
  Keep policy in the target repository. Reuse it in CI rather than duplicating policy arguments in
40
46
  workflow files. A [repository plan](repository-plans.md) is useful once several checks need the
41
47
  same selection; branch and change checks remain separate commands.
@@ -10,7 +10,8 @@ or `yaga self update --dry-run` to verify a uv tool installation without updatin
10
10
 
11
11
  | Command | Input | Reference |
12
12
  | --- | --- | --- |
13
- | `yaga commit check` | One message, file, stdin, commit, or range | [Commit policy](commit-policy.md) |
13
+ | `yaga commit check` | One title, message, editor file, file, stdin, commit, or range | [Commit policy](commit-policy.md) |
14
+ | `yaga commit template` | Selected policy and explicit conventional type/scope, or plain format | [Authoring help](commit-policy.md#read-only-message-templates) |
14
15
  | `yaga config init` / `show` | Target repository or explicit configuration | [Configuration](configuration.md) |
15
16
  | `yaga branch check` | Explicit short branch name and policy | [Branch policy](branch-policy.md) |
16
17
  | `yaga change check` | Explicit Git range and policy | [Changed-path policy](change-policy.md) |
@@ -0,0 +1,83 @@
1
+ # Commit policy direction for 0.2.0
2
+
3
+ This records the design decisions behind YAGA 0.2.0. See [commit policy](commit-policy.md)
4
+ for supported configuration and [the changelog](changelog.md) for release scope.
5
+
6
+ ## The problem to solve
7
+
8
+ A useful commit records what changed and enough context to understand why. Teams also use its
9
+ structure for release classification, issue references, and review policy. These are different
10
+ needs: passing a punctuation rule does not prove a message is useful, and a long body can be
11
+ less helpful than a short explanation.
12
+
13
+ YAGA should make those choices explicit and apply them consistently to the inputs a project
14
+ actually uses: local messages, editor files, historical commits, and pull-request titles.
15
+ Configuration should describe policy without requiring a program to execute it.
16
+
17
+ ## What the surrounding tools teach us
18
+
19
+ - [commitlint](https://commitlint.js.org/reference/rules.html) offers detailed component rules;
20
+ its [rule configuration](https://commitlint.js.org/reference/rules-configuration.html) also
21
+ separates severity from conditions. The useful lesson is control and gradual adoption,
22
+ not copying every casing convention or inversion into YAGA.
23
+ - [Gitlint](https://jorisroovers.com/gitlint/latest/rules/builtin_rules/) emphasizes readability,
24
+ configurable limits, and tailored rules, including checks beyond conventional structure.
25
+ Its [configuration precedence](https://jorisroovers.com/gitlint/latest/configuration/) permits
26
+ message-level overrides. YAGA should keep policy outside the message being evaluated.
27
+ - [Commitizen](https://commitizen-tools.github.io/commitizen/commands/check/) puts validation
28
+ alongside authoring and release commands. Helping users prepare a valid message is valuable;
29
+ quietly exempting broad text prefixes is not the same as verifying a Git merge identity.
30
+ - [Cocogitto](https://docs.cocogitto.io/reference/config.html) connects commit conventions with
31
+ versioning, changelogs, and monorepos. YAGA should provide dependable checks and reports
32
+ without requiring users to replace their release tooling.
33
+ - [git-cliff](https://git-cliff.org/docs/configuration/git/) demonstrates the downstream need
34
+ for classification and reference extraction. Checking stored input and transforming release
35
+ notes should remain separate operations.
36
+ - [semantic-pull-request](https://github.com/amannn/action-semantic-pull-request) focuses on the
37
+ title that often becomes a squash commit. The meaningful input depends on merge strategy;
38
+ validating every intermediate commit is not universally the best default workflow.
39
+
40
+ These are observations from the tools' primary documentation, reviewed on 2026-09-20. They are
41
+ not a popularity ranking or a promise of compatibility with their configurations.
42
+
43
+ ## YAGA's place
44
+
45
+ YAGA combines message checks with workflow and committed-tree policy, explicit Git selection,
46
+ bounded processing, and shared local/CI reporting. Its trusted GitHub adapter can verify the
47
+ event and checked-out objects before applying account exemptions. Those properties are worth
48
+ preserving as customization grows.
49
+
50
+ The 0.2.0 work addresses flexibility and usability: per-type body requirements, nonblocking
51
+ warnings, bounded references and footer values, and policy-guided authoring templates. An explicit
52
+ plain-message format allows readability checks without requiring Conventional Commit structure.
53
+
54
+ ## Defaults and customization
55
+
56
+ Keep structural validity separate from style. Do not impose universal capitalization, punctuation,
57
+ mandatory prose, dictionaries, or artificial minimum lengths. A project may enable these choices,
58
+ but the documentation must say what each rule measures and what it cannot prove.
59
+
60
+ Keep existing schema-v1 defaults stable. A future recommended setup should generate explicit,
61
+ editable choices or select a frozen versioned profile. It must not silently change existing
62
+ repositories when YAGA is upgraded. Unknown keys and contradictory requirements should fail
63
+ before checking messages. Project configuration remains independent of global fallback settings.
64
+
65
+ Add customization in bounded, named forms. Do not put commands, imports, message-controlled
66
+ waivers, or unrestricted regular expressions into policy. Optional authoring assistance should
67
+ preview changes; checking must never rewrite history or alter its input.
68
+
69
+ ## Implemented choices
70
+
71
+ 1. **Content requirements:** require bodies for selected types without skipping other checks;
72
+ bound total prose independently of line wrapping. Preserve optional-body and title-only behavior.
73
+ 2. **Understandable configuration:** explain effective settings and overrides; offer editable
74
+ starter policies for squash-title and full-message workflows.
75
+ 3. **References and trailers:** use bounded project-specific reference and footer-value
76
+ constraints. Token presence must never be presented as verified identity or completed testing.
77
+ 4. **Gradual enforcement:** configure warning/error policy with one schema-v1 report shape and
78
+ unchanged input-error precedence. Only explicitly selected policy findings become warnings.
79
+ 5. **Alternative message formats and authoring:** offer an explicit plain-message mode and
80
+ configuration-derived message templates. Retain a clear conventional parser boundary.
81
+
82
+ Full release/changelog automation, arbitrary plugin execution, and automatic commit rewriting are
83
+ not necessary to make commit checking useful. Keep them outside this first 0.2.0 scope.
@@ -272,3 +272,183 @@ parent, or global configuration discovery. Custom dictionaries are currently uns
272
272
  trusted mode: neither a PR's `_typos.toml` nor dirty files in the trusted checkout can weaken it.
273
273
  Ordinary local checks and the default PR-head mode retain repository Typos configuration.
274
274
  Keep the tool version consistent when comparing local and CI spelling results.
275
+
276
+ ## Proposed PR messages
277
+
278
+ `pull-request-message = "title-and-body"` opts into full commit policy for the PR title and
279
+ description together. The default is `"title-only"`. This setting affects only event-aware
280
+ PR checks; see [GitHub Actions](github-actions.md#proposed-merge-messages)
281
+ for merge settings, event triggers, reporting, and limitations.
282
+
283
+ ## Workflow starters and type explanations
284
+
285
+ Start with explicit, editable settings for your workflow:
286
+
287
+ ```bash
288
+ yaga config init --starter title-v1 --dry-run
289
+ yaga config init --starter complete-message-v1
290
+ yaga config show --type fix
291
+ yaga config show --type docs --format json
292
+ ```
293
+
294
+ `config init` without `--starter` retains the original `recommended-v1` starter byte for byte.
295
+ `title-v1` uses lowercase types and a 100-character header limit, allows ending punctuation,
296
+ leaves bodies optional, and ignores Git-proven merge commits. It does not disable checks on
297
+ commits selected by the caller. `complete-message-v1` uses the same choices and additionally
298
+ requires prose for `feat` and `fix`; other types remain optional. Neither starter imposes a
299
+ word count or restricts the set of types. Their names are frozen: future recommendations need
300
+ new names. Generated TOML is yours to edit, and initialization never replaces existing policy.
301
+ `--dry-run` validates and reports the proposed policy without publishing a configuration file.
302
+
303
+ Both starters retain title-only PR checks. If the PR description is your proposed merge body,
304
+ explicitly enable `pull-request-message = "title-and-body"` as described above. Full-message
305
+ requirements apply to actual commits and enabled proposed messages, never standalone titles.
306
+
307
+ `config show --type TYPE` adds the effective body and scope requirements and names the override
308
+ or global setting that supplied each. Matching is case-insensitive, just as in the checker.
309
+ The JSON report adds `effective_type` only when requested. `listed_type_allowed` tells you whether
310
+ the configured type list admits the token; it does not evaluate type casing or prove a complete
311
+ message will pass. All independent casing, scope-list, length, footer, and other rules still apply.
312
+
313
+ The reported `config_path` identifies the single selected file, or built-in defaults. A project
314
+ configuration replaces the global fallback as a whole; fields are not merged between files.
315
+ For trusted Actions, inspect the committed default-branch policy used by that runner: a local
316
+ `config show` does not reproduce a trusted Action's revision selection automatically.
317
+
318
+ ## References and footer values
319
+
320
+ To require a work-item reference and a controlled validation label in complete messages:
321
+
322
+ ```toml
323
+ [tool.yaga.commit]
324
+ required-issue-prefixes = ["#", "PROJ-"]
325
+ required-footer-tokens = ["Validation"]
326
+ footer-values = {Validation = ["passed", "not-run"]}
327
+ ```
328
+
329
+ Both new settings default to empty and apply only to complete messages, including opted-in
330
+ proposed PR messages. Standalone titles and the independent PR title result remain header-only.
331
+ A full message with neither `#123` nor `PROJ-123` reports `reference.required`.
332
+
333
+ References are case-sensitive whitespace-delimited tokens, optionally wrapped in the punctuation
334
+ `()` `[]` `{}` `<>` `,` `.` `;` `:` `!` `?` or ASCII quotation marks. A configured prefix must be followed
335
+ by 1–20 ASCII digits, beginning with 1–9. `(#123).` matches; `#0`, `#012`, `prefix#123`, and
336
+ `https://example.com/#123` do not. References may appear in the header, prose, or final footers.
337
+ Markdown links, URLs, and tracker-specific query syntax are not interpreted. Prefixes start with
338
+ an ASCII letter or `#`, followed by ASCII letters, digits, `_`, or `-`; there are at most 128 unique
339
+ prefixes of at most 64 characters. Matching uses a bounded prefix tree over the already bounded
340
+ message rather than user-supplied regular expressions.
341
+
342
+ `footer-values` constrains every occurrence of each configured final footer token, matching tokens
343
+ case-insensitively and values case-sensitively. It does not require the token to occur: combine it
344
+ with `required-footer-tokens` when presence is mandatory. Values are the complete parsed footer
345
+ value up to the next recognized token, with outer whitespace removed. A multiline value must match
346
+ as a whole, so it cannot satisfy a configured single-line choice by adding an approved first line.
347
+ Each offending token produces one source-located `footer.value` diagnostic. The configured footer
348
+ syntax and paragraph boundary still determine which text is a footer; prose that resembles a
349
+ trailer is not silently reclassified. With hash separators, `Refs #123` has value `123`.
350
+
351
+ The table allows up to 128 unique case-insensitive tokens and 256 total choices, with at most 128
352
+ choices per token. Each choice is a nonempty safe single-line string of at most 256 characters,
353
+ without outer whitespace; duplicates are rejected. Breaking-change tokens and tokens forbidden
354
+ by `forbidden-footer-tokens` cannot have value constraints.
355
+
356
+ These options verify stored syntax only. A reference does not prove that an issue exists or is
357
+ resolved. A `Validation: passed` label does not prove that tests ran. An allowed sign-off value
358
+ would not prove identity, DCO compliance, or a cryptographic signature.
359
+
360
+ ## Gradual enforcement
361
+
362
+ Keep a rule enabled while introducing it as a nonblocking warning:
363
+
364
+ ```toml
365
+ [tool.yaga.commit]
366
+ body-policy = "required"
367
+ body-min-words = 8
368
+ warning-rules = ["body.required", "body.word-count"]
369
+ ```
370
+
371
+ `warning-rules` defaults to empty. Only the listed diagnostic codes become warnings; other findings
372
+ remain errors. A warning does not enable a rule: configure its underlying policy as usual.
373
+ Remove a code from the list when you want its findings to block validation. Messages cannot waive
374
+ or change severity themselves. The same policy applies locally, in the read-only Action, to opted-in
375
+ proposed PR messages, and in the commit provider of `repo check`.
376
+
377
+ Supported codes are `type.allowed`, `type.case`, `scope.required`, `scope.forbidden`,
378
+ `scope.allowed`, `scope.case`, `header.length`, `description.length`, `description.case`,
379
+ `description.ending`, `breaking.marker-pair`, `body.required`, `body.forbidden`, `body.length`,
380
+ `body.word-count`, `body.line-length`, `body.paragraph-format`, `footer.line-length`,
381
+ `footer.required-colon`, `footer.required`, `footer.forbidden`, `footer.value`, `reference.required`,
382
+ and `typos.word`. The list is closed, case-sensitive, and rejects duplicates. Structural diagnostics
383
+ (`syntax.header`, `syntax.separator`), resource limits, and merge rejection cannot become warnings.
384
+ Missing history, malformed configuration/input, unavailable tools, and other operational errors
385
+ continue to exit 2. A configured warning for spelling never converts a missing or broken Typos tool
386
+ into a successful check.
387
+
388
+ ### Warning-aware report contract
389
+
390
+ Commit and pull-request JSON reports use schema v1 consistently. Every diagnostic includes an
391
+ `error` or `warning` severity, and every report includes `warning_count`, including zero for clean,
392
+ empty, or skipped selections. Configuring warnings changes enforcement, not the report format.
393
+ Codes, locations, and order remain unchanged. `warning_count` counts diagnostics across all targets,
394
+ including failed targets. A warning-only target has `status: "passed"` and `valid: true`; `passed`,
395
+ `failed`, and `skipped` continue counting targets. Policy errors still produce exit 1, and warning-only
396
+ results exit 0. Consumers should use severity rather than treating every diagnostic as an error.
397
+ Text identifies warning findings and their count. GitHub output emits escaped `::warning`
398
+ annotations for warnings and `::error` for errors, retaining bounded annotation output.
399
+ Repository reports embed the same commit report shape. Configuration inspection, quality-advisory
400
+ reports, and operational-error envelopes retain their existing schema v1 contracts.
401
+
402
+ ## Ordinary messages and authoring help
403
+
404
+ Teams that want message policy without Conventional Commit prefixes can opt into plain format:
405
+
406
+ ```toml
407
+ [tool.yaga.commit]
408
+ message-format = "plain"
409
+ header-max-length = 100
410
+ body-policy = "required"
411
+ ```
412
+
413
+ Or start from an editable, frozen policy with `yaga config init --starter plain-v1`.
414
+ The default remains `"conventional"`; format is never inferred from the message. Plain format
415
+ requires a nonempty first line without outer whitespace or unsafe controls. The whole first line
416
+ is the description. Header/description limits, casing and ending policy, body/footer rules,
417
+ references, spelling, warnings, Git merge policy, and explicit ignored headers still apply.
418
+ A blank line must separate the title from body or footers.
419
+
420
+ Plain parsing does not invent a type, scope, or header breaking marker, even when the text looks
421
+ like `fix(core)!: example`. Final footer parsing is shared, including recognized breaking footers,
422
+ but `!` has no special header meaning. Plain configuration rejects `allowed-types`, `type-case`,
423
+ `scope-policy`, `allowed-scopes`, `scope-case`, `scope-policy-by-type`, `body-policy-by-type`, and
424
+ `breaking-markers`, even if explicitly set to their conventional defaults. Warning rules for type,
425
+ scope, or marker pairing are also rejected. Remove those keys when converting an existing policy;
426
+ `config show --type` is not applicable to plain format.
427
+
428
+ This option does not make messages suitable for tools that require Conventional Commit release
429
+ classification. It changes YAGA's explicit validation grammar only. PR titles, opted-in proposed
430
+ messages, and ordinary selected commits use the same configured format; title-only checks still
431
+ exclude body and footer requirements.
432
+
433
+ ### Read-only message templates
434
+
435
+ ```bash
436
+ yaga commit template --type fix --scope cli
437
+ yaga commit template --type fix --scope cli --comment-char ';'
438
+ # With message-format = "plain":
439
+ yaga commit template
440
+ ```
441
+
442
+ `commit template` prints an incomplete draft using the selected policy. It never writes a file,
443
+ changes Git configuration, launches an editor, or rewrites history. Conventional drafts require an
444
+ explicit type and a scope when policy requires one; supplied components must satisfy blocking policy even
445
+ if an ignored-header pattern would otherwise skip checking. Plain drafts reject type/scope options.
446
+
447
+ The description is deliberately blank. Required footer labels have blank values: YAGA does not
448
+ invent a reason, work-item ID, sign-off identity, or a `Validation: passed` claim. Commented guidance
449
+ shows effective prose requirements, relevant limits, allowed footer values, and warning rules.
450
+ Complete the draft yourself and validate the final message; the draft is not a passing example.
451
+
452
+ Template comments default to `#`; `;` is also supported explicitly. Match the Git editor's comment
453
+ character or remove the guidance before committing. YAGA does not inspect or change that setting.
454
+ `commit check --file` reads comments literally; `--edit` uses Git's configured cleanup behavior.
@@ -89,7 +89,7 @@ versions, joined by commas (all must match). Each numeric component has at most
89
89
  no leading zeroes. The limit is eight comparisons and 256 characters. Wildcards, compatible-release
90
90
  operators, prereleases, URLs, and other Python packaging requirement syntax are not supported.
91
91
 
92
- This setting applies to commands that load this configuration: commit checks and quality, the
92
+ This setting applies to commands that load this configuration: commit checks, templates, and quality, the
93
93
  GitHub commit adapter, repository checks selecting the commit provider, and `config show`.
94
94
  Explicit-policy providers such as `branch check` and `tree check` retain their no-discovery
95
95
  contract. Use `yaga config show --config pyproject.toml` as an explicit version preflight before
@@ -102,6 +102,11 @@ version. Pin the installation separately when CI must always use one exact relea
102
102
 
103
103
  | Key | Values and purpose |
104
104
  | --- | --- |
105
+ | `message-format` | `conventional` (default) or `plain`; [format boundaries](commit-policy.md#ordinary-messages-and-authoring-help). |
106
+ | `warning-rules` | Empty-default list of configurable diagnostic codes to report without blocking; [gradual enforcement](commit-policy.md#gradual-enforcement). |
107
+ | `pull-request-message` | `title-only` (default) or `title-and-body`; [proposed merge messages](github-actions.md#proposed-merge-messages). |
108
+ | `required-issue-prefixes` | Empty-default bounded reference prefixes; [matching rules](commit-policy.md#references-and-footer-values). |
109
+ | `footer-values` | Empty-default exact allowed values by footer token; presence is configured separately. |
105
110
  | `allowed-types` | Optional nonempty ordered type tokens. Omit to allow any valid type. |
106
111
  | `type-case` | `any`, `lower`, or `upper`. |
107
112
  | `scope-policy` | `optional`, `required`, or `forbidden`. |
@@ -116,7 +121,9 @@ version. Pin the installation separately when CI must always use one exact relea
116
121
  | `required-footer-tokens` | Up to 128 combined required/forbidden ASCII tokens. |
117
122
  | `forbidden-footer-tokens` | Exact case-insensitive presence prohibitions. |
118
123
  | `body-policy` | `optional`, `required`, or `forbidden`. |
124
+ | `body-policy-by-type` | Empty-default mapping of up to 128 types to body presence overrides. |
119
125
  | `body-min-length` | Nonnegative prose-body character lower bound. |
126
+ | `body-max-length` | Optional total prose-body limit from 1 through 100000; independent of line wrapping. |
120
127
  | `body-min-words` | Integer from 0 through 100000, counting prose tokens. |
121
128
  | `body-max-line-length` | Optional maximum body-line length; omitted means unlimited. |
122
129
  | `body-paragraph-splitting` | `skip` (default) or `check` for likely sentence splits across blank lines. |
@@ -135,6 +142,28 @@ unique, non-overlapping, and cannot use `BREAKING CHANGE` or `BREAKING-CHANGE`.
135
142
 
136
143
  ### Body layout settings
137
144
 
145
+ YAGA 0.2.0 adds `body-policy-by-type` and `body-max-length`. A project can require an
146
+ explanation for behavioral changes while keeping
147
+ documentation and maintenance bodies optional:
148
+
149
+ ```toml
150
+ [commit]
151
+ body-policy = "optional"
152
+ body-min-length = 20
153
+ body-max-length = 2000
154
+ body-policy-by-type = { feat = "required", fix = "required" }
155
+ ```
156
+
157
+ Each case-insensitive type override replaces only body presence, not the other checks. Values
158
+ are `optional`, `required`, or `forbidden`; duplicate normalized keys and keys outside configured
159
+ `allowed-types` are errors. Length and word minima apply when an allowed body exists; they do
160
+ not require an optional body and do not create extra minimum findings for a forbidden body.
161
+ All reachable body policies cannot be forbidden alongside a positive minimum.
162
+ The total limit counts stripped prose, including internal newlines, in the configured
163
+ `length-unit`; recognized final footers are excluded. It cannot be smaller than `body-min-length`
164
+ or too small to contain `body-min-words` one-character words separated by whitespace.
165
+ Both limits report `body.length`. No body requirement or limit applies to a standalone title.
166
+
138
167
  `body-max-line-length` is an optional wrapping limit; omitting it leaves body line length
139
168
  unlimited. `body-paragraph-splitting` is an explicit layout heuristic. `skip` (the default) allows
140
169
  any paragraph layout. `check` identifies the first blank-line boundary where a one-line prose
@@ -1,5 +1,8 @@
1
1
  # Contributing
2
2
 
3
+ See the [commit policy direction for 0.2.0](commit-policy-direction.md) for the current
4
+ problem-led development scope and customization principles.
5
+
3
6
  The docs gate checks rendered local links and anchors, including README routes and the public
4
7
  logo, against the built site. Run `uv run make docs` after changing documentation or navigation.
5
8
 
@@ -1,6 +1,6 @@
1
1
  # Get started
2
2
 
3
- This guide covers **YAGA 0.1.2 (Beta)**. YAGA requires Python 3.12 or newer. Install the **`yaga-cli`** distribution from PyPI;
3
+ This guide covers **YAGA 0.2.0 (Beta)**. YAGA requires Python 3.12 or newer. Install the **`yaga-cli`** distribution from PyPI;
4
4
  the executable and import package are **`yaga`**. The `yaga` distribution is an unrelated project.
5
5
 
6
6
  ## Install as a global tool
@@ -28,7 +28,7 @@ at the newer main SHA fails closed. This mode does not support older server beha
28
28
  `pull_request_target` from a non-default target branch.
29
29
 
30
30
  Retain a revision-aware concurrency group containing both PR number and head SHA, and subscribe
31
- to `edited` as well as commit lifecycle events so title edits are checked. For django-ray,
31
+ to `edited` as well as commit lifecycle events so title and body edits are checked. For django-ray,
32
32
  retain the required job name `Commit Messages`. A successful message comparison alone does not
33
33
  establish safe event/checkout integration.
34
34
 
@@ -46,6 +46,39 @@ consumer's real-event qualification; they do not authorize a production cutover.
46
46
  Use ordinary unprivileged CI for repository checks. The write-capable review adapter has a
47
47
  separate [deployment guide](github-review-adapter.md); it is not required to use YAGA in CI.
48
48
 
49
+ ## Proposed merge messages
50
+
51
+ Repositories using the PR title and description as the default commit message can opt in:
52
+
53
+ ```toml
54
+ [tool.yaga.commit]
55
+ pull-request-message = "title-and-body"
56
+ body-policy = "required"
57
+ body-min-words = 8
58
+ ```
59
+
60
+ Use `[commit]` in `.yaga.toml`. The default `"title-only"` keeps existing behavior.
61
+ The additional check composes the literal title, a blank line, and the description, then applies
62
+ full commit policy: per-type body requirements, prose limits, breaking markers, footer rules,
63
+ and optional spelling. A missing or null description is empty. Markdown and HTML comments are
64
+ not stripped or interpreted; template text can satisfy structural limits without explaining a change.
65
+
66
+ GitHub supports title plus description for both
67
+ [squash commits](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/configuring-commit-squashing-for-pull-requests)
68
+ and [merge commits](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/configuring-commit-merging-for-pull-requests).
69
+ Choose this option to match your repository's intended message source. YAGA does not read or modify
70
+ GitHub merge settings. Rebase merges use existing commit messages; multiple enabled merge methods,
71
+ GitHub-generated text, and last-minute message edits can produce a different final commit.
72
+ This check validates the proposed event text, not the final merged object.
73
+
74
+ Subscribe to `edited` events as well as commit lifecycle events: changing a description does not
75
+ change the PR head SHA. Preserve the workflow's concurrency and trusted-policy protections.
76
+ The existing title and commit results remain separate. An enabled check adds `proposed_message`
77
+ inside the schema-v1 JSON `pull_request` object and includes it in result counts; the key is absent
78
+ in default mode. Text and GitHub summaries identify the additional proposed message explicitly.
79
+ Author exemptions apply to it only after normal event, checkout, policy, and range validation.
80
+ `merge-commits = "ignore"` does not skip it because no Git merge parents exist for proposed text.
81
+
49
82
  ## Pull-request checks in GitHub Actions
50
83
 
51
84
  `yaga github pull-request check` applies the same commit policy to a GitHub event without calling
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "yaga-cli"
7
- version = "0.1.2"
7
+ version = "0.2.0"
8
8
  description = "Configurable developer workflow checks for local use and GitHub Actions"
9
9
  readme = "README.md"
10
10
  license = "BSD-3-Clause"
@@ -0,0 +1,21 @@
1
+ ### Added
2
+
3
+ - Support explicit plain-message policy and a frozen `plain-v1` starter; print incomplete,
4
+ policy-guided drafts with `commit template` without changing files or Git.
5
+
6
+ - Introduce opt-in `warning-rules` for gradual policy adoption, with consistent schema-v1 commit
7
+ reports containing severity and warning counts, and nonblocking annotations.
8
+
9
+ - Require bounded work-item references and constrain exact footer values through opt-in
10
+ `required-issue-prefixes` and `footer-values` settings.
11
+
12
+ - Add frozen editable workflow starters and `config show --type` explanations of effective
13
+ body/scope overrides, preserving the existing default starter.
14
+
15
+ - Validate proposed PR title-plus-description messages with opt-in `pull-request-message`,
16
+ reusing full commit policy and reporting the proposed message separately.
17
+
18
+ - Allow per-type body requirements with `body-policy-by-type` and cap total prose with
19
+ `body-max-length`, preserving existing defaults and independent title checks.
20
+
21
+ [PyPI](https://pypi.org/project/yaga-cli/0.2.0/)
@@ -7,6 +7,7 @@ from typing import Annotated
7
7
 
8
8
  import typer
9
9
 
10
+ from yaga.commits.config import load_config
10
11
  from yaga.commits.github_reporting import (
11
12
  CommitOutputFormat,
12
13
  render_commit_error,
@@ -19,11 +20,43 @@ from yaga.commits.reporting import (
19
20
  )
20
21
  from yaga.commits.service import check_commit_quality
21
22
  from yaga.commits.service import check_commits as check_commit_service
23
+ from yaga.commits.template import TemplateComment, message_template
22
24
  from yaga.errors import YagaError
23
25
 
24
26
  app = typer.Typer(help="Inspect and enforce commit-message policy.", no_args_is_help=True)
25
27
 
26
28
 
29
+ @app.command("template")
30
+ def template(
31
+ commit_type: Annotated[
32
+ str | None, typer.Option("--type", help="Explicit conventional commit type.")
33
+ ] = None,
34
+ scope: Annotated[
35
+ str | None, typer.Option("--scope", help="Explicit conventional scope, if needed.")
36
+ ] = None,
37
+ repository: Annotated[
38
+ Path, typer.Option("--repo", help="Configuration discovery root.")
39
+ ] = Path("."),
40
+ config: Annotated[
41
+ Path | None, typer.Option("--config", help="Use one explicit configuration file.")
42
+ ] = None,
43
+ comment: Annotated[
44
+ TemplateComment,
45
+ typer.Option("--comment-char", help="Match the editor's Git comment character."),
46
+ ] = TemplateComment.HASH,
47
+ ) -> None:
48
+ """Print an incomplete, policy-guided message template without modifying files or Git."""
49
+ try:
50
+ loaded = load_config(config, start=repository.expanduser().resolve())
51
+ output = message_template(
52
+ loaded.policy, commit_type=commit_type, scope=scope, comment=comment
53
+ )
54
+ except YagaError as error:
55
+ typer.echo(render_commit_error(error, CommitOutputFormat.TEXT), err=True)
56
+ raise typer.Exit(code=2) from error
57
+ typer.echo(output, nl=False)
58
+
59
+
27
60
  @app.command("check")
28
61
  def check_commits(
29
62
  edit: Annotated[
@@ -8,7 +8,7 @@ from typing import Annotated
8
8
  import typer
9
9
 
10
10
  from yaga.commits.config import load_config
11
- from yaga.commits.config_init import initialize_config
11
+ from yaga.commits.config_init import ConfigStarter, initialize_config
12
12
  from yaga.commits.models import OutputFormat
13
13
  from yaga.commits.reporting import render_config, render_error
14
14
  from yaga.errors import YagaError
@@ -18,6 +18,9 @@ app = typer.Typer(help="Inspect YAGA configuration.", no_args_is_help=True)
18
18
 
19
19
  @app.command("init")
20
20
  def init_config(
21
+ starter: Annotated[
22
+ ConfigStarter, typer.Option("--starter", help="Frozen editable starter policy.")
23
+ ] = ConfigStarter.RECOMMENDED_V1,
21
24
  repository: Annotated[
22
25
  Path,
23
26
  typer.Option(
@@ -39,7 +42,7 @@ def init_config(
39
42
  ) -> None:
40
43
  """Create or preview a recommended standalone .yaga.toml without overwriting."""
41
44
  try:
42
- loaded = initialize_config(repository, dry_run=dry_run)
45
+ loaded = initialize_config(repository, dry_run=dry_run, starter=starter)
43
46
  except YagaError as error:
44
47
  typer.echo(render_error(error, output_format), err=True)
45
48
  raise typer.Exit(code=2) from error
@@ -48,6 +51,10 @@ def init_config(
48
51
 
49
52
  @app.command("show")
50
53
  def show_config(
54
+ commit_type: Annotated[
55
+ str | None,
56
+ typer.Option("--type", help="Explain body and scope requirements for this type."),
57
+ ] = None,
51
58
  repository: Annotated[
52
59
  Path,
53
60
  typer.Option("--repo", help="Configuration discovery root."),
@@ -64,7 +71,8 @@ def show_config(
64
71
  """Show the effective configuration and its source."""
65
72
  try:
66
73
  loaded = load_config(config, start=repository.expanduser().resolve())
74
+ rendered = render_config(loaded, output_format, commit_type=commit_type)
67
75
  except YagaError as error:
68
76
  typer.echo(render_error(error, output_format), err=True)
69
77
  raise typer.Exit(code=2) from error
70
- typer.echo(render_config(loaded, output_format))
78
+ typer.echo(rendered)