devex-cli 0.30.0__tar.gz → 0.30.1__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 (331) hide show
  1. {devex_cli-0.30.0 → devex_cli-0.30.1}/.github/workflows/test.yml +12 -2
  2. {devex_cli-0.30.0 → devex_cli-0.30.1}/CHANGELOG.md +14 -0
  3. {devex_cli-0.30.0 → devex_cli-0.30.1}/PKG-INFO +1 -1
  4. {devex_cli-0.30.0 → devex_cli-0.30.1}/pyproject.toml +1 -1
  5. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/reviewer/assets/backends/acp.yaml +1 -0
  6. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/reviewer/assets/backends/claude-code.yaml +1 -0
  7. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/reviewer/assets/backends/codex.yaml +1 -0
  8. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/reviewer/assets/backends/copilot.yaml +1 -0
  9. devex_cli-0.30.1/src/devex/commands/reviewer/assets/unsupported.md.j2 +24 -0
  10. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/reviewer/scripts/next_step.py +6 -1
  11. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/reviewer/scripts/reviewer.py +8 -1
  12. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/qodo.py +17 -0
  13. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/test_reviewer.py +21 -1
  14. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/test_footer_hints.py +1 -0
  15. {devex_cli-0.30.0 → devex_cli-0.30.1}/uv.lock +1 -1
  16. devex_cli-0.30.0/src/devex/commands/reviewer/assets/unsupported.md.j2 +0 -15
  17. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/agent-config/SKILL.md +0 -0
  18. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/agent-config/data/backend-fingerprints.yaml +0 -0
  19. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/agent-config/scripts/show.sh +0 -0
  20. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/ask-colleague/SKILL.md +0 -0
  21. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/ask-colleague/prompts/explore.md +0 -0
  22. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/ask-colleague/prompts/review.md +0 -0
  23. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/ask-colleague/prompts/write.md +0 -0
  24. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/ask-colleague/scripts/ask-colleague.sh +0 -0
  25. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/assign-to-workforce/SKILL.md +0 -0
  26. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh +0 -0
  27. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/cicd/SKILL.md +0 -0
  28. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/cicd/scripts/workflow.sh +0 -0
  29. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/communicate/SKILL.md +0 -0
  30. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/communicate/scripts/fetch-issues.sh +0 -0
  31. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/communicate/scripts/mesh-message.sh +0 -0
  32. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/communicate/scripts/post-comment.sh +0 -0
  33. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/communicate/scripts/post-issue.sh +0 -0
  34. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/doc-test-alignment/SKILL.md +0 -0
  35. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/doc-test-alignment/scripts/check.sh +0 -0
  36. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/pypi-maintainer/SKILL.md +0 -0
  37. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/pypi-maintainer/scripts/switch-source.sh +0 -0
  38. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/run-tests/SKILL.md +0 -0
  39. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/run-tests/scripts/test.sh +0 -0
  40. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/sonarclaude/SKILL.md +0 -0
  41. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/sonarclaude/scripts/sonar.sh +0 -0
  42. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/spec-to-plan/SKILL.md +0 -0
  43. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/spec-to-plan/scripts/spec-to-plan.sh +0 -0
  44. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/think/SKILL.md +0 -0
  45. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/think/scripts/think.sh +0 -0
  46. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/version-bump/SKILL.md +0 -0
  47. {devex_cli-0.30.0 → devex_cli-0.30.1}/.claude/skills/version-bump/scripts/bump.py +0 -0
  48. {devex_cli-0.30.0 → devex_cli-0.30.1}/.devague/frames/devex-now-reads-qodo-pr-review-findings-structural.json +0 -0
  49. {devex_cli-0.30.0 → devex_cli-0.30.1}/.devague/frames/devex-now-turns-a-push-into-continuous-pr-manageme.json +0 -0
  50. {devex_cli-0.30.0 → devex_cli-0.30.1}/.devague/frames/every-devex-command-now-closes-with-a-deterministi.json +0 -0
  51. {devex_cli-0.30.0 → devex_cli-0.30.1}/.devague/plans/devex-now-reads-qodo-pr-review-findings-structural.json +0 -0
  52. {devex_cli-0.30.0 → devex_cli-0.30.1}/.devague/plans/devex-now-turns-a-push-into-continuous-pr-manageme.json +0 -0
  53. {devex_cli-0.30.0 → devex_cli-0.30.1}/.devague/plans/every-devex-command-now-closes-with-a-deterministi.json +0 -0
  54. {devex_cli-0.30.0 → devex_cli-0.30.1}/.flake8 +0 -0
  55. {devex_cli-0.30.0 → devex_cli-0.30.1}/.github/workflows/publish.yml +0 -0
  56. {devex_cli-0.30.0 → devex_cli-0.30.1}/.gitignore +0 -0
  57. {devex_cli-0.30.0 → devex_cli-0.30.1}/.markdownlint-cli2.yaml +0 -0
  58. {devex_cli-0.30.0 → devex_cli-0.30.1}/.pre-commit-config.yaml +0 -0
  59. {devex_cli-0.30.0 → devex_cli-0.30.1}/.python-version +0 -0
  60. {devex_cli-0.30.0 → devex_cli-0.30.1}/CLAUDE.md +0 -0
  61. {devex_cli-0.30.0 → devex_cli-0.30.1}/LICENSE +0 -0
  62. {devex_cli-0.30.0 → devex_cli-0.30.1}/README.md +0 -0
  63. {devex_cli-0.30.0 → devex_cli-0.30.1}/culture.yaml +0 -0
  64. {devex_cli-0.30.0 → devex_cli-0.30.1}/docs/plans/2026-05-29-devex-now-turns-a-push-into-continuous-pr-manageme.md +0 -0
  65. {devex_cli-0.30.0 → devex_cli-0.30.1}/docs/plans/2026-05-29-every-devex-command-now-closes-with-a-deterministi.md +0 -0
  66. {devex_cli-0.30.0 → devex_cli-0.30.1}/docs/plans/2026-06-19-devex-now-reads-qodo-pr-review-findings-structural.md +0 -0
  67. {devex_cli-0.30.0 → devex_cli-0.30.1}/docs/skill-sources.md +0 -0
  68. {devex_cli-0.30.0 → devex_cli-0.30.1}/docs/specs/2026-05-29-devex-now-turns-a-push-into-continuous-pr-manageme.md +0 -0
  69. {devex_cli-0.30.0 → devex_cli-0.30.1}/docs/specs/2026-05-29-every-devex-command-now-closes-with-a-deterministi.md +0 -0
  70. {devex_cli-0.30.0 → devex_cli-0.30.1}/docs/specs/2026-06-19-devex-now-reads-qodo-pr-review-findings-structural.md +0 -0
  71. {devex_cli-0.30.0 → devex_cli-0.30.1}/docs/superpowers/plans/2026-04-18-agex-v0.1.md +0 -0
  72. {devex_cli-0.30.0 → devex_cli-0.30.1}/docs/superpowers/plans/2026-05-10-agex-pr.md +0 -0
  73. {devex_cli-0.30.0 → devex_cli-0.30.1}/docs/superpowers/specs/2026-04-18-agex-design.md +0 -0
  74. {devex_cli-0.30.0 → devex_cli-0.30.1}/docs/superpowers/specs/2026-04-26-agex-doctor.md +0 -0
  75. {devex_cli-0.30.0 → devex_cli-0.30.1}/docs/superpowers/specs/2026-05-10-agex-pr-design.md +0 -0
  76. {devex_cli-0.30.0 → devex_cli-0.30.1}/sonar-project.properties +0 -0
  77. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/__init__.py +0 -0
  78. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/__main__.py +0 -0
  79. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/backends/__init__.py +0 -0
  80. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/backends/acp/__init__.py +0 -0
  81. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/backends/acp/probe.py +0 -0
  82. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/backends/capabilities/acp.yaml +0 -0
  83. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/backends/capabilities/claude-code.yaml +0 -0
  84. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/backends/capabilities/codex.yaml +0 -0
  85. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/backends/capabilities/copilot.yaml +0 -0
  86. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/backends/claude_code/__init__.py +0 -0
  87. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/backends/claude_code/probe.py +0 -0
  88. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/backends/codex/__init__.py +0 -0
  89. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/backends/codex/probe.py +0 -0
  90. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/backends/copilot/__init__.py +0 -0
  91. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/backends/copilot/probe.py +0 -0
  92. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/cli.py +0 -0
  93. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/__init__.py +0 -0
  94. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/doctor/SKILL.md +0 -0
  95. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/doctor/__init__.py +0 -0
  96. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/doctor/assets/backends/__init__.py +0 -0
  97. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/doctor/assets/backends/acp.yaml +0 -0
  98. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/doctor/assets/backends/claude-code.yaml +0 -0
  99. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/doctor/assets/backends/codex.yaml +0 -0
  100. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/doctor/assets/backends/copilot.yaml +0 -0
  101. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/doctor/assets/report.md.j2 +0 -0
  102. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/doctor/references/design.md +0 -0
  103. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/doctor/scripts/__init__.py +0 -0
  104. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/doctor/scripts/_footer.py +0 -0
  105. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/doctor/scripts/doctor.py +0 -0
  106. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/doctor/scripts/next_step.py +0 -0
  107. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/explain/SKILL.md +0 -0
  108. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/explain/__init__.py +0 -0
  109. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/explain/assets/backends/__init__.py +0 -0
  110. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/explain/assets/backends/acp.yaml +0 -0
  111. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/explain/assets/backends/claude-code.yaml +0 -0
  112. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/explain/assets/backends/codex.yaml +0 -0
  113. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/explain/assets/backends/copilot.yaml +0 -0
  114. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/explain/assets/topics/devex.md +0 -0
  115. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/explain/references/.gitkeep +0 -0
  116. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/explain/scripts/__init__.py +0 -0
  117. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/explain/scripts/_footer.py +0 -0
  118. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/explain/scripts/explain.py +0 -0
  119. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/explain/scripts/next_step.py +0 -0
  120. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/gamify/SKILL.md +0 -0
  121. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/gamify/__init__.py +0 -0
  122. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/gamify/assets/backends/__init__.py +0 -0
  123. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/gamify/assets/backends/acp.yaml +0 -0
  124. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/gamify/assets/backends/claude-code.yaml +0 -0
  125. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/gamify/assets/backends/codex.yaml +0 -0
  126. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/gamify/assets/backends/copilot.yaml +0 -0
  127. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/gamify/assets/hooks/claude-code.json +0 -0
  128. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/gamify/references/.gitkeep +0 -0
  129. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/gamify/scripts/__init__.py +0 -0
  130. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/gamify/scripts/install.py +0 -0
  131. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/gamify/scripts/next_step.py +0 -0
  132. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/hook/SKILL.md +0 -0
  133. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/hook/__init__.py +0 -0
  134. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/hook/assets/backends/__init__.py +0 -0
  135. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/hook/assets/backends/acp.yaml +0 -0
  136. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/hook/assets/backends/claude-code.yaml +0 -0
  137. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/hook/assets/backends/codex.yaml +0 -0
  138. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/hook/assets/backends/copilot.yaml +0 -0
  139. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/hook/assets/table.md.j2 +0 -0
  140. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/hook/references/.gitkeep +0 -0
  141. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/hook/scripts/__init__.py +0 -0
  142. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/hook/scripts/_footer.py +0 -0
  143. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/hook/scripts/next_step.py +0 -0
  144. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/hook/scripts/read.py +0 -0
  145. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/hook/scripts/write.py +0 -0
  146. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/SKILL.md +0 -0
  147. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/__init__.py +0 -0
  148. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/assets/backends/__init__.py +0 -0
  149. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/assets/backends/acp.yaml +0 -0
  150. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/assets/backends/claude-code.yaml +0 -0
  151. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/assets/backends/codex.yaml +0 -0
  152. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/assets/backends/copilot.yaml +0 -0
  153. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/assets/menu.md.j2 +0 -0
  154. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/assets/topics/cicd/SKILL.md +0 -0
  155. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/assets/topics/gamify/SKILL.md +0 -0
  156. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/assets/topics/gamify/assets/skill-template/claude-code/SKILL.md +0 -0
  157. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/assets/topics/introspect/SKILL.md +0 -0
  158. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/assets/topics/introspect/assets/skill-template/claude-code/SKILL.md +0 -0
  159. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/assets/topics/levelup/SKILL.md +0 -0
  160. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/assets/topics/levelup/assets/skill-template/claude-code/SKILL.md +0 -0
  161. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/assets/topics/visualize/SKILL.md +0 -0
  162. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/assets/topics/visualize/assets/skill-template/claude-code/SKILL.md +0 -0
  163. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/references/.gitkeep +0 -0
  164. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/scripts/__init__.py +0 -0
  165. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/scripts/learn.py +0 -0
  166. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/learn/scripts/next_step.py +0 -0
  167. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/overview/SKILL.md +0 -0
  168. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/overview/__init__.py +0 -0
  169. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/overview/assets/__init__.py +0 -0
  170. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/overview/assets/backends/__init__.py +0 -0
  171. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/overview/assets/backends/acp.yaml +0 -0
  172. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/overview/assets/backends/claude-code.yaml +0 -0
  173. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/overview/assets/backends/codex.yaml +0 -0
  174. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/overview/assets/backends/copilot.yaml +0 -0
  175. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/overview/assets/sections.md.j2 +0 -0
  176. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/overview/references/.gitkeep +0 -0
  177. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/overview/scripts/__init__.py +0 -0
  178. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/overview/scripts/_footer.py +0 -0
  179. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/overview/scripts/next_step.py +0 -0
  180. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/overview/scripts/overview.py +0 -0
  181. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/SKILL.md +0 -0
  182. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/__init__.py +0 -0
  183. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/assets/__init__.py +0 -0
  184. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/assets/backends/__init__.py +0 -0
  185. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/assets/backends/acp.yaml +0 -0
  186. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/assets/backends/claude-code.yaml +0 -0
  187. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/assets/backends/codex.yaml +0 -0
  188. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/assets/backends/copilot.yaml +0 -0
  189. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/assets/rules/__init__.py +0 -0
  190. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/assets/rules/lint_rules.py +0 -0
  191. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/assets/rules/next_step_rules.py +0 -0
  192. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/assets/templates/__init__.py +0 -0
  193. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/assets/templates/delta.md.j2 +0 -0
  194. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/assets/templates/lint_result.md.j2 +0 -0
  195. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/assets/templates/pr_await_detached.md.j2 +0 -0
  196. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/assets/templates/pr_briefing.md.j2 +0 -0
  197. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/assets/templates/pr_open_result.md.j2 +0 -0
  198. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/assets/templates/pr_reply_result.md.j2 +0 -0
  199. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/assets/templates/pr_review_result.md.j2 +0 -0
  200. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/scripts/__init__.py +0 -0
  201. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/scripts/_await_worker.py +0 -0
  202. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/scripts/_deploy.py +0 -0
  203. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/scripts/_detach.py +0 -0
  204. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/scripts/_footer.py +0 -0
  205. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/scripts/_journal.py +0 -0
  206. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/scripts/_qodo.py +0 -0
  207. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/scripts/_readiness.py +0 -0
  208. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/scripts/_sonar.py +0 -0
  209. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/scripts/_webhook.py +0 -0
  210. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/scripts/await_.py +0 -0
  211. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/scripts/delta.py +0 -0
  212. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/scripts/lint.py +0 -0
  213. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/scripts/open_.py +0 -0
  214. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/scripts/read.py +0 -0
  215. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/scripts/reply.py +0 -0
  216. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/pr/scripts/review.py +0 -0
  217. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/push/SKILL.md +0 -0
  218. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/push/__init__.py +0 -0
  219. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/push/assets/__init__.py +0 -0
  220. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/push/assets/backends/__init__.py +0 -0
  221. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/push/assets/backends/acp.yaml +0 -0
  222. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/push/assets/backends/claude-code.yaml +0 -0
  223. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/push/assets/backends/codex.yaml +0 -0
  224. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/push/assets/backends/copilot.yaml +0 -0
  225. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/push/scripts/__init__.py +0 -0
  226. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/push/scripts/push.py +0 -0
  227. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/reviewer/SKILL.md +0 -0
  228. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/reviewer/__init__.py +0 -0
  229. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/reviewer/assets/__init__.py +0 -0
  230. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/reviewer/assets/backends/__init__.py +0 -0
  231. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/reviewer/assets/config.md.j2 +0 -0
  232. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/reviewer/assets/failed.md.j2 +0 -0
  233. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/reviewer/assets/review_list.md.j2 +0 -0
  234. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/reviewer/assets/review_resolve.md.j2 +0 -0
  235. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/reviewer/assets/rules.md.j2 +0 -0
  236. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/reviewer/references/.gitkeep +0 -0
  237. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/reviewer/scripts/__init__.py +0 -0
  238. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/commands/reviewer/scripts/_footer.py +0 -0
  239. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/__init__.py +0 -0
  240. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/_jsonl.py +0 -0
  241. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/assets/__init__.py +0 -0
  242. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/assets/backends/__init__.py +0 -0
  243. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/assets/backends/neutral.yaml +0 -0
  244. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/assets/footer.md.j2 +0 -0
  245. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/backend.py +0 -0
  246. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/capabilities.py +0 -0
  247. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/config.py +0 -0
  248. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/footer.py +0 -0
  249. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/github.py +0 -0
  250. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/hook_io.py +0 -0
  251. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/journal.py +0 -0
  252. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/paths.py +0 -0
  253. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/prog.py +0 -0
  254. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/render.py +0 -0
  255. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/skill_loader.py +0 -0
  256. {devex_cli-0.30.0 → devex_cli-0.30.1}/src/devex/core/webhook.py +0 -0
  257. {devex_cli-0.30.0 → devex_cli-0.30.1}/tester-agents/claude/.claude/settings.json +0 -0
  258. {devex_cli-0.30.0 → devex_cli-0.30.1}/tester-agents/claude/.claude/skills +0 -0
  259. {devex_cli-0.30.0 → devex_cli-0.30.1}/tester-agents/claude/CLAUDE.md +0 -0
  260. {devex_cli-0.30.0 → devex_cli-0.30.1}/tester-agents/claude/README.md +0 -0
  261. {devex_cli-0.30.0 → devex_cli-0.30.1}/tester-agents/claude/culture.yaml +0 -0
  262. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/__init__.py +0 -0
  263. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/backends/__init__.py +0 -0
  264. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/backends/test_claude_code_probe.py +0 -0
  265. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/backends/test_stub_probes.py +0 -0
  266. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/__init__.py +0 -0
  267. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/__init__.py +0 -0
  268. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/fixtures/gh/.gitkeep +0 -0
  269. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/fixtures/gh/pr_checks_42.json +0 -0
  270. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/fixtures/gh/pr_comments_42.json +0 -0
  271. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/fixtures/gh/qodo_summary_comment.html +0 -0
  272. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/fixtures/journals/dogfood_40.jsonl +0 -0
  273. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/test_await.py +0 -0
  274. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/test_await_detach.py +0 -0
  275. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/test_briefing_findings.py +0 -0
  276. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/test_delta.py +0 -0
  277. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/test_deploy.py +0 -0
  278. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/test_footer.py +0 -0
  279. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/test_lint.py +0 -0
  280. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/test_lint_rules.py +0 -0
  281. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/test_open.py +0 -0
  282. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/test_qodo.py +0 -0
  283. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/test_read.py +0 -0
  284. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/test_readiness.py +0 -0
  285. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/test_reply.py +0 -0
  286. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/test_review.py +0 -0
  287. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/pr/test_webhook_helper.py +0 -0
  288. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/push/__init__.py +0 -0
  289. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/push/test_push.py +0 -0
  290. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/push/test_push_backends.py +0 -0
  291. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/test_doctor.py +0 -0
  292. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/test_explain.py +0 -0
  293. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/test_gamify.py +0 -0
  294. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/test_hook.py +0 -0
  295. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/test_learn.py +0 -0
  296. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/test_overview.py +0 -0
  297. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/commands/test_prog_propagation.py +0 -0
  298. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/conftest.py +0 -0
  299. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/core/__init__.py +0 -0
  300. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/core/test_backend.py +0 -0
  301. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/core/test_capabilities.py +0 -0
  302. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/core/test_config.py +0 -0
  303. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/core/test_footer.py +0 -0
  304. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/core/test_github.py +0 -0
  305. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/core/test_hook_io.py +0 -0
  306. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/core/test_journal.py +0 -0
  307. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/core/test_paths.py +0 -0
  308. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/core/test_prog.py +0 -0
  309. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/core/test_qodo_adapter.py +0 -0
  310. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/core/test_render.py +0 -0
  311. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/core/test_resolve_backend.py +0 -0
  312. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/core/test_skill_loader.py +0 -0
  313. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/core/test_version_lookup.py +0 -0
  314. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/core/test_webhook.py +0 -0
  315. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/core/test_webhook_live.py +0 -0
  316. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/fixtures/claude-code/empty/.gitkeep +0 -0
  317. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/fixtures/claude-code/malformed/.claude/hooks.json +0 -0
  318. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/fixtures/claude-code/malformed/.claude/settings.json +0 -0
  319. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/fixtures/claude-code/malformed/.claude/skills/bad/SKILL.md +0 -0
  320. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/fixtures/claude-code/malformed/.claude/skills/broken-yaml/SKILL.md +0 -0
  321. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/fixtures/claude-code/typical/.claude/hooks.json +0 -0
  322. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/fixtures/claude-code/typical/.claude/settings.json +0 -0
  323. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/fixtures/claude-code/typical/.claude/skills/example/SKILL.md +0 -0
  324. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/fixtures/claude-code/typical/CLAUDE.md +0 -0
  325. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/test_cli_dispatch.py +0 -0
  326. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/test_cli_errors.py +0 -0
  327. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/test_cli_smoke.py +0 -0
  328. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/test_footer_guarantee.py +0 -0
  329. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/test_packaging_qodo_extra.py +0 -0
  330. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/test_reviewer_invariant_docs.py +0 -0
  331. {devex_cli-0.30.0 → devex_cli-0.30.1}/tests/test_skill_md_consistency.py +0 -0
@@ -5,13 +5,23 @@ on:
5
5
  branches: [main]
6
6
  pull_request:
7
7
 
8
+ # Cancel superseded runs on the same ref so a rapid push sequence doesn't pile
9
+ # up parallel matrices (Actions-quota savings — see issue #84).
10
+ concurrency:
11
+ group: ${{ github.workflow }}-${{ github.ref }}
12
+ cancel-in-progress: true
13
+
8
14
  jobs:
15
+ # Linux-only matrix. macOS (runner ×10) and Windows (×2) were dropped to cut
16
+ # GitHub Actions quota — see issue #84 (devex was the org's #2 private-repo
17
+ # consumer; the 4 macOS legs were 65% of the quota cost from 19% of raw
18
+ # minutes). Trade-off: the Windows-specific guards this repo cares about
19
+ # (portalocker over fcntl/msvcrt; utf-8 encoding) are no longer exercised in CI.
9
20
  test:
10
- runs-on: ${{ matrix.os }}
21
+ runs-on: ubuntu-latest
11
22
  strategy:
12
23
  fail-fast: false
13
24
  matrix:
14
- os: [ubuntu-latest, macos-latest, windows-latest]
15
25
  python: ["3.10", "3.11", "3.12", "3.13"]
16
26
  steps:
17
27
  - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
@@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.30.1] - 2026-06-19
11
+
12
+ ### Added
13
+
14
+ - devex.core.qodo.MIN_PYTHON + python_supported() — the single in-code source of truth for qodo-cli's Python floor (mirrors the pyproject [qodo] marker).
15
+
16
+ ### Changed
17
+
18
+ - CI: trimmed test.yml to a Linux-only matrix (was 3 OS x 4 Python, 12 jobs) and added workflow-level concurrency with cancel-in-progress to cut GitHub Actions quota (#84).
19
+
20
+ ### Fixed
21
+
22
+ - devex reviewer unavailable notice and its "Next step:" footer no longer recommend pip install 'devex-cli[qodo]' on Python < 3.12, where the marker-gated extra cannot install at all — they now explain the interpreter is too old and show how to recreate the environment on Python >= 3.12.
23
+
10
24
  ## [0.30.0] - 2026-06-19
11
25
 
12
26
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devex-cli
3
- Version: 0.30.0
3
+ Version: 0.30.1
4
4
  Summary: Agent-operated developer-experience CLI — deterministic per-backend markdown briefings for autonomous agents.
5
5
  Project-URL: Homepage, https://culture.dev/devex/
6
6
  Project-URL: Repository, https://github.com/agentculture/devex
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "devex-cli"
3
- version = "0.30.0"
3
+ version = "0.30.1"
4
4
  description = "Agent-operated developer-experience CLI — deterministic per-backend markdown briefings for autonomous agents."
5
5
  authors = [{name = "Ori Nachum"}]
6
6
  license = {text = "MIT"}
@@ -1,5 +1,6 @@
1
1
  hints:
2
2
  reviewer_unavailable: "Install the integration with `uv tool install 'devex-cli[qodo]'`, then re-run the command — or keep using `{{ prog }} pr read` for Qodo findings."
3
+ reviewer_unavailable_old_python: "Recreate the environment on Python ≥ {{ min_python }} as shown above, then re-run the command — or keep using `{{ prog }} pr read` for Qodo findings."
3
4
  reviewer_failed: "Fix the cause above (pass `--pr <n>`, set `~/.qodo/config.json`, or run `gh auth login`), then re-run the `{{ prog }} reviewer` command."
4
5
  reviewer_rules: "Apply the most relevant rule above to your change, then continue your task (refine with `{{ prog }} reviewer rules \"...\"`)."
5
6
  reviewer_review_findings: "Triage the comments above, prepare fixes, then clear them with `{{ prog }} reviewer review resolve <id>`."
@@ -1,5 +1,6 @@
1
1
  hints:
2
2
  reviewer_unavailable: "Install the integration with `uv tool install 'devex-cli[qodo]'`, then re-run the command — or keep using `{{ prog }} pr read` for Qodo findings."
3
+ reviewer_unavailable_old_python: "Recreate the environment on Python ≥ {{ min_python }} as shown above, then re-run the command — or keep using `{{ prog }} pr read` for Qodo findings."
3
4
  reviewer_failed: "Fix the cause above (pass `--pr <n>`, set `~/.qodo/config.json`, or run `gh auth login`), then re-run the `{{ prog }} reviewer` command."
4
5
  reviewer_rules: "Apply the most relevant rule above to your change, then continue your task (refine with `{{ prog }} reviewer rules \"...\"`)."
5
6
  reviewer_review_findings: "Triage the comments above, prepare fixes, then clear them with `{{ prog }} reviewer review resolve <id>`."
@@ -1,5 +1,6 @@
1
1
  hints:
2
2
  reviewer_unavailable: "Install the integration with `uv tool install 'devex-cli[qodo]'`, then re-run the command — or keep using `{{ prog }} pr read` for Qodo findings."
3
+ reviewer_unavailable_old_python: "Recreate the environment on Python ≥ {{ min_python }} as shown above, then re-run the command — or keep using `{{ prog }} pr read` for Qodo findings."
3
4
  reviewer_failed: "Fix the cause above (pass `--pr <n>`, set `~/.qodo/config.json`, or run `gh auth login`), then re-run the `{{ prog }} reviewer` command."
4
5
  reviewer_rules: "Apply the most relevant rule above to your change, then continue your task (refine with `{{ prog }} reviewer rules \"...\"`)."
5
6
  reviewer_review_findings: "Triage the comments above, prepare fixes, then clear them with `{{ prog }} reviewer review resolve <id>`."
@@ -1,5 +1,6 @@
1
1
  hints:
2
2
  reviewer_unavailable: "Install the integration with `uv tool install 'devex-cli[qodo]'`, then re-run the command — or keep using `{{ prog }} pr read` for Qodo findings."
3
+ reviewer_unavailable_old_python: "Recreate the environment on Python ≥ {{ min_python }} as shown above, then re-run the command — or keep using `{{ prog }} pr read` for Qodo findings."
3
4
  reviewer_failed: "Fix the cause above (pass `--pr <n>`, set `~/.qodo/config.json`, or run `gh auth login`), then re-run the `{{ prog }} reviewer` command."
4
5
  reviewer_rules: "Apply the most relevant rule above to your change, then continue your task (refine with `{{ prog }} reviewer rules \"...\"`)."
5
6
  reviewer_review_findings: "Triage the comments above, prepare fixes, then clear them with `{{ prog }} reviewer review resolve <id>`."
@@ -0,0 +1,24 @@
1
+ ## `{{ verb_label }}` needs the optional qodo-cli integration
2
+
3
+ `{{ verb_label }}` is powered by the sibling **qodo-cli**, which isn't installed in this environment.
4
+
5
+ **To enable it:**
6
+
7
+ {% if py_supported -%}
8
+ ```bash
9
+ uv tool install 'devex-cli[qodo]' # or: pip install 'devex-cli[qodo]'
10
+ ```
11
+ {%- else -%}
12
+ This environment is Python {{ py_version }}, but qodo-cli requires Python ≥ {{ min_python }}, so the `[qodo]` extra **can't install here at all** (it's marker-gated). Recreate the environment on Python {{ min_python }} first, then install:
13
+
14
+ ```bash
15
+ uv venv --python {{ min_python }} && uv pip install -e '.[dev,qodo]'
16
+ # or, as a standalone tool: uv tool install --python {{ min_python }} 'devex-cli[qodo]'
17
+ ```
18
+ {%- endif %}
19
+
20
+ devex degrades gracefully without it — `pr read` / `pr await` still surface Qodo findings via the built-in HTML reader.
21
+
22
+ Want this supported differently, or hit a problem? Open an issue: <{{ issue_url }}>
23
+
24
+ {{ footer }}
@@ -13,7 +13,12 @@ from typing import Any
13
13
  def reviewer_next_step(verb_key: str, ctx: dict[str, Any]) -> tuple[str, dict[str, Any]]:
14
14
  """Return the footer rule key + context for a reviewer verb render."""
15
15
  if verb_key == "unavailable":
16
- return "reviewer_unavailable", {}
16
+ # A too-old interpreter can't install the [qodo] extra at all (it's
17
+ # marker-gated to Python >= 3.12), so the footer must not repeat the
18
+ # "uv tool install" advice the body already replaced for that case.
19
+ if ctx.get("py_supported", True):
20
+ return "reviewer_unavailable", {}
21
+ return "reviewer_unavailable_old_python", {"min_python": ctx.get("min_python", "3.12")}
17
22
  if verb_key == "failed":
18
23
  return "reviewer_failed", {}
19
24
  if verb_key == "rules":
@@ -20,6 +20,7 @@ read-only.
20
20
 
21
21
  from __future__ import annotations
22
22
 
23
+ import sys
23
24
  from importlib.resources import files
24
25
  from importlib.resources.abc import Traversable
25
26
  from typing import Any
@@ -51,7 +52,13 @@ def _render(name: str, backend: Backend, verb_key: str, ctx: dict[str, Any]) ->
51
52
 
52
53
 
53
54
  def _unavailable(backend: Backend, verb_label: str) -> tuple[str, int, str]:
54
- ctx = {"verb_label": verb_label, "issue_url": _ISSUE_URL}
55
+ ctx = {
56
+ "verb_label": verb_label,
57
+ "issue_url": _ISSUE_URL,
58
+ "py_supported": qodo_adapter.python_supported(),
59
+ "py_version": ".".join(str(n) for n in sys.version_info[:3]),
60
+ "min_python": ".".join(str(n) for n in qodo_adapter.MIN_PYTHON),
61
+ }
55
62
  return _render("unsupported.md.j2", backend, "unavailable", ctx), 0, ""
56
63
 
57
64
 
@@ -28,9 +28,26 @@ from __future__ import annotations
28
28
 
29
29
  import io
30
30
  import json
31
+ import sys
31
32
  from contextlib import redirect_stderr, redirect_stdout
32
33
  from typing import Any
33
34
 
35
+ # qodo-cli's Python floor — mirrors the `python_version >= '3.12'` marker on the
36
+ # [qodo] extra in pyproject.toml. Kept here as the single in-code source of truth
37
+ # so the reviewer "unsupported" notice can tell the user the accurate reason the
38
+ # extra is missing (too-old interpreter vs. simply not installed).
39
+ MIN_PYTHON: tuple[int, int] = (3, 12)
40
+
41
+
42
+ def python_supported() -> bool:
43
+ """True iff the running interpreter is new enough to host qodo-cli (>= MIN_PYTHON).
44
+
45
+ Deterministic, read-only, never raises. On 3.10/3.11 the [qodo] extra can't
46
+ install at all (marker-gated), so the reviewer notice uses this to give
47
+ accurate guidance instead of advice that silently no-ops.
48
+ """
49
+ return sys.version_info[:2] >= MIN_PYTHON
50
+
34
51
 
35
52
  def _exit_code(exc: SystemExit) -> int:
36
53
  """Normalize a ``SystemExit`` code to an int (``None`` -> 0, str/other -> 1)."""
@@ -153,13 +153,33 @@ def test_config_renders_nested_payload(captured):
153
153
  # --- degradation (c14/h11) -------------------------------------------------
154
154
 
155
155
 
156
- def test_unavailable_is_exit_0_notice(monkeypatch):
156
+ def test_unavailable_notice_supported_python(monkeypatch):
157
+ """On a new-enough interpreter the notice gives the install command."""
157
158
  monkeypatch.setattr(reviewer.qodo_adapter, "available", lambda: False)
159
+ monkeypatch.setattr(reviewer.qodo_adapter, "python_supported", lambda: True)
158
160
  out, code, _ = reviewer.rules(_BACKEND, "x")
159
161
  assert code == 0
160
162
  assert "needs the optional qodo-cli integration" in out
161
163
  assert "devex-cli[qodo]" in out
162
164
  assert "**Next step:**" in out
165
+ assert "Install the integration" in out # footer matches the install body
166
+
167
+
168
+ def test_unavailable_notice_old_python(monkeypatch):
169
+ """On Python < 3.12 the notice says the extra can't install — recreate on 3.12.
170
+
171
+ Both the body AND the "Next step:" footer must drop the install advice that
172
+ silently no-ops on a too-old interpreter.
173
+ """
174
+ monkeypatch.setattr(reviewer.qodo_adapter, "available", lambda: False)
175
+ monkeypatch.setattr(reviewer.qodo_adapter, "python_supported", lambda: False)
176
+ out, code, _ = reviewer.rules(_BACKEND, "x")
177
+ assert code == 0
178
+ assert "needs the optional qodo-cli integration" in out
179
+ assert "can't install here" in out
180
+ assert "3.12" in out
181
+ assert "**Next step:**" in out
182
+ assert "Recreate the environment" in out # version-aware footer, not the install hint
163
183
 
164
184
 
165
185
  def test_qodo_failure_is_exit_0_notice(monkeypatch):
@@ -60,6 +60,7 @@ _FULL_CONTEXT: dict = {
60
60
  "backend": "claude-code",
61
61
  "elapsed": "42",
62
62
  "fail_count": 3,
63
+ "min_python": "3.12",
63
64
  "pr": 99,
64
65
  "reviewers": "@alice, @bob",
65
66
  "topic": "pr",
@@ -206,7 +206,7 @@ toml = [
206
206
 
207
207
  [[package]]
208
208
  name = "devex-cli"
209
- version = "0.30.0"
209
+ version = "0.30.1"
210
210
  source = { editable = "." }
211
211
  dependencies = [
212
212
  { name = "jinja2" },
@@ -1,15 +0,0 @@
1
- ## `{{ verb_label }}` needs the optional qodo-cli integration
2
-
3
- `{{ verb_label }}` is powered by the sibling **qodo-cli**, which isn't installed in this environment.
4
-
5
- **To enable it:**
6
-
7
- ```bash
8
- uv tool install 'devex-cli[qodo]' # or: pip install 'devex-cli[qodo]'
9
- ```
10
-
11
- (qodo-cli requires Python ≥ 3.12.) devex degrades gracefully without it — `pr read` / `pr await` still surface Qodo findings via the built-in HTML reader.
12
-
13
- Want this supported differently, or hit a problem? Open an issue: <{{ issue_url }}>
14
-
15
- {{ footer }}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes