agex-cli 0.25.0__tar.gz → 0.26.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 (232) hide show
  1. {agex_cli-0.25.0 → agex_cli-0.26.1}/.github/workflows/publish.yml +5 -4
  2. {agex_cli-0.25.0 → agex_cli-0.26.1}/.github/workflows/test.yml +41 -0
  3. {agex_cli-0.25.0 → agex_cli-0.26.1}/.gitignore +1 -0
  4. {agex_cli-0.25.0 → agex_cli-0.26.1}/CHANGELOG.md +21 -0
  5. {agex_cli-0.25.0 → agex_cli-0.26.1}/CLAUDE.md +24 -23
  6. {agex_cli-0.25.0 → agex_cli-0.26.1}/PKG-INFO +10 -10
  7. agex_cli-0.26.1/README.md +29 -0
  8. {agex_cli-0.25.0 → agex_cli-0.26.1}/culture.yaml +1 -1
  9. {agex_cli-0.25.0 → agex_cli-0.26.1}/pyproject.toml +21 -6
  10. {agex_cli-0.25.0 → agex_cli-0.26.1}/sonar-project.properties +11 -12
  11. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/__init__.py +5 -4
  12. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/__main__.py +1 -1
  13. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/backends/acp/probe.py +1 -1
  14. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/backends/capabilities/codex.yaml +1 -1
  15. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/backends/capabilities/copilot.yaml +1 -1
  16. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/backends/claude_code/probe.py +1 -1
  17. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/backends/codex/probe.py +1 -1
  18. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/backends/copilot/probe.py +1 -1
  19. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/cli.py +65 -32
  20. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/doctor/SKILL.md +9 -9
  21. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/doctor/references/design.md +5 -5
  22. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/doctor/scripts/doctor.py +34 -35
  23. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/explain/SKILL.md +7 -7
  24. agex_cli-0.26.1/src/devex/commands/explain/assets/topics/devex.md +39 -0
  25. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/explain/scripts/explain.py +11 -5
  26. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/gamify/SKILL.md +7 -7
  27. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/gamify/scripts/install.py +6 -6
  28. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/hook/SKILL.md +6 -6
  29. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/hook/scripts/read.py +6 -6
  30. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/hook/scripts/write.py +3 -3
  31. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/learn/SKILL.md +3 -3
  32. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/learn/assets/topics/cicd/SKILL.md +13 -13
  33. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/learn/assets/topics/gamify/SKILL.md +5 -5
  34. {agex_cli-0.25.0/src/agent_experience/commands/learn/assets/topics/levelup → agex_cli-0.26.1/src/devex/commands/learn/assets/topics/gamify}/assets/skill-template/claude-code/SKILL.md +3 -3
  35. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/learn/assets/topics/introspect/SKILL.md +3 -3
  36. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/learn/assets/topics/introspect/assets/skill-template/claude-code/SKILL.md +1 -1
  37. agex_cli-0.26.1/src/devex/commands/learn/assets/topics/levelup/SKILL.md +31 -0
  38. {agex_cli-0.25.0/src/agent_experience/commands/learn/assets/topics/gamify → agex_cli-0.26.1/src/devex/commands/learn/assets/topics/levelup}/assets/skill-template/claude-code/SKILL.md +3 -3
  39. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/learn/assets/topics/visualize/SKILL.md +2 -2
  40. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/learn/assets/topics/visualize/assets/skill-template/claude-code/SKILL.md +1 -1
  41. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/learn/scripts/learn.py +6 -6
  42. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/overview/SKILL.md +5 -5
  43. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/overview/scripts/overview.py +8 -8
  44. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/SKILL.md +45 -17
  45. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/assets/backends/acp.yaml +4 -0
  46. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/assets/backends/claude-code.yaml +4 -0
  47. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/assets/backends/codex.yaml +4 -0
  48. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/assets/backends/copilot.yaml +4 -0
  49. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/assets/rules/lint_rules.py +1 -1
  50. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/assets/rules/next_step_rules.py +15 -1
  51. agex_cli-0.26.1/src/devex/commands/pr/assets/templates/pr_await_detached.md.j2 +29 -0
  52. agex_cli-0.26.1/src/devex/commands/pr/scripts/_await_worker.py +109 -0
  53. agex_cli-0.26.1/src/devex/commands/pr/scripts/_detach.py +129 -0
  54. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/scripts/_footer.py +5 -5
  55. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/scripts/_journal.py +1 -1
  56. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/scripts/_qodo.py +1 -1
  57. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/scripts/_readiness.py +4 -6
  58. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/scripts/_sonar.py +3 -3
  59. agex_cli-0.26.1/src/devex/commands/pr/scripts/await_.py +395 -0
  60. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/scripts/delta.py +8 -8
  61. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/scripts/lint.py +7 -7
  62. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/scripts/open_.py +21 -9
  63. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/scripts/read.py +8 -8
  64. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/scripts/reply.py +9 -9
  65. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/scripts/review.py +9 -9
  66. agex_cli-0.25.0/src/agent_experience/core/hook_io.py → agex_cli-0.26.1/src/devex/core/_jsonl.py +23 -35
  67. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/core/capabilities.py +1 -1
  68. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/core/config.py +2 -2
  69. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/core/github.py +2 -2
  70. agex_cli-0.26.1/src/devex/core/hook_io.py +46 -0
  71. agex_cli-0.26.1/src/devex/core/journal.py +39 -0
  72. agex_cli-0.26.1/src/devex/core/paths.py +50 -0
  73. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/core/prog.py +8 -8
  74. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/core/render.py +1 -1
  75. agex_cli-0.26.1/tester-agents/claude/.claude/skills +1 -0
  76. agex_cli-0.26.1/tester-agents/claude/CLAUDE.md +30 -0
  77. agex_cli-0.26.1/tester-agents/claude/README.md +23 -0
  78. {agex_cli-0.25.0 → agex_cli-0.26.1}/tester-agents/claude/culture.yaml +5 -5
  79. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/backends/test_claude_code_probe.py +1 -1
  80. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/backends/test_stub_probes.py +3 -3
  81. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/pr/fixtures/gh/qodo_summary_comment.html +3 -3
  82. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/pr/test_await.py +5 -5
  83. agex_cli-0.26.1/tests/commands/pr/test_await_detach.py +298 -0
  84. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/pr/test_delta.py +1 -1
  85. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/pr/test_deploy.py +1 -1
  86. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/pr/test_footer.py +9 -7
  87. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/pr/test_lint.py +4 -4
  88. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/pr/test_lint_rules.py +2 -2
  89. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/pr/test_open.py +71 -12
  90. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/pr/test_qodo.py +2 -2
  91. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/pr/test_read.py +8 -8
  92. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/pr/test_readiness.py +2 -2
  93. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/pr/test_reply.py +8 -8
  94. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/pr/test_review.py +5 -5
  95. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/test_doctor.py +28 -28
  96. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/test_explain.py +2 -2
  97. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/test_gamify.py +2 -2
  98. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/test_hook.py +8 -8
  99. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/test_learn.py +1 -1
  100. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/test_overview.py +1 -1
  101. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/test_prog_propagation.py +6 -5
  102. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/core/test_backend.py +1 -1
  103. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/core/test_capabilities.py +2 -2
  104. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/core/test_config.py +3 -3
  105. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/core/test_github.py +5 -5
  106. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/core/test_hook_io.py +13 -12
  107. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/core/test_journal.py +4 -4
  108. agex_cli-0.26.1/tests/core/test_paths.py +59 -0
  109. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/core/test_prog.py +4 -4
  110. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/core/test_render.py +1 -1
  111. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/core/test_resolve_backend.py +2 -2
  112. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/core/test_skill_loader.py +1 -1
  113. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/core/test_version_lookup.py +11 -15
  114. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/test_cli_dispatch.py +4 -4
  115. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/test_cli_errors.py +9 -9
  116. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/test_cli_smoke.py +2 -2
  117. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/test_skill_md_consistency.py +8 -9
  118. {agex_cli-0.25.0 → agex_cli-0.26.1}/uv.lock +1 -1
  119. agex_cli-0.25.0/README.md +0 -29
  120. agex_cli-0.25.0/src/agent_experience/commands/explain/assets/topics/agex.md +0 -37
  121. agex_cli-0.25.0/src/agent_experience/commands/learn/assets/topics/levelup/SKILL.md +0 -31
  122. agex_cli-0.25.0/src/agent_experience/commands/pr/scripts/await_.py +0 -168
  123. agex_cli-0.25.0/src/agent_experience/core/journal.py +0 -90
  124. agex_cli-0.25.0/src/agent_experience/core/paths.py +0 -26
  125. agex_cli-0.25.0/tester-agents/claude/CLAUDE.md +0 -30
  126. agex_cli-0.25.0/tester-agents/claude/README.md +0 -23
  127. agex_cli-0.25.0/tests/core/test_paths.py +0 -31
  128. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/agent-config/SKILL.md +0 -0
  129. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/agent-config/data/backend-fingerprints.yaml +0 -0
  130. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/agent-config/scripts/show.sh +0 -0
  131. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/assign-to-workforce/SKILL.md +0 -0
  132. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh +0 -0
  133. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/cicd/SKILL.md +0 -0
  134. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/cicd/scripts/workflow.sh +0 -0
  135. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/communicate/SKILL.md +0 -0
  136. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/communicate/scripts/fetch-issues.sh +0 -0
  137. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/communicate/scripts/mesh-message.sh +0 -0
  138. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/communicate/scripts/post-comment.sh +0 -0
  139. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/communicate/scripts/post-issue.sh +0 -0
  140. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/doc-test-alignment/SKILL.md +0 -0
  141. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/doc-test-alignment/scripts/check.sh +0 -0
  142. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/pypi-maintainer/SKILL.md +0 -0
  143. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/pypi-maintainer/scripts/switch-source.sh +0 -0
  144. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/run-tests/SKILL.md +0 -0
  145. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/run-tests/scripts/test.sh +0 -0
  146. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/sonarclaude/SKILL.md +0 -0
  147. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/sonarclaude/scripts/sonar.sh +0 -0
  148. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/spec-to-plan/SKILL.md +0 -0
  149. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/spec-to-plan/scripts/spec-to-plan.sh +0 -0
  150. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/think/SKILL.md +0 -0
  151. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/think/scripts/think.sh +0 -0
  152. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/version-bump/SKILL.md +0 -0
  153. {agex_cli-0.25.0 → agex_cli-0.26.1}/.claude/skills/version-bump/scripts/bump.py +0 -0
  154. {agex_cli-0.25.0 → agex_cli-0.26.1}/.flake8 +0 -0
  155. {agex_cli-0.25.0 → agex_cli-0.26.1}/.python-version +0 -0
  156. {agex_cli-0.25.0 → agex_cli-0.26.1}/LICENSE +0 -0
  157. {agex_cli-0.25.0 → agex_cli-0.26.1}/docs/skill-sources.md +0 -0
  158. {agex_cli-0.25.0 → agex_cli-0.26.1}/docs/superpowers/plans/2026-04-18-agex-v0.1.md +0 -0
  159. {agex_cli-0.25.0 → agex_cli-0.26.1}/docs/superpowers/plans/2026-05-10-agex-pr.md +0 -0
  160. {agex_cli-0.25.0 → agex_cli-0.26.1}/docs/superpowers/specs/2026-04-18-agex-design.md +0 -0
  161. {agex_cli-0.25.0 → agex_cli-0.26.1}/docs/superpowers/specs/2026-04-26-agex-doctor.md +0 -0
  162. {agex_cli-0.25.0 → agex_cli-0.26.1}/docs/superpowers/specs/2026-05-10-agex-pr-design.md +0 -0
  163. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/backends/__init__.py +0 -0
  164. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/backends/acp/__init__.py +0 -0
  165. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/backends/capabilities/acp.yaml +0 -0
  166. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/backends/capabilities/claude-code.yaml +0 -0
  167. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/backends/claude_code/__init__.py +0 -0
  168. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/backends/codex/__init__.py +0 -0
  169. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/backends/copilot/__init__.py +0 -0
  170. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/__init__.py +0 -0
  171. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/doctor/__init__.py +0 -0
  172. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/doctor/assets/report.md.j2 +0 -0
  173. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/doctor/scripts/__init__.py +0 -0
  174. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/explain/__init__.py +0 -0
  175. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/explain/references/.gitkeep +0 -0
  176. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/explain/scripts/__init__.py +0 -0
  177. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/gamify/__init__.py +0 -0
  178. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/gamify/assets/hooks/claude-code.json +0 -0
  179. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/gamify/references/.gitkeep +0 -0
  180. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/gamify/scripts/__init__.py +0 -0
  181. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/hook/__init__.py +0 -0
  182. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/hook/assets/table.md.j2 +0 -0
  183. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/hook/references/.gitkeep +0 -0
  184. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/hook/scripts/__init__.py +0 -0
  185. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/learn/__init__.py +0 -0
  186. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/learn/assets/menu.md.j2 +0 -0
  187. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/learn/references/.gitkeep +0 -0
  188. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/learn/scripts/__init__.py +0 -0
  189. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/overview/__init__.py +0 -0
  190. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/overview/assets/backends/acp.yaml +0 -0
  191. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/overview/assets/backends/claude-code.yaml +0 -0
  192. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/overview/assets/backends/codex.yaml +0 -0
  193. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/overview/assets/backends/copilot.yaml +0 -0
  194. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/overview/assets/sections.md.j2 +0 -0
  195. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/overview/references/.gitkeep +0 -0
  196. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/overview/scripts/__init__.py +0 -0
  197. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/__init__.py +0 -0
  198. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/assets/__init__.py +0 -0
  199. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/assets/backends/__init__.py +0 -0
  200. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/assets/rules/__init__.py +0 -0
  201. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/assets/templates/__init__.py +0 -0
  202. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/assets/templates/delta.md.j2 +0 -0
  203. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/assets/templates/footer.md.j2 +0 -0
  204. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/assets/templates/lint_result.md.j2 +0 -0
  205. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/assets/templates/pr_briefing.md.j2 +0 -0
  206. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/assets/templates/pr_open_result.md.j2 +0 -0
  207. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/assets/templates/pr_reply_result.md.j2 +0 -0
  208. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/assets/templates/pr_review_result.md.j2 +0 -0
  209. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/scripts/__init__.py +0 -0
  210. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/commands/pr/scripts/_deploy.py +0 -0
  211. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/core/__init__.py +0 -0
  212. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/core/backend.py +0 -0
  213. {agex_cli-0.25.0/src/agent_experience → agex_cli-0.26.1/src/devex}/core/skill_loader.py +0 -0
  214. {agex_cli-0.25.0 → agex_cli-0.26.1}/tester-agents/claude/.claude/settings.json +0 -0
  215. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/__init__.py +0 -0
  216. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/backends/__init__.py +0 -0
  217. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/__init__.py +0 -0
  218. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/pr/__init__.py +0 -0
  219. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/pr/fixtures/gh/.gitkeep +0 -0
  220. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/pr/fixtures/gh/pr_checks_42.json +0 -0
  221. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/pr/fixtures/gh/pr_comments_42.json +0 -0
  222. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/commands/pr/fixtures/journals/dogfood_40.jsonl +0 -0
  223. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/core/__init__.py +0 -0
  224. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/fixtures/claude-code/empty/.gitkeep +0 -0
  225. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/fixtures/claude-code/malformed/.claude/hooks.json +0 -0
  226. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/fixtures/claude-code/malformed/.claude/settings.json +0 -0
  227. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/fixtures/claude-code/malformed/.claude/skills/bad/SKILL.md +0 -0
  228. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/fixtures/claude-code/malformed/.claude/skills/broken-yaml/SKILL.md +0 -0
  229. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/fixtures/claude-code/typical/.claude/hooks.json +0 -0
  230. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/fixtures/claude-code/typical/.claude/settings.json +0 -0
  231. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/fixtures/claude-code/typical/.claude/skills/example/SKILL.md +0 -0
  232. {agex_cli-0.25.0 → agex_cli-0.26.1}/tests/fixtures/claude-code/typical/CLAUDE.md +0 -0
@@ -73,8 +73,9 @@ jobs:
73
73
  # because it needs to rewrite the version before building.
74
74
  #
75
75
  # The matrix exists so we can publish the same code under three PyPI
76
- # distribution names: `agex-cli` (canonical) plus the `agent-devex` and
77
- # `devex-cli` aliases. Each leg rewrites `[project].name` in pyproject.toml
76
+ # distribution names: `devex-cli` (canonical) plus the `agent-devex` and
77
+ # `agex-cli` aliases (`agex-cli` is the legacy canonical name, still
78
+ # published for back-compat). Each leg rewrites `[project].name` in pyproject.toml
78
79
  # before building so each wheel is uploaded under its own Trusted Publishing
79
80
  # project.
80
81
  # --------------------------------------------------------------------------
@@ -97,9 +98,9 @@ jobs:
97
98
  - run: uv venv
98
99
  - run: uv pip install build
99
100
 
100
- # Rewrite `[project].name` to the matrix dist name. For `agex-cli`
101
+ # Rewrite `[project].name` to the matrix dist name. For `devex-cli`
101
102
  # (the canonical dist) the regex still has to match so we re-emit
102
- # the line; for `agent-devex` / `devex-cli` it produces an alias dist
103
+ # the line; for `agent-devex` / `agex-cli` it produces an alias dist
103
104
  # with identical contents. The post-rewrite re-parse is a fail-closed
104
105
  # check: if a future formatting change breaks the regex match (or
105
106
  # `[project].name` ends up wrong for any reason), the job aborts
@@ -23,6 +23,47 @@ jobs:
23
23
  - run: uv pip install -e ".[dev]"
24
24
  - run: uv run pytest
25
25
 
26
+ # --------------------------------------------------------------------------
27
+ # SonarCloud CI-based analysis + coverage. SonarCloud is no longer in
28
+ # Automatic Analysis mode (the two modes are mutually exclusive), so this job
29
+ # is the sole analysis path: it generates coverage.xml (with repo-relative
30
+ # paths via pyproject [tool.coverage.run] so Sonar can match files) and runs
31
+ # the scanner, which
32
+ # reads sonar-project.properties (projectKey / organization / reportPaths)
33
+ # and the SONAR_TOKEN repo secret. Runs on PRs (new-code decoration) and on
34
+ # pushes to main (baseline). fetch-depth: 0 gives Sonar the full history it
35
+ # needs for accurate new-code / blame attribution.
36
+ # --------------------------------------------------------------------------
37
+ sonarcloud:
38
+ name: SonarCloud
39
+ runs-on: ubuntu-latest
40
+ # Promote a *presence flag* (not the secret) to job env so the scan step
41
+ # can gate on it — `secrets.*` isn't allowed in `if:`. Lets forks /
42
+ # token-less runs skip the scan rather than hard-fail. (Pattern from the
43
+ # sibling agentfront repo, whose CI-based SonarCloud scan is green.)
44
+ env:
45
+ SONAR_TOKEN_PRESENT: ${{ secrets.SONAR_TOKEN != '' }}
46
+ steps:
47
+ - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
48
+ with:
49
+ fetch-depth: 0
50
+ - uses: astral-sh/setup-uv@caf0cab7a618c569241d31dcd442f54681755d39 # v3
51
+ - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
52
+ with:
53
+ python-version: "3.12"
54
+ - run: uv venv
55
+ - run: uv pip install -e ".[dev]"
56
+ - run: uv run pytest --cov=src/devex --cov-report=xml --cov-report=term
57
+ # Pinned to v6 to match the sibling agentfront repo's working scan.
58
+ # The v7+/v8 scanner engine 404s on `api.sonarcloud.io/analysis/analyses`
59
+ # against SonarQube Cloud; v6 posts to sonarcloud.io directly.
60
+ - name: SonarCloud Scan
61
+ if: env.SONAR_TOKEN_PRESENT == 'true'
62
+ uses: SonarSource/sonarqube-scan-action@fd88b7d7ccbaefd23d8f36f73b59db7a3d246602 # v6
63
+ env:
64
+ SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
65
+ SONAR_HOST_URL: https://sonarcloud.io
66
+
26
67
  # --------------------------------------------------------------------------
27
68
  # Enforces that every PR touching code (src/, tests/, pyproject.toml) also
28
69
  # bumps the version in pyproject.toml. Without this, a merge to main that
@@ -208,6 +208,7 @@ marimo/_lsp/
208
208
  __marimo__/
209
209
 
210
210
  # Project
211
+ .devex/data/
211
212
  .agex/data/
212
213
 
213
214
  # Worktrees
@@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.26.1] - 2026-05-29
11
+
12
+ ### Added
13
+
14
+ - SonarCloud CI-based analysis + coverage upload: a `sonarcloud` job in test.yml runs `pytest --cov` and the SHA-pinned `sonarqube-scan-action` (v6), reading `sonar-project.properties` + the `SONAR_TOKEN` secret. Coverage config lives in `pyproject.toml [tool.coverage.run]` (`relative_files` so coverage.xml paths map to `sonar.sources=src`).
15
+
16
+ ### Changed
17
+
18
+ - SonarCloud moved from Automatic Analysis to CI-based analysis (the two are mutually exclusive); project now under the `agentculture` org. Updated CLAUDE.md / sonar-project.properties notes accordingly.
19
+
20
+ ## [0.26.0] - 2026-05-29
21
+
22
+ ### Added
23
+
24
+ - **`devex pr await <PR> --detach` / `--check`** — non-blocking await (#64). `--detach` forks a detached background poller that runs the same readiness → CI → Sonar-gate → thread-tally logic, writes the verdict to a marker (`.devex/data/pr/<PR>/await.json`, atomic `os.replace`), and returns immediately — taking the in-session `time.sleep` (and the prompt-cache re-read tax past the ~5-min TTL) out of the agent's context. `--check` reads that marker back without sleeping or re-polling: the stored briefing + the same non-zero-on-blocked exit code when done, a "still polling (started Ns ago)" notice while running, and a clear notice (never a crash or false "clean") when no run exists or the marker schema is incompatible. The detached worker always leaves a marker — even on `gh` failure, and even if the spawn itself fails — so `--check` is never left hanging. The two flags are mutually exclusive. New per-backend footer keys (`await_detached`, `await_check_pending`, `await_check_missing`, `await_check_incompatible`) ship for all four backends.
25
+ - **`devex pr open --detached-await`** — auto-wait at open time: after creating the PR (and posting the Qodo trigger), fork the detached `pr await` poller and return immediately, so "open → walk away → `pr await <PR> --check`" is one command. The non-blocking counterpart to `--delayed-read` (the two are mutually exclusive).
26
+
27
+ ### Changed
28
+
29
+ - **Renamed the tool from `agex` to `devex` end to end** — `devex` is now the canonical command, `devex-cli` the canonical PyPI distribution, and the Python module is `devex` (was `agent_experience`). The on-disk state directory is `.devex/` (was `.agex/`), with a transparent read-fallback to a pre-existing `.agex/` and a one-time migration on first write. **`agex` stays a fully working, non-breaking alias**: the `agex` console script and `agex-cli` distribution are still published, `agex` is still recognized as an invoked name, and `devex explain agex` resolves to the overview page. Kept stable for back-compat: the `agex_version` config-file key, the `agex:` gamify hook-fragment IDs, and the `agex hook write` command in the shipped hook asset.
30
+
10
31
  ## [0.25.0] - 2026-05-29
11
32
 
12
33
  ### Added
@@ -4,24 +4,24 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
4
4
 
5
5
  ## Project
6
6
 
7
- `agex` — non-agentic Python CLI that emits deterministic per-backend markdown briefings for autonomous agents. Published on PyPI under three distribution names: `agex-cli` (canonical), `agent-devex`, and `devex-cli` — the same wheel each time. CLI entry points: `agex` and `devex` (both invoke the same tool; emitted output reflects whichever name was typed). GitHub repo: `agentculture/devex`. Python module (unchanged): `agent_experience`.
7
+ `devex` — non-agentic Python CLI that emits deterministic per-backend markdown briefings for autonomous agents. Published on PyPI under three distribution names: `devex-cli` (canonical), `agent-devex`, and `agex-cli` (the legacy canonical name, still published) — the same wheel each time. CLI entry points: `devex` (canonical) and `agex` (legacy alias) — both invoke the same tool; emitted output reflects whichever name was typed. GitHub repo: `agentculture/devex`. Python module: `devex` (renamed from `agent_experience`).
8
8
 
9
9
  **Source-of-truth documents:**
10
10
 
11
11
  - Spec: `docs/superpowers/specs/2026-04-18-agex-design.md`
12
12
  - Implementation plan: `docs/superpowers/plans/2026-04-18-agex-v0.1.md` — 33 tasks across 12 phases.
13
- - Status: PR #1 merged Phases 1–3 (scaffolding, core, `agex explain`). Phases 4–12 (`overview`, `learn`, `gamify`, `hook`, backends, docs site, tester) remain.
13
+ - Status: PR #1 merged Phases 1–3 (scaffolding, core, `devex explain`). Phases 4–12 (`overview`, `learn`, `gamify`, `hook`, backends, docs site, tester) remain.
14
14
 
15
15
  Read the spec before any non-trivial change — the design invariants below are derived from it.
16
16
 
17
17
  ## Design invariants (non-negotiable)
18
18
 
19
- 1. **Zero LLM calls inside agex.** All output is deterministic markdown from Jinja templates + Python.
19
+ 1. **Zero LLM calls inside devex.** All output is deterministic markdown from Jinja templates + Python.
20
20
  2. **Markdown is the only output format.** No `--json` flag.
21
21
  3. **`--agent <backend>` is required** on backend-sensitive commands. The CLI never auto-detects.
22
- 4. **Side effects only in** `gamify`, `gamify --uninstall`, `hook write`, `pr open`, `pr reply`, `pr review`, `pr read` (journal writes), and first-run `.agex/` init. Everything else is read-only. The `agex pr` namespace allows scoped network I/O (via `gh`) and bounded `--wait` sleep — a deliberate carve-out from the no-network/no-sleep invariants.
22
+ 4. **Side effects only in** `gamify`, `gamify --uninstall`, `hook write`, `pr open`, `pr reply`, `pr review`, `pr read` (journal writes), `pr await` (journal + `--detach` marker writes under `.devex/data/pr/<pr>/` and the detached poller subprocess), and first-run `.devex/` init. Everything else is read-only. The `devex pr` namespace allows scoped network I/O (via `gh`), bounded `--wait` sleep, and for `pr await --detach` — a detached background process that pays that sleep outside the agent session; a deliberate carve-out from the no-network/no-sleep invariants.
23
23
  5. **"Unsupported" is success** — exit 0 with a markdown notice that links to the issue tracker, not a non-zero exit.
24
- 6. **Skills are authored by the agent, not shipped by agex.** `agex learn <topic>` teaches; `agex explain <topic>` describes; agex never writes a user skill file on the agent's behalf in v0.1.
24
+ 6. **Skills are authored by the agent, not shipped by devex.** `devex learn <topic>` teaches; `devex explain <topic>` describes; devex never writes a user skill file on the agent's behalf in v0.1.
25
25
 
26
26
  ## Architecture (3-stage pipeline)
27
27
 
@@ -36,17 +36,18 @@ cli.py ──► commands/<name>/scripts/<name>.py ──► core/render.py
36
36
  (supported / unsupported)
37
37
  ```
38
38
 
39
- - `cli.py` (Typer) routes `agex <command> [args] --agent X`. No business logic.
40
- - Each `commands/<name>/` is a **skill-folder**: `SKILL.md` + `scripts/` + `assets/` + `references/`. The `SKILL.md` doubles as the content emitted by `agex explain <command>`.
41
- - `core/` is shared plumbing — backend enum, `.agex/` paths, Jinja renderer (`StrictUndefined`), TOML config, SKILL.md frontmatter parser, capability matrix loader, hook JSON I/O. Command- and content-agnostic.
39
+ - `cli.py` (Typer) routes `devex <command> [args] --agent X`. No business logic.
40
+ - Each `commands/<name>/` is a **skill-folder**: `SKILL.md` + `scripts/` + `assets/` + `references/`. The `SKILL.md` doubles as the content emitted by `devex explain <command>`.
41
+ - `core/` is shared plumbing — backend enum, `.devex/` paths, Jinja renderer (`StrictUndefined`), TOML config, SKILL.md frontmatter parser, capability matrix loader, hook JSON I/O. Command- and content-agnostic.
42
42
  - A backend lives in three places: `core/backend.Backend` (enum entry), `backends/<name>/probe.py` (optional Python probe), and one YAML per relevant command under `commands/*/assets/backends/<name>.yaml`. Adding a backend touches only those locations.
43
43
 
44
- ## `agex pr` namespace (v0.17.0+)
44
+ ## `devex pr` namespace (v0.17.0+)
45
45
 
46
- `lint`, `open`, `read`, `reply`, `review`, `await`, `delta`. Each command ends with a deterministic "Next step:" footer. The `pr` namespace allows scoped network I/O (via `gh`) and bounded `--wait` sleep — a deliberate carve-out from the no-network/no-sleep invariants. `pr open` (non-draft, new PR) and `pr review` post the Qodo `/agentic_review` trigger comment; the legacy `/improve` is deprecated and never emitted. The trigger string lives in one place: `commands/pr/scripts/review.QODO_REVIEW_TRIGGER`. Key modules:
46
+ `lint`, `open`, `read`, `reply`, `review`, `await`, `delta`. Each command ends with a deterministic "Next step:" footer. The `pr` namespace allows scoped network I/O (via `gh`) and bounded `--wait` sleep — a deliberate carve-out from the no-network/no-sleep invariants. `pr open` (non-draft, new PR) and `pr review` post the Qodo `/agentic_review` trigger comment; the legacy `/improve` is deprecated and never emitted. The trigger string lives in one place: `commands/pr/scripts/review.QODO_REVIEW_TRIGGER`. `pr await --detach` / `--check` (issue #64) move the bounded poll out of the agent session: `--detach` forks a detached worker (`commands/pr/scripts/_await_worker.py`) that writes the verdict to a marker (`commands/pr/scripts/_detach.py`, atomic `os.replace`), and `--check` reads it back without sleeping. Key modules:
47
47
 
48
48
  - `core/github.py` — thin `gh` shellout wrapper; future zero-trust httpx swap touches only this file.
49
- - `core/journal.py` — nested-stream JSONL append/load for `.agex/data/<dir>/<stream>.jsonl`.
49
+ - `commands/pr/scripts/_detach.py` — await-marker read/write (atomic) + the detached-subprocess spawn helper.
50
+ - `core/journal.py` — nested-stream JSONL append/load for `.devex/data/<dir>/<stream>.jsonl`.
50
51
  - `core/backend.resolve_backend()` — `--agent` resolution with `culture.yaml` fallback.
51
52
  - `commands/pr/assets/rules/next_step_rules.py` — "Next step:" footer decision logic, per-backend phrasing under `commands/pr/assets/backends/<backend>.yaml`.
52
53
 
@@ -57,8 +58,8 @@ Spec: `docs/superpowers/specs/2026-05-10-agex-pr-design.md`. Plan: `docs/superpo
57
58
  - **Resource loading: use `importlib.resources.files(...)` and treat the result as a `Traversable`.** Call `.joinpath()` / `.is_file()` / `.read_text(encoding="utf-8")` directly. Wrap with `importlib.resources.as_file()` only when a third-party API needs a real `pathlib.Path`. Do NOT do `Path(str(files(...)))` — it's not zipapp/PEX safe.
58
59
  - **File locking: use `portalocker.lock` / `portalocker.unlock`.** Reaching for `fcntl.flock` / `msvcrt.locking` directly is a known foot-gun on Windows (see commit `923f639`).
59
60
  - **Always pass `encoding="utf-8"` to `read_text` / `write_text`.** Default locale on Windows corrupts non-ASCII output.
60
- - **Validate user-controlled CLI args before joining into paths.** `agex explain <topic>` rejects anything that doesn't match `^[a-z][a-z0-9-]*$` to block path traversal (commit `5ac796e`, test `test_explain_rejects_path_traversal`).
61
- - **Single source of truth for the version:** `pyproject.toml`. `agent_experience.__version__` derives from installed distribution metadata via `importlib.metadata.version("agex-cli")`, and `Config.agex_version` derives from `__version__` via `field(default_factory=...)`. Bumping the version means editing `pyproject.toml` only — no `__init__.py` edit needed.
61
+ - **Validate user-controlled CLI args before joining into paths.** `devex explain <topic>` rejects anything that doesn't match `^[a-z][a-z0-9-]*$` to block path traversal (commit `5ac796e`, test `test_explain_rejects_path_traversal`).
62
+ - **Single source of truth for the version:** `pyproject.toml`. `devex.__version__` derives from installed distribution metadata via `importlib.metadata.version("devex-cli")` (falling back to the `agent-devex` / `agex-cli` alias dists, then pyproject), and `Config.agex_version` derives from `__version__` via `field(default_factory=...)`. (The `agex_version` config-file key name is kept for back-compat with existing `.devex/config.toml` / `.agex/config.toml` files.) Bumping the version means editing `pyproject.toml` only — no `__init__.py` edit needed.
62
63
 
63
64
  ## Common commands
64
65
 
@@ -73,24 +74,24 @@ uv run pytest
73
74
  uv run pytest tests/core/test_paths.py::test_ensure_init_creates_dir_and_gitignore -v
74
75
 
75
76
  # Run the CLI
76
- uv run agex --version
77
- uv run agex explain agex
78
- uv run agex explain explain
77
+ uv run devex --version
78
+ uv run devex explain devex
79
+ uv run devex explain explain
79
80
 
80
- # Coverage (matches what build.yml runs; SonarCloud reads this file)
81
- uv run pytest --cov=src/agent_experience --cov-report=xml --cov-report=term
81
+ # Coverage (matches the `sonarcloud` job in test.yml; SonarCloud reads coverage.xml)
82
+ uv run pytest --cov=src/devex --cov-report=xml --cov-report=term
82
83
  ```
83
84
 
84
85
  ## CI surface
85
86
 
86
- - `.github/workflows/test.yml` — matrix: 3 OS × 4 Python (3.10–3.13) running `uv run pytest`. Also runs a `version-check` job on PRs that fails (with a sticky `<!-- version-check -->` comment) when `pyproject.toml`'s version on the PR matches the one on `main` and any code file under `src/` / `tests/` / `pyproject.toml` changed. Docs-only PRs skip the check.
87
+ - `.github/workflows/test.yml` — matrix: 3 OS × 4 Python (3.10–3.13) running `uv run pytest`. Also runs (1) a `sonarcloud` job that generates `coverage.xml` (`pytest --cov`, repo-relative paths via `pyproject [tool.coverage.run]`) and runs the SHA-pinned `sonarqube-scan-action` (needs the `SONAR_TOKEN` repo secret); and (2) a `version-check` job on PRs that fails (with a sticky `<!-- version-check -->` comment) when `pyproject.toml`'s version on the PR matches the one on `main` and any code file under `src/` / `tests/` / `pyproject.toml` changed. Docs-only PRs skip the version check.
87
88
  - `.github/workflows/publish.yml` — builds sdist + wheel. PRs publish a per-PR dev version to TestPyPI (sticky install-command comment); pushes to `main` publish the stable version to TestPyPI (canary), then an `autotag` job pushes `v<version>` if missing, which gates the inline `publish-pypi` + `github-release` jobs. No manual tagging — bumping `pyproject.toml` is the release signal.
88
- - SonarCloud is configured as **Automatic Analysis** on the repo (no CI workflow). Coverage and quality are read by SonarCloud directly.
89
+ - SonarCloud runs in **CI-based analysis** mode (Automatic Analysis is off — the two are mutually exclusive). The `sonarcloud` job in `test.yml` uploads coverage + triggers the scan via `sonarqube-scan-action`, reading `sonar-project.properties` and the `SONAR_TOKEN` secret. The quality gate decorates PRs and gates merges.
89
90
  - All third-party actions are **pinned to full commit SHAs** with trailing `# vN` comments (rule `githubactions:S7637`). Keep new actions pinned the same way.
90
91
 
91
92
  ## SonarCloud notes
92
93
 
93
- - `python:S5496` is **narrowly suppressed** for `src/agent_experience/core/render.py` only via `sonar.issue.ignore.multicriteria` in `sonar-project.properties`. Reason: `render_string()` renders Jinja templates that are always package-shipped; output is markdown, never HTML in a browser. See the comment in `render.py` above `render_string` for the rationale. Do not widen the suppression to other files.
94
+ - `python:S5496` is **narrowly suppressed** for `src/devex/core/render.py` only via `sonar.issue.ignore.multicriteria` in `sonar-project.properties`. Reason: `render_string()` renders Jinja templates that are always package-shipped; output is markdown, never HTML in a browser. See the comment in `render.py` above `render_string` for the rationale. Do not widen the suppression to other files.
94
95
  - The `render.py` autoescape decision is explicit (`autoescape=select_autoescape([])`). Don't change it.
95
96
 
96
97
  ## Git workflow
@@ -100,6 +101,6 @@ uv run pytest --cov=src/agent_experience --cov-report=xml --cov-report=term
100
101
  - Push, open a PR, let CI + SonarCloud + Qodo + Copilot run. Address inline comments + resolve threads before merge.
101
102
  - Merging to `main` publishes to PyPI automatically (via `autotag` → `publish-pypi` → `github-release` in `publish.yml`). No manual tagging.
102
103
  - When posting on GitHub on the user's behalf (PR descriptions, issue replies, review-thread replies), sign so it's clear the message came from an AI. Three conventions, in priority order:
103
- - **`agex pr open` / `agex pr reply`** — auto-append `- agex-cli (Claude)` (the nick is resolved from `culture.yaml` via `core.github.resolve_nick`, falling back to the repo basename). Don't sign manually.
104
+ - **`devex pr open` / `devex pr reply`** — auto-append `- devex-cli (Claude)` (the nick is resolved from `culture.yaml` via `core.github.resolve_nick`, falling back to the repo basename). Don't sign manually.
104
105
  - **Inside `communicate` workflow scripts** (`post-issue.sh`, `post-comment.sh`) — `agtag` resolves the same nick from `culture.yaml`. Don't sign manually.
105
- - **Manual posts the scripts didn't author** (a hand-typed `gh pr create --body …`, a one-off review reply) — sign explicitly as `- agex-cli (Claude)`.
106
+ - **Manual posts the scripts didn't author** (a hand-typed `gh pr create --body …`, a one-off review reply) — sign explicitly as `- devex-cli (Claude)`.
@@ -1,8 +1,8 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agex-cli
3
- Version: 0.25.0
3
+ Version: 0.26.1
4
4
  Summary: Agent-operated developer-experience CLI — deterministic per-backend markdown briefings for autonomous agents.
5
- Project-URL: Homepage, https://culture.dev/agex/
5
+ Project-URL: Homepage, https://culture.dev/devex/
6
6
  Project-URL: Repository, https://github.com/agentculture/devex
7
7
  Project-URL: Issues, https://github.com/agentculture/devex/issues
8
8
  Author: Ori Nachum
@@ -24,29 +24,29 @@ Requires-Dist: pytest>=8.0; extra == 'dev'
24
24
  Requires-Dist: syrupy>=4.6; extra == 'dev'
25
25
  Description-Content-Type: text/markdown
26
26
 
27
- # agex
27
+ # devex
28
28
 
29
- Agent-operated developer-experience CLI. Non-agentic, deterministic, markdown-first. The same wheel is published on PyPI under three distribution names — `agex-cli` (canonical), `agent-devex`, and `devex-cli` — and installs two equivalent commands, `agex` and `devex` (emitted output reflects whichever name you invoke).
29
+ Agent-operated developer-experience CLI. Non-agentic, deterministic, markdown-first. The same wheel is published on PyPI under three distribution names — `devex-cli` (canonical), `agent-devex`, and `agex-cli` (the legacy canonical name, still published) — and installs two equivalent commands, `devex` (canonical) and `agex` (legacy alias) (emitted output reflects whichever name you invoke).
30
30
 
31
31
  ## Install
32
32
 
33
33
  ```bash
34
- uv tool install agex-cli # or: devex-cli
34
+ uv tool install devex-cli # or: agex-cli
35
35
  # or
36
- pipx install agex-cli # or: pipx install devex-cli
36
+ pipx install devex-cli # or: pipx install agex-cli
37
37
  ```
38
38
 
39
39
  ## Quick start
40
40
 
41
41
  ```bash
42
- agex explain agex
43
- agex overview --agent claude-code
44
- agex learn --agent claude-code
42
+ devex explain devex
43
+ devex overview --agent claude-code
44
+ devex learn --agent claude-code
45
45
  ```
46
46
 
47
47
  ## Docs
48
48
 
49
- [culture.dev/agex](https://culture.dev/agex/).
49
+ [culture.dev/devex](https://culture.dev/devex/).
50
50
 
51
51
  Spec: `docs/superpowers/specs/2026-04-18-agex-design.md`.
52
52
 
@@ -0,0 +1,29 @@
1
+ # devex
2
+
3
+ Agent-operated developer-experience CLI. Non-agentic, deterministic, markdown-first. The same wheel is published on PyPI under three distribution names — `devex-cli` (canonical), `agent-devex`, and `agex-cli` (the legacy canonical name, still published) — and installs two equivalent commands, `devex` (canonical) and `agex` (legacy alias) (emitted output reflects whichever name you invoke).
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ uv tool install devex-cli # or: agex-cli
9
+ # or
10
+ pipx install devex-cli # or: pipx install agex-cli
11
+ ```
12
+
13
+ ## Quick start
14
+
15
+ ```bash
16
+ devex explain devex
17
+ devex overview --agent claude-code
18
+ devex learn --agent claude-code
19
+ ```
20
+
21
+ ## Docs
22
+
23
+ [culture.dev/devex](https://culture.dev/devex/).
24
+
25
+ Spec: `docs/superpowers/specs/2026-04-18-agex-design.md`.
26
+
27
+ ## License
28
+
29
+ MIT.
@@ -1,3 +1,3 @@
1
1
  agents:
2
- - suffix: agex-cli
2
+ - suffix: devex-cli
3
3
  backend: claude
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "agex-cli"
3
- version = "0.25.0"
3
+ version = "0.26.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"}
@@ -26,11 +26,11 @@ dev = [
26
26
  ]
27
27
 
28
28
  [project.scripts]
29
- agex = "agent_experience.cli:_main_entrypoint"
30
- devex = "agent_experience.cli:_main_entrypoint"
29
+ devex = "devex.cli:_main_entrypoint"
30
+ agex = "devex.cli:_main_entrypoint"
31
31
 
32
32
  [project.urls]
33
- Homepage = "https://culture.dev/agex/"
33
+ Homepage = "https://culture.dev/devex/"
34
34
  Repository = "https://github.com/agentculture/devex"
35
35
  Issues = "https://github.com/agentculture/devex/issues"
36
36
 
@@ -39,12 +39,27 @@ requires = ["hatchling"]
39
39
  build-backend = "hatchling.build"
40
40
 
41
41
  [tool.hatch.build.targets.wheel]
42
- packages = ["src/agent_experience"]
42
+ packages = ["src/devex"]
43
43
 
44
44
  [tool.pytest.ini_options]
45
45
  testpaths = ["tests"]
46
46
  addopts = "-n auto -v"
47
47
 
48
+ [tool.coverage.run]
49
+ source = ["src/devex"]
50
+ # Emit repo-relative paths in coverage.xml so SonarCloud maps them to
51
+ # sonar.sources=src (absolute / .venv paths fail to map → empty coverage).
52
+ relative_files = true
53
+
54
+ [tool.coverage.report]
55
+ show_missing = true
56
+ fail_under = 60
57
+ exclude_lines = [
58
+ "pragma: no cover",
59
+ "if __name__ == .__main__.",
60
+ "if TYPE_CHECKING:",
61
+ ]
62
+
48
63
  [tool.black]
49
64
  line-length = 100
50
65
 
@@ -54,7 +69,7 @@ line_length = 100
54
69
 
55
70
  [tool.bandit]
56
71
  # B311 flags any `random.*` usage as potentially unsafe for crypto purposes.
57
- # `core/hook_io._acquire_lock_with_retry` uses `random.uniform` purely for
72
+ # `core/_jsonl.acquire_lock_with_retry` uses `random.uniform` purely for
58
73
  # backoff jitter between bounded retries -- not a security context, so the
59
74
  # standard `random` module is the right choice (secrets would be misuse).
60
75
  skips = ["B311"]
@@ -1,5 +1,5 @@
1
1
  sonar.projectKey=agentculture_devex
2
- sonar.organization=orinachum
2
+ sonar.organization=agentculture
3
3
 
4
4
  # Displayed in SonarCloud UI
5
5
  sonar.projectName=devex
@@ -12,12 +12,11 @@ sonar.sourceEncoding=UTF-8
12
12
  # Python: target versions (matches CI matrix)
13
13
  sonar.python.version=3.10, 3.11, 3.12, 3.13
14
14
 
15
- # Coverage report path. SonarCloud runs in Automatic Analysis mode (no
16
- # CI-based scansee PR #20). Automatic Analysis doesn't upload
17
- # pytest-cov output; this key remains so that if/when we ever revisit
18
- # coverage delivery, the file path is already declared. The bugs /
19
- # vulnerabilities / code-smells portion of the analysis works without
20
- # coverage and is what gates the PR quality gate today.
15
+ # Coverage report path. SonarCloud now runs in CI-based analysis mode
16
+ # (Automatic Analysis is OFF the two are mutually exclusive). The `sonarcloud`
17
+ # job in .github/workflows/test.yml runs `pytest --cov` (repo-relative paths
18
+ # via pyproject [tool.coverage.run], so Sonar can match files) and the
19
+ # sonarqube-scan-action uploads this report. Requires the SONAR_TOKEN repo secret.
21
20
  sonar.python.coverage.reportPaths=coverage.xml
22
21
 
23
22
  # S5496 triggers on render_string() because it renders a Jinja template with a
@@ -30,17 +29,17 @@ sonar.python.coverage.reportPaths=coverage.xml
30
29
  # S2083 (path injection) fires in commands/gamify/scripts/install.py because
31
30
  # the hooks file path is `Path.cwd() / ".claude" / "hooks.json"`. `Path.cwd()`
32
31
  # is the process's working directory (set by the user's shell before invoking
33
- # agex); `.claude` and `hooks.json` are hardcoded literals. No HTTP body, CLI
32
+ # devex); `.claude` and `hooks.json` are hardcoded literals. No HTTP body, CLI
34
33
  # string argument, or other network/request input is ever joined into this
35
34
  # path — the backend name is enum-validated by `parse_backend()` before reaching
36
35
  # install.py and does not itself flow into the path. S2083 is designed for
37
36
  # web contexts where a request-body filename taints a filesystem call; that
38
37
  # threat model does not apply here. Writing `.claude/hooks.json` is the
39
- # documented contract of `agex gamify` (design spec invariant #4: "Side
38
+ # documented contract of `devex gamify` (design spec invariant #4: "Side
40
39
  # effects only in gamify, gamify --uninstall, hook write, and first-run
41
- # `.agex/` init"). Rule is disabled only for this one file.
40
+ # `.devex/` init"). Rule is disabled only for this one file.
42
41
  sonar.issue.ignore.multicriteria=e1,e2
43
42
  sonar.issue.ignore.multicriteria.e1.ruleKey=pythonsecurity:S5496
44
- sonar.issue.ignore.multicriteria.e1.resourceKey=src/agent_experience/core/render.py
43
+ sonar.issue.ignore.multicriteria.e1.resourceKey=src/devex/core/render.py
45
44
  sonar.issue.ignore.multicriteria.e2.ruleKey=pythonsecurity:S2083
46
- sonar.issue.ignore.multicriteria.e2.resourceKey=src/agent_experience/commands/gamify/scripts/install.py
45
+ sonar.issue.ignore.multicriteria.e2.resourceKey=src/devex/commands/gamify/scripts/install.py
@@ -2,14 +2,15 @@ from importlib.metadata import PackageNotFoundError, version
2
2
 
3
3
 
4
4
  def _resolve_version() -> str:
5
- # `agex-cli` is the canonical PyPI distribution name; `agent-devex` and
6
- # `devex-cli` are alias distributions that ship the identical wheel under
7
- # different names. Whichever one is installed, surface its metadata
5
+ # `devex-cli` is the canonical PyPI distribution name; `agent-devex` and
6
+ # `agex-cli` are alias distributions that ship the identical wheel under
7
+ # different names (`agex-cli` is the legacy canonical name, kept published
8
+ # for back-compat). Whichever one is installed, surface its metadata
8
9
  # version. As a final fallback for unbuilt source checkouts (no installed
9
10
  # dist metadata), read the version directly from the repo's pyproject.toml
10
11
  # so the version stays single-sourced from pyproject.toml in every
11
12
  # reachable code path.
12
- for dist in ("agex-cli", "agent-devex", "devex-cli"):
13
+ for dist in ("devex-cli", "agent-devex", "agex-cli"):
13
14
  try:
14
15
  return version(dist)
15
16
  except PackageNotFoundError:
@@ -1,4 +1,4 @@
1
- from agent_experience.cli import _main_entrypoint
1
+ from devex.cli import _main_entrypoint
2
2
 
3
3
  if __name__ == "__main__":
4
4
  _main_entrypoint()
@@ -1,6 +1,6 @@
1
1
  from pathlib import Path
2
2
 
3
- from agent_experience.backends.claude_code.probe import ProbeResult
3
+ from devex.backends.claude_code.probe import ProbeResult
4
4
 
5
5
 
6
6
  def probe(project_dir: Path) -> ProbeResult:
@@ -1,7 +1,7 @@
1
1
  hooks: false
2
2
  hooks_alternative: |
3
3
  Codex does not expose a hook interface. Wrap your Codex invocation in a shell
4
- script that calls `agex hook write` before/after each turn as a workaround.
4
+ script that calls `devex hook write` before/after each turn as a workaround.
5
5
  mcp: true
6
6
  skills: false
7
7
  agents: false
@@ -1,7 +1,7 @@
1
1
  hooks: false
2
2
  hooks_alternative: |
3
3
  GitHub Copilot CLI does not expose a hook interface in v0.1-era versions.
4
- Track usage via a shell wrapper that calls `agex hook write`.
4
+ Track usage via a shell wrapper that calls `devex hook write`.
5
5
  mcp: false
6
6
  skills: false
7
7
  agents: false
@@ -5,7 +5,7 @@ from typing import Any
5
5
 
6
6
  import yaml
7
7
 
8
- from agent_experience.core.skill_loader import load_skill
8
+ from devex.core.skill_loader import load_skill
9
9
 
10
10
  _CLAUDE_DIR = ".claude"
11
11
 
@@ -1,6 +1,6 @@
1
1
  from pathlib import Path
2
2
 
3
- from agent_experience.backends.claude_code.probe import ProbeResult
3
+ from devex.backends.claude_code.probe import ProbeResult
4
4
 
5
5
 
6
6
  def probe(project_dir: Path) -> ProbeResult:
@@ -1,6 +1,6 @@
1
1
  from pathlib import Path
2
2
 
3
- from agent_experience.backends.claude_code.probe import ProbeResult
3
+ from devex.backends.claude_code.probe import ProbeResult
4
4
 
5
5
 
6
6
  def probe(project_dir: Path) -> ProbeResult: