lemming-cli 0.4.6__tar.gz → 0.5.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 (194) hide show
  1. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/PKG-INFO +69 -30
  2. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/README.md +67 -29
  3. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/SKILL.md +78 -7
  4. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/docs/HOOKS.md +20 -5
  5. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/pyproject.toml +2 -1
  6. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/exec_cli.py +23 -6
  7. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/exec_cli_test.py +248 -1
  8. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/main_test.py +1 -1
  9. lemming_cli-0.5.1/src/lemming/cli/skill.py +7 -0
  10. lemming_cli-0.5.1/src/lemming/cli/skill_test.py +47 -0
  11. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/orchestrator.py +101 -46
  12. lemming_cli-0.5.1/src/lemming/prompts/hooks/60-testing.md +65 -0
  13. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/prompts/hooks/90-roadmap.md +4 -3
  14. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/uv.lock +19 -1
  15. lemming_cli-0.4.6/src/lemming/cli/skill.py +0 -344
  16. lemming_cli-0.4.6/src/lemming/cli/skill_test.py +0 -151
  17. lemming_cli-0.4.6/src/lemming/prompts/hooks/60-testing.md +0 -48
  18. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/.dockerignore +0 -0
  19. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/.github/workflows/ci.yml +0 -0
  20. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/.github/workflows/publish.yml +0 -0
  21. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/.github/workflows/screenshots.yml +0 -0
  22. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/.gitignore +0 -0
  23. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/.prettierignore +0 -0
  24. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/.prettierrc +0 -0
  25. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/Dockerfile +0 -0
  26. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/LICENSE +0 -0
  27. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/biome.json +0 -0
  28. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/docker-compose.yml +0 -0
  29. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/docs/EVALS.md +0 -0
  30. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/docs/screenshots/dashboard-desktop.png +0 -0
  31. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/docs/screenshots/dashboard-mobile.png +0 -0
  32. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/docs/screenshots/task-log-desktop.png +0 -0
  33. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/docs/screenshots/task-log-mobile.png +0 -0
  34. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/package-lock.json +0 -0
  35. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/package.json +0 -0
  36. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/playwright.config.js +0 -0
  37. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/pyrefly.toml +0 -0
  38. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/__init__.py +0 -0
  39. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/__init__.py +0 -0
  40. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/auth.py +0 -0
  41. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/auth_test.py +0 -0
  42. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/config.py +0 -0
  43. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/config_test.py +0 -0
  44. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/conftest.py +0 -0
  45. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/context.py +0 -0
  46. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/context_test.py +0 -0
  47. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/directories.py +0 -0
  48. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/directories_test.py +0 -0
  49. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/files.py +0 -0
  50. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/files_test.py +0 -0
  51. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/hooks.py +0 -0
  52. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/hooks_test.py +0 -0
  53. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/logging.py +0 -0
  54. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/logging_test.py +0 -0
  55. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/loop.py +0 -0
  56. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/loop_test.py +0 -0
  57. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/main.py +0 -0
  58. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/main_test.py +0 -0
  59. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/tasks.py +0 -0
  60. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/tasks_test.py +0 -0
  61. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api_test.py +0 -0
  62. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/brief_test.py +0 -0
  63. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/__init__.py +0 -0
  64. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/brief.py +0 -0
  65. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/config.py +0 -0
  66. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/config_test.py +0 -0
  67. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/goal.py +0 -0
  68. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/goal_test.py +0 -0
  69. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/hooks.py +0 -0
  70. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/hooks_test.py +0 -0
  71. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/machine_output_test.py +0 -0
  72. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/main.py +0 -0
  73. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/operations.py +0 -0
  74. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/operations_test.py +0 -0
  75. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/progress.py +0 -0
  76. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/progress_test.py +0 -0
  77. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/readability_cli.py +0 -0
  78. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/readability_cli_test.py +0 -0
  79. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/stop_test.py +0 -0
  80. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/tasks.py +0 -0
  81. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/tasks_test.py +0 -0
  82. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli_test.py +0 -0
  83. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/conftest.py +0 -0
  84. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/__init__.py +0 -0
  85. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/__main__.py +0 -0
  86. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/cli.py +0 -0
  87. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/cli_test.py +0 -0
  88. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/container.py +0 -0
  89. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/container_test.py +0 -0
  90. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/fixtures.py +0 -0
  91. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/fixtures_test.py +0 -0
  92. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/harness.py +0 -0
  93. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/harness_test.py +0 -0
  94. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/metrics.py +0 -0
  95. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/metrics_test.py +0 -0
  96. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/base/README.md +0 -0
  97. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/base/calc/__init__.py +0 -0
  98. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/base/calc/legacy.py +0 -0
  99. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/base/calc/ops.py +0 -0
  100. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/base/calc/ops_test.py +0 -0
  101. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/clean/calc/ops.py +0 -0
  102. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/clean/calc/ops_test.py +0 -0
  103. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/dead-code/calc/ops.py +0 -0
  104. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/dead-code/calc/ops_test.py +0 -0
  105. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/duplicated-behavior/calc/ops.py +0 -0
  106. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/duplicated-behavior/calc/ops_test.py +0 -0
  107. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/false-reuse/calc/limits.py +0 -0
  108. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/false-reuse/calc/limits_test.py +0 -0
  109. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/lint-debt/calc/ops.py +0 -0
  110. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/lint-debt/calc/ops_test.py +0 -0
  111. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/add-only/README.md +0 -0
  112. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/add-only/calc/__init__.py +0 -0
  113. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/add-only/calc/ops.py +0 -0
  114. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/add-only/calc/ops_test.py +0 -0
  115. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/buggy-subtract/README.md +0 -0
  116. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/buggy-subtract/calc/__init__.py +0 -0
  117. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/buggy-subtract/calc/ops.py +0 -0
  118. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/buggy-subtract/calc/ops_test.py +0 -0
  119. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/full-ops/README.md +0 -0
  120. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/full-ops/calc/__init__.py +0 -0
  121. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/full-ops/calc/ops.py +0 -0
  122. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/full-ops/calc/ops_test.py +0 -0
  123. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/unwired-cli/README.md +0 -0
  124. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/unwired-cli/calc/__init__.py +0 -0
  125. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/unwired-cli/calc/cli.py +0 -0
  126. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/unwired-cli/calc/cli_test.py +0 -0
  127. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/unwired-cli/calc/ops.py +0 -0
  128. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/unwired-cli/calc/ops_test.py +0 -0
  129. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/task/hidden/stats/summary_hidden_test.py +0 -0
  130. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/task/summary/README.md +0 -0
  131. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/task/summary/stats/__init__.py +0 -0
  132. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/task/summary/stats/summary.py +0 -0
  133. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/task/summary/stats/summary_test.py +0 -0
  134. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/readability.py +0 -0
  135. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/readability_test.py +0 -0
  136. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/report.py +0 -0
  137. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/report_test.py +0 -0
  138. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/roadmap.py +0 -0
  139. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/roadmap_test.py +0 -0
  140. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/scenarios.py +0 -0
  141. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/scenarios_test.py +0 -0
  142. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/suites.py +0 -0
  143. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/task.py +0 -0
  144. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/task_test.py +0 -0
  145. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/trial.py +0 -0
  146. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/trial_test.py +0 -0
  147. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/hooks.py +0 -0
  148. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/hooks_test.py +0 -0
  149. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/integration_test.py +0 -0
  150. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/main.py +0 -0
  151. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/main_test.py +0 -0
  152. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/models.py +0 -0
  153. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/models_test.py +0 -0
  154. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/orchestrator_test.py +0 -0
  155. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/paths.py +0 -0
  156. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/paths_test.py +0 -0
  157. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/persistence.py +0 -0
  158. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/persistence_test.py +0 -0
  159. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/prompts/hooks/50-readability.md +0 -0
  160. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/prompts/hooks/70-ux.md +0 -0
  161. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/prompts/taskrunner.md +0 -0
  162. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/prompts.py +0 -0
  163. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/prompts_test.py +0 -0
  164. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/providers.py +0 -0
  165. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/providers_test.py +0 -0
  166. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/runner.py +0 -0
  167. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/runner_test.py +0 -0
  168. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/scope.py +0 -0
  169. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/scope_test.py +0 -0
  170. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/shutdown.py +0 -0
  171. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/shutdown_integration_test.py +0 -0
  172. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/shutdown_test.py +0 -0
  173. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/__init__.py +0 -0
  174. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/lifecycle.py +0 -0
  175. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/lifecycle_test.py +0 -0
  176. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/limits.py +0 -0
  177. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/operations.py +0 -0
  178. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/operations_test.py +0 -0
  179. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/progress.py +0 -0
  180. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/progress_test.py +0 -0
  181. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/queries.py +0 -0
  182. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/queries_test.py +0 -0
  183. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/dashboard.spec.js +0 -0
  184. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/dashboard.test.js +0 -0
  185. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/favicon.js +0 -0
  186. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/favicon.spec.js +0 -0
  187. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/files.html +0 -0
  188. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/files.spec.js +0 -0
  189. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/index.html +0 -0
  190. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/index.js +0 -0
  191. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/logs.html +0 -0
  192. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/logs.test.js +0 -0
  193. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/mancha.js +0 -0
  194. {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/screenshots.spec.js +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: lemming-cli
3
- Version: 0.4.6
3
+ Version: 0.5.1
4
4
  Summary: An autonomous, iterative task runner for AI coding agents.
5
5
  Project-URL: Homepage, https://github.com/owahltinez/lemming
6
6
  Project-URL: Repository, https://github.com/owahltinez/lemming
@@ -10,6 +10,7 @@ License-File: LICENSE
10
10
  Keywords: agents,ai,antigravity,automation,claude,opencode
11
11
  Requires-Python: >=3.12
12
12
  Requires-Dist: beautifulsoup4>=4.13.3
13
+ Requires-Dist: click-agentcli>=0.3.0
13
14
  Requires-Dist: click>=8.0.0
14
15
  Requires-Dist: fastapi>=0.124.4
15
16
  Requires-Dist: markdownify>=0.14.1
@@ -112,10 +113,19 @@ runner, and the agent's closing message comes back on stdout.
112
113
  # Delegate one task to a different agent, e.g. to spare another's quota
113
114
  lemming exec "Fix the flaky test in runner_test.py" --runner codex
114
115
 
116
+ # Allow up to three total attempts for transient runner failures
117
+ lemming exec "Fix the flaky test in runner_test.py" --retries 3
118
+
115
119
  # Pipe a longer handoff instead of fighting shell quoting
116
- cat handoff.md | lemming exec -f - --runner agy
120
+ cat handoff.md | lemming -v exec -f - --runner agy
117
121
  ```
118
122
 
123
+ The runner receives no conversation history and cannot be steered mid-run.
124
+ Make the handoff self-contained: state the goal, hard constraints, relevant
125
+ findings and evidence, approaches ruled out and why, and the definition of done
126
+ and verification. The installed skill includes a complete here-document
127
+ example for orchestrating agents.
128
+
119
129
  With no description there is nothing for a task runner to do, so only the
120
130
  reviews run — against work that already exists.
121
131
 
@@ -124,7 +134,7 @@ reviews run — against work that already exists.
124
134
  lemming exec --review readability
125
135
 
126
136
  # Review someone else's branch, checked out in a worktree
127
- lemming exec -C ../review-worktree --review testing --scope main...HEAD
137
+ lemming -C ../review-worktree exec --review testing --scope main...HEAD
128
138
 
129
139
  # Do the work, then gate it
130
140
  lemming exec "Add pagination to the tasks API" --review all
@@ -134,14 +144,23 @@ lemming exec "Add pagination to the tasks API" --review all
134
144
  which is resolved to the files it changed. It defaults to uncommitted work, or
135
145
  to the whole tree outside a git repository.
136
146
 
147
+ Reviews may edit the working directory. The built-in readability review
148
+ intentionally applies fixes, and testing may repair production code or tests.
149
+ UX is instructed to remain advisory, but its prompt and `--no-yolo` do not
150
+ enforce filesystem isolation. A global review override may perform any actions
151
+ its prompt requests. When isolation is required, follow the working-copy
152
+ guidance below and pass a separate VCS-managed working copy with
153
+ `lemming -C <working-copy> exec --review ...`.
154
+
137
155
  Each run is self-contained: nothing is read from the project's roadmap or its
138
- local hooks, one agent run is attempted, and the run's state directory is
139
- removed unless it failed — in which case it is kept, and its path printed, so
140
- the log can be read. Kept directories live in `~/.local/lemming/exec-*` and are
141
- retired automatically a week later, so a recent failure is always still there to
142
- inspect. Stdout carries the agent's message alone and everything else goes to
143
- stderr, so the output can be consumed directly. Stderr reports the ephemeral
144
- tasks file and task ID at startup; pass those to
156
+ local hooks, it runs only the requested task and reviews, and its state
157
+ directory is removed unless it failed — in which case it is kept, and its path
158
+ printed, so the log can be read. Kept directories live in
159
+ `~/.local/lemming/exec-*` and are retired automatically a week later, so a
160
+ recent failure is always still there to inspect. Stdout carries the agent's
161
+ message alone and everything else goes to stderr, so the output can be consumed
162
+ directly. Stderr reports the ephemeral tasks file and task ID at startup; pass
163
+ those to
145
164
  `lemming --tasks-file <path> status <id>` or `logs <id>` to inspect an active
146
165
  run. Use the global verbose flag (`lemming -v exec ...`) to stream runner
147
166
  activity.
@@ -149,25 +168,40 @@ activity.
149
168
  Note that the agent runs unattended (`--yolo` by default), so it does not
150
169
  inherit the permission prompts of whatever launched it.
151
170
 
171
+ `--retries N` includes the first attempt and defaults to 1. Retries reuse the
172
+ same task state and progress after incomplete runs, timeouts, launch errors, or
173
+ non-zero exits. An explicit failure or cancellation, an interruption, or a
174
+ failed review stops immediately. Review-only runs cannot be retried.
175
+
176
+ Concurrent writing runs must not share a checkout. Lemming stays independent of
177
+ Git, Mercurial, and other version control systems: the caller creates a separate
178
+ working copy with the repository's existing VCS, passes it with
179
+ `lemming -C <working-copy> -v exec ...`, and owns result recovery and cleanup.
180
+ For Git, stop when the source checkout has modified or untracked files instead
181
+ of silently excluding them. Retain every isolated working copy until its changes
182
+ have been recovered. The packaged skill includes a minimal Git example.
183
+
152
184
  ### Teaching Your Agent to Use It
153
185
 
154
186
  Lemming ships an Agent Skill so that an agent already running — Codex, Claude
155
187
  Code, Gemini CLI, Cursor — can reach any other agent CLI without knowing how
156
- each one spells its flags. Install it once:
188
+ each one spells its flags. Install or refresh it with:
157
189
 
158
190
  ```bash
159
- # Cross-tool location (~/.agents/skills), and report any tool-specific ones
191
+ # Cross-tool location plus every detected tool-specific location
160
192
  lemming skill install
161
193
 
162
- # Cover detected tools that require their own skill directory too
163
- lemming skill install --all
164
-
165
194
  # This repository only
166
195
  lemming skill install --to .agents/skills
196
+
197
+ # Inspect every supported location
198
+ lemming skill status
167
199
  ```
168
200
 
169
- `lemming skill uninstall` reverses it. Both refuse to touch a directory that
170
- does not hold this skill, so a mistyped `--to` fails instead of deleting work.
201
+ `lemming skill uninstall` reverses the default installation sweep. Both refuse
202
+ to touch a directory that does not hold this skill, so a mistyped `--to` fails
203
+ instead of deleting work. Use `--link` on a durable installation to track
204
+ package upgrades without reinstalling.
171
205
 
172
206
  ---
173
207
 
@@ -209,9 +243,9 @@ loops through each pending task:
209
243
  `lemming complete` or `lemming fail`. Agents can also schedule new tasks
210
244
  with `lemming add`, breaking down complex work into smaller steps that
211
245
  Lemming will pick up automatically.
212
- 4. **Retry or advance**: On failure, Lemming retries the task (up to
213
- `--retries`) with accumulated progress as context, so the agent learns from
214
- previous attempts. On success, it moves to the next task.
246
+ 4. **Retry or advance**: On failure, Lemming retries the task up to the
247
+ configured roadmap limit, with accumulated progress as context so the agent
248
+ learns from previous attempts. On success, it moves to the next task.
215
249
  5. **Orchestration**: After each task, Lemming can run one or more
216
250
  **Orchestrator Hooks** (like the built-in `roadmap` hook) to evaluate the
217
251
  results and adapt the roadmap if needed. Hooks are enabled by default but
@@ -258,13 +292,15 @@ Lemming comes with several built-in hooks to help manage your project:
258
292
  unnecessary complexity and duplicate implementations, then reviews changes for
259
293
  adherence to the Google Style Guide and general readability using the
260
294
  [readability](https://github.com/owahltinez/readability) tool (exposed as
261
- `lemming readability`). It can record findings as task progress or suggest
262
- follow-up refactoring tasks.
295
+ `lemming readability`). It intentionally applies automated and targeted fixes
296
+ in the working directory and records broader findings as task progress.
263
297
  - **`testing`**: Verifies that changed behavior has focused test coverage and
264
- that the relevant tests pass.
298
+ that the relevant tests pass. It may repair small, targeted problems in
299
+ production code or tests and may add, merge, or remove tests.
265
300
  - **`ux`**: Reviews at most one critical user journey affected by a user-visible
266
301
  change. It reports only concrete, reproducible continuity gaps and exits
267
- immediately for non-user-facing tasks.
302
+ immediately for non-user-facing tasks. Its prompt instructs the agent to stay
303
+ advisory, but this is not sandbox-enforced.
268
304
 
269
305
  ### Custom and Global Hooks
270
306
 
@@ -406,24 +442,27 @@ These come before the subcommand and apply to all of them.
406
442
  `add`, there is no length cap.
407
443
  - `--review <names>`: Reviews to run after the task, comma-separated or
408
444
  repeated; `all` selects every one. With no description, only the reviews
409
- run. Hooks that revise the roadmap cannot be selected.
445
+ run. Reviews may edit the working directory. Hooks that revise the roadmap
446
+ cannot be selected.
410
447
  - `--scope <path|range>`: What the reviews look at. Paths pass through; a git
411
448
  revision range is resolved to the files it changed. Defaults to uncommitted
412
449
  work, or the whole tree outside a repository.
413
450
  - `--runner`, `--model`: Which agent CLI and model to use.
451
+ - `--retries`: Maximum total task-runner attempts, including the first
452
+ (default 1). Does not retry review-only runs.
414
453
  - `--time-limit`: Minutes before the agent is killed (default 60, 0 for no
415
454
  limit).
416
455
  - `--yolo/--no-yolo`: Run the agent unattended (default: True).
417
456
  - `--keep`: Keep the run's state directory even when it succeeds.
418
457
  - **`skill install`**: Install the packaged Agent Skill so agents discover
419
- Lemming. Writes to `~/.agents/skills` by default and names any tool-specific
420
- directories it found.
458
+ Lemming. Writes to `~/.agents/skills` and every detected tool-specific
459
+ directory by default. Re-running it refreshes existing Lemming copies.
421
460
  - `--to <dir>`: Install into a specific skills directory.
422
- - `--all`: Also cover every detected tool's own skills directory.
423
461
  - `--link`: Symlink instead of copying, so upgrades take effect immediately.
424
- - `--force`: Replace an existing installation of this skill.
425
462
  - `--dry-run`: Print what would happen, refusals included.
426
- - **`skill uninstall`**: Remove it again. Same `--to`, `--all`, and `--dry-run`.
463
+ - **`skill uninstall`**: Remove it again. Supports `--to` and `--dry-run`.
464
+ - **`skill status`**: Show every supported location and installation state.
465
+ Supports `--json` for structured output.
427
466
  - **`stop`**: Stop the running loop and its runner.
428
467
  - `--after-current-task`: Drain instead — let the running task finish, then
429
468
  stop before claiming another. This is the safe way to change the runner or
@@ -90,10 +90,19 @@ runner, and the agent's closing message comes back on stdout.
90
90
  # Delegate one task to a different agent, e.g. to spare another's quota
91
91
  lemming exec "Fix the flaky test in runner_test.py" --runner codex
92
92
 
93
+ # Allow up to three total attempts for transient runner failures
94
+ lemming exec "Fix the flaky test in runner_test.py" --retries 3
95
+
93
96
  # Pipe a longer handoff instead of fighting shell quoting
94
- cat handoff.md | lemming exec -f - --runner agy
97
+ cat handoff.md | lemming -v exec -f - --runner agy
95
98
  ```
96
99
 
100
+ The runner receives no conversation history and cannot be steered mid-run.
101
+ Make the handoff self-contained: state the goal, hard constraints, relevant
102
+ findings and evidence, approaches ruled out and why, and the definition of done
103
+ and verification. The installed skill includes a complete here-document
104
+ example for orchestrating agents.
105
+
97
106
  With no description there is nothing for a task runner to do, so only the
98
107
  reviews run — against work that already exists.
99
108
 
@@ -102,7 +111,7 @@ reviews run — against work that already exists.
102
111
  lemming exec --review readability
103
112
 
104
113
  # Review someone else's branch, checked out in a worktree
105
- lemming exec -C ../review-worktree --review testing --scope main...HEAD
114
+ lemming -C ../review-worktree exec --review testing --scope main...HEAD
106
115
 
107
116
  # Do the work, then gate it
108
117
  lemming exec "Add pagination to the tasks API" --review all
@@ -112,14 +121,23 @@ lemming exec "Add pagination to the tasks API" --review all
112
121
  which is resolved to the files it changed. It defaults to uncommitted work, or
113
122
  to the whole tree outside a git repository.
114
123
 
124
+ Reviews may edit the working directory. The built-in readability review
125
+ intentionally applies fixes, and testing may repair production code or tests.
126
+ UX is instructed to remain advisory, but its prompt and `--no-yolo` do not
127
+ enforce filesystem isolation. A global review override may perform any actions
128
+ its prompt requests. When isolation is required, follow the working-copy
129
+ guidance below and pass a separate VCS-managed working copy with
130
+ `lemming -C <working-copy> exec --review ...`.
131
+
115
132
  Each run is self-contained: nothing is read from the project's roadmap or its
116
- local hooks, one agent run is attempted, and the run's state directory is
117
- removed unless it failed — in which case it is kept, and its path printed, so
118
- the log can be read. Kept directories live in `~/.local/lemming/exec-*` and are
119
- retired automatically a week later, so a recent failure is always still there to
120
- inspect. Stdout carries the agent's message alone and everything else goes to
121
- stderr, so the output can be consumed directly. Stderr reports the ephemeral
122
- tasks file and task ID at startup; pass those to
133
+ local hooks, it runs only the requested task and reviews, and its state
134
+ directory is removed unless it failed — in which case it is kept, and its path
135
+ printed, so the log can be read. Kept directories live in
136
+ `~/.local/lemming/exec-*` and are retired automatically a week later, so a
137
+ recent failure is always still there to inspect. Stdout carries the agent's
138
+ message alone and everything else goes to stderr, so the output can be consumed
139
+ directly. Stderr reports the ephemeral tasks file and task ID at startup; pass
140
+ those to
123
141
  `lemming --tasks-file <path> status <id>` or `logs <id>` to inspect an active
124
142
  run. Use the global verbose flag (`lemming -v exec ...`) to stream runner
125
143
  activity.
@@ -127,25 +145,40 @@ activity.
127
145
  Note that the agent runs unattended (`--yolo` by default), so it does not
128
146
  inherit the permission prompts of whatever launched it.
129
147
 
148
+ `--retries N` includes the first attempt and defaults to 1. Retries reuse the
149
+ same task state and progress after incomplete runs, timeouts, launch errors, or
150
+ non-zero exits. An explicit failure or cancellation, an interruption, or a
151
+ failed review stops immediately. Review-only runs cannot be retried.
152
+
153
+ Concurrent writing runs must not share a checkout. Lemming stays independent of
154
+ Git, Mercurial, and other version control systems: the caller creates a separate
155
+ working copy with the repository's existing VCS, passes it with
156
+ `lemming -C <working-copy> -v exec ...`, and owns result recovery and cleanup.
157
+ For Git, stop when the source checkout has modified or untracked files instead
158
+ of silently excluding them. Retain every isolated working copy until its changes
159
+ have been recovered. The packaged skill includes a minimal Git example.
160
+
130
161
  ### Teaching Your Agent to Use It
131
162
 
132
163
  Lemming ships an Agent Skill so that an agent already running — Codex, Claude
133
164
  Code, Gemini CLI, Cursor — can reach any other agent CLI without knowing how
134
- each one spells its flags. Install it once:
165
+ each one spells its flags. Install or refresh it with:
135
166
 
136
167
  ```bash
137
- # Cross-tool location (~/.agents/skills), and report any tool-specific ones
168
+ # Cross-tool location plus every detected tool-specific location
138
169
  lemming skill install
139
170
 
140
- # Cover detected tools that require their own skill directory too
141
- lemming skill install --all
142
-
143
171
  # This repository only
144
172
  lemming skill install --to .agents/skills
173
+
174
+ # Inspect every supported location
175
+ lemming skill status
145
176
  ```
146
177
 
147
- `lemming skill uninstall` reverses it. Both refuse to touch a directory that
148
- does not hold this skill, so a mistyped `--to` fails instead of deleting work.
178
+ `lemming skill uninstall` reverses the default installation sweep. Both refuse
179
+ to touch a directory that does not hold this skill, so a mistyped `--to` fails
180
+ instead of deleting work. Use `--link` on a durable installation to track
181
+ package upgrades without reinstalling.
149
182
 
150
183
  ---
151
184
 
@@ -187,9 +220,9 @@ loops through each pending task:
187
220
  `lemming complete` or `lemming fail`. Agents can also schedule new tasks
188
221
  with `lemming add`, breaking down complex work into smaller steps that
189
222
  Lemming will pick up automatically.
190
- 4. **Retry or advance**: On failure, Lemming retries the task (up to
191
- `--retries`) with accumulated progress as context, so the agent learns from
192
- previous attempts. On success, it moves to the next task.
223
+ 4. **Retry or advance**: On failure, Lemming retries the task up to the
224
+ configured roadmap limit, with accumulated progress as context so the agent
225
+ learns from previous attempts. On success, it moves to the next task.
193
226
  5. **Orchestration**: After each task, Lemming can run one or more
194
227
  **Orchestrator Hooks** (like the built-in `roadmap` hook) to evaluate the
195
228
  results and adapt the roadmap if needed. Hooks are enabled by default but
@@ -236,13 +269,15 @@ Lemming comes with several built-in hooks to help manage your project:
236
269
  unnecessary complexity and duplicate implementations, then reviews changes for
237
270
  adherence to the Google Style Guide and general readability using the
238
271
  [readability](https://github.com/owahltinez/readability) tool (exposed as
239
- `lemming readability`). It can record findings as task progress or suggest
240
- follow-up refactoring tasks.
272
+ `lemming readability`). It intentionally applies automated and targeted fixes
273
+ in the working directory and records broader findings as task progress.
241
274
  - **`testing`**: Verifies that changed behavior has focused test coverage and
242
- that the relevant tests pass.
275
+ that the relevant tests pass. It may repair small, targeted problems in
276
+ production code or tests and may add, merge, or remove tests.
243
277
  - **`ux`**: Reviews at most one critical user journey affected by a user-visible
244
278
  change. It reports only concrete, reproducible continuity gaps and exits
245
- immediately for non-user-facing tasks.
279
+ immediately for non-user-facing tasks. Its prompt instructs the agent to stay
280
+ advisory, but this is not sandbox-enforced.
246
281
 
247
282
  ### Custom and Global Hooks
248
283
 
@@ -384,24 +419,27 @@ These come before the subcommand and apply to all of them.
384
419
  `add`, there is no length cap.
385
420
  - `--review <names>`: Reviews to run after the task, comma-separated or
386
421
  repeated; `all` selects every one. With no description, only the reviews
387
- run. Hooks that revise the roadmap cannot be selected.
422
+ run. Reviews may edit the working directory. Hooks that revise the roadmap
423
+ cannot be selected.
388
424
  - `--scope <path|range>`: What the reviews look at. Paths pass through; a git
389
425
  revision range is resolved to the files it changed. Defaults to uncommitted
390
426
  work, or the whole tree outside a repository.
391
427
  - `--runner`, `--model`: Which agent CLI and model to use.
428
+ - `--retries`: Maximum total task-runner attempts, including the first
429
+ (default 1). Does not retry review-only runs.
392
430
  - `--time-limit`: Minutes before the agent is killed (default 60, 0 for no
393
431
  limit).
394
432
  - `--yolo/--no-yolo`: Run the agent unattended (default: True).
395
433
  - `--keep`: Keep the run's state directory even when it succeeds.
396
434
  - **`skill install`**: Install the packaged Agent Skill so agents discover
397
- Lemming. Writes to `~/.agents/skills` by default and names any tool-specific
398
- directories it found.
435
+ Lemming. Writes to `~/.agents/skills` and every detected tool-specific
436
+ directory by default. Re-running it refreshes existing Lemming copies.
399
437
  - `--to <dir>`: Install into a specific skills directory.
400
- - `--all`: Also cover every detected tool's own skills directory.
401
438
  - `--link`: Symlink instead of copying, so upgrades take effect immediately.
402
- - `--force`: Replace an existing installation of this skill.
403
439
  - `--dry-run`: Print what would happen, refusals included.
404
- - **`skill uninstall`**: Remove it again. Same `--to`, `--all`, and `--dry-run`.
440
+ - **`skill uninstall`**: Remove it again. Supports `--to` and `--dry-run`.
441
+ - **`skill status`**: Show every supported location and installation state.
442
+ Supports `--json` for structured output.
405
443
  - **`stop`**: Stop the running loop and its runner.
406
444
  - `--after-current-task`: Drain instead — let the running task finish, then
407
445
  stop before claiming another. This is the safe way to change the runner or
@@ -24,6 +24,9 @@ agent run can hold.
24
24
  ```sh
25
25
  lemming -v exec "Fix the flaky heartbeat test in src/runner_test.py" --runner codex
26
26
 
27
+ # Opt into at most three total attempts for transient runner failures
28
+ lemming -v exec "Fix the flaky heartbeat test" --retries 3
29
+
27
30
  # Pipe a longer handoff rather than fighting shell quoting; no length limit
28
31
  cat handoff.md | lemming -v exec -f - --runner agy
29
32
  ```
@@ -48,8 +51,70 @@ The task runner is required to record its approach first and concise findings as
48
51
  it works. These entries are checkpoints rather than a continuous trace, so use
49
52
  verbose output or the log to tell whether it is actively making progress.
50
53
 
51
- The task starts with an empty context and sees nothing of your conversation, so
52
- give it everything it needs.
54
+ The runner receives no conversation history and cannot be steered mid-run. Give
55
+ it a self-contained handoff with:
56
+
57
+ - **Goal:** the concrete outcome to produce.
58
+ - **Hard constraints:** scope, compatibility, process, and safety requirements.
59
+ - **Relevant findings and evidence:** paths, commands, output, and prior
60
+ observations it should rely on.
61
+ - **Approaches ruled out and why:** decisions it should not revisit without new
62
+ evidence.
63
+ - **Definition of done and verification:** the required result and checks that
64
+ prove it works.
65
+
66
+ For example:
67
+
68
+ ```sh
69
+ lemming -v exec -f - --runner codex <<'EOF'
70
+ # Goal
71
+ Fix the race that lets two workers claim the same queued job.
72
+
73
+ # Hard constraints
74
+ - Keep the SQLite schema and public CLI unchanged.
75
+ - Make the smallest scoped change; do not reformat unrelated files.
76
+
77
+ # Relevant findings and evidence
78
+ - `uv run pytest tests/test_queue.py -k concurrent_claim` fails intermittently.
79
+ - `src/queue.py:claim_next` reads and updates in separate transactions.
80
+
81
+ # Approaches ruled out and why
82
+ - Do not add an in-process mutex; separate worker processes would bypass it.
83
+
84
+ # Definition of done and verification
85
+ - The concurrency test passes repeatedly and no existing behavior regresses.
86
+ - Run the focused test, then the full test suite and configured linter.
87
+ EOF
88
+ ```
89
+
90
+ ## Isolate concurrent writing runs
91
+
92
+ Concurrent writing runs must use separate working copies. Detect and use the
93
+ repository's existing version control system, then pass each copy with the
94
+ global `-C` option. The caller owns creation, result recovery, and cleanup;
95
+ Lemming remains independent of Git, Mercurial, and other VCSs.
96
+
97
+ For Git, refuse modified or untracked input rather than silently excluding it,
98
+ then create a worktree from committed `HEAD`:
99
+
100
+ ```sh
101
+ repo=$(git rev-parse --show-toplevel) || exit 1
102
+ test -z "$(git -C "$repo" status --porcelain)" || exit 1
103
+ worktree=$(mktemp -d "${TMPDIR:-/tmp}/lemming-exec.XXXXXX") || exit 1
104
+ branch="lemming/$(basename "$worktree")"
105
+ git -C "$repo" worktree add -b "$branch" "$worktree" HEAD || exit 1
106
+ printf 'Worktree: %s\nBranch: %s\n' "$worktree" "$branch"
107
+ lemming -C "$worktree" -v exec "<self-contained task>" --runner codex
108
+ ```
109
+
110
+ Retain the reported worktree after success, failure, timeout, or interruption.
111
+ After its changes have been committed, copied, or deliberately discarded, use
112
+ Git's non-forcing cleanup so dirty or unmerged work is not destroyed:
113
+
114
+ ```sh
115
+ git -C "$repo" worktree remove "$worktree"
116
+ git -C "$repo" branch -d "$branch"
117
+ ```
53
118
 
54
119
  ## Run a review
55
120
 
@@ -71,8 +136,12 @@ lemming -C /tmp/pr-123 exec --review testing --scope main...HEAD
71
136
  which is resolved to the files it changed. It defaults to uncommitted work, and
72
137
  a clean tree stops the run rather than reviewing everything.
73
138
 
74
- Reviews **edit the workspace** — readability applies fixes and reruns checks.
75
- That is the point, but it means a review is not read-only.
139
+ Reviews may edit the working directory. Readability intentionally applies fixes,
140
+ and testing may repair production code or tests. UX is instructed to remain
141
+ advisory, but its prompt and `--no-yolo` do not enforce filesystem isolation. A
142
+ global review override may perform any actions its prompt requests. When
143
+ isolation is required, use a separate VCS-managed working copy and pass it with
144
+ the global `-C` option, as in the example above.
76
145
 
77
146
  ## Drive a roadmap
78
147
 
@@ -111,12 +180,14 @@ one off for the project.
111
180
  - **The agent runs unattended.** `--yolo` is the default, so it does not inherit
112
181
  the permission prompts of whatever launched it. Treat this as granting an
113
182
  agent unsupervised write access to the working directory.
114
- - **`exec` makes one attempt, no retry.** A failure is final. A roadmap task
115
- retries (3 by default) with its progress carried forward.
183
+ - **`exec` makes one attempt by default.** `--retries N` opts into at most `N`
184
+ total task attempts with progress carried forward. Explicit failure,
185
+ cancellation, interruption, and failed reviews stop immediately.
116
186
  - **Interrupting leaves partial edits.** Nothing is restored, so there is no
117
187
  atomicity to rely on.
118
188
  - **Concurrent runs in one checkout interleave their edits.** Give each writing
119
- run its own worktree and address it with `-C`.
189
+ run its own VCS-managed working copy and address it with `-C`; retain the copy
190
+ until its result is recovered.
120
191
  - **Every run reports its state.** The tasks file and task ID are printed on
121
192
  stderr at startup. Successful state is removed on exit unless `--keep` is
122
193
  used; failures keep their directory and print it again for recovery. Kept
@@ -54,20 +54,34 @@ a broad task).
54
54
  A code quality and simplification hook that challenges unnecessary complexity,
55
55
  indirection, and duplicated implementations before reviewing changes for
56
56
  adherence to the Google Style Guide and general readability using the bundled
57
- `lemming readability` tool. It provides feedback via task progress or suggests
58
- follow-up refactoring tasks.
57
+ `lemming readability` tool. It intentionally applies automated and targeted
58
+ fixes in the working directory and records broader findings as task progress.
59
59
 
60
60
  ### `testing`
61
61
 
62
62
  Checks that changed behavior has focused test coverage and runs the relevant
63
- tests. It records larger testing gaps as task progress for the roadmap hook.
63
+ tests. It may repair small, targeted problems in production code or tests and
64
+ may add, merge, or remove tests. It records larger testing gaps as task progress
65
+ for the roadmap hook.
64
66
 
65
67
  ### `ux`
66
68
 
67
69
  A lightweight journey-continuity review for user-visible changes. It considers
68
70
  at most one affected critical journey, reports only concrete and reproducible
69
71
  gaps, and exits immediately when the task did not change user-facing behavior.
70
- It runs after `testing` and before `roadmap`.
72
+ Its prompt instructs the agent to stay advisory, but this is not
73
+ sandbox-enforced. It runs after `testing` and before `roadmap`.
74
+
75
+ ### Reviews Are Not Read-Only
76
+
77
+ When selected with `lemming exec --review`, the hooks above may edit the working
78
+ directory. Prompt instructions and `--no-yolo` do not enforce filesystem
79
+ isolation. When isolation is required, create a separate VCS-managed working
80
+ copy and pass it through the global option:
81
+
82
+ ```bash
83
+ lemming -C <working-copy> exec --review <name>
84
+ ```
71
85
 
72
86
  ### Editing Built-in Hook Prompts
73
87
 
@@ -104,7 +118,8 @@ Because of this precedence order, overriding a built-in hook only requires
104
118
  creating a Markdown file with the same logical name in the project or global
105
119
  directory (e.g. `~/.local/lemming/hooks/90-roadmap.md`); delete the file to
106
120
  restore the built-in version. Global hooks are available to all Lemming projects
107
- on the system.
121
+ on the system. A global review override selected by `lemming exec --review` may
122
+ perform any actions its prompt requests.
108
123
 
109
124
  ### Example: `lint` hook
110
125
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "lemming-cli"
7
- version = "0.4.6"
7
+ version = "0.5.1"
8
8
  description = "An autonomous, iterative task runner for AI coding agents."
9
9
  readme = "README.md"
10
10
  authors = [
@@ -16,6 +16,7 @@ keywords = ["ai", "agents", "automation", "antigravity", "claude", "opencode"]
16
16
  dependencies = [
17
17
  "beautifulsoup4>=4.13.3",
18
18
  "click>=8.0.0",
19
+ "click-agentcli>=0.3.0",
19
20
  "fastapi>=0.124.4",
20
21
  "markdownify>=0.14.1",
21
22
  "pydantic>=2.12.5",
@@ -30,6 +30,9 @@ ALL_REVIEWS = "all"
30
30
  # large enough that reading it whole is wasteful.
31
31
  MAX_LOG_TAIL_BYTES = 256 * 1024
32
32
 
33
+ # Log header used to isolate the final runner or review output.
34
+ ATTEMPT_HEADER = "--- Attempt started at "
35
+
33
36
 
34
37
  def _read_log_tail(
35
38
  log_file: pathlib.Path, max_bytes: int = MAX_LOG_TAIL_BYTES
@@ -41,17 +44,20 @@ def _read_log_tail(
41
44
  max_bytes: Most bytes to read from the end of the file.
42
45
 
43
46
  Returns:
44
- The tail of the log, decoded leniently. A leading partial line is
47
+ The final attempt within the decoded tail. A leading partial line is
45
48
  harmless: the extractor skips anything that is not a whole event.
46
49
  """
47
50
  try:
48
51
  with open(log_file, "rb") as f:
49
52
  f.seek(0, 2)
50
53
  f.seek(max(0, f.tell() - max_bytes))
51
- return f.read().decode("utf-8", errors="replace")
54
+ text = f.read().decode("utf-8", errors="replace")
52
55
  except OSError:
53
56
  return ""
54
57
 
58
+ header = text.rfind(ATTEMPT_HEADER)
59
+ return text[header:] if header >= 0 else text
60
+
55
61
 
56
62
  def _resolve_prompt(description: str | None, file: typing.TextIO | None) -> str:
57
63
  """Returns the prompt text from an argument or a file.
@@ -217,7 +223,7 @@ def _task_status(
217
223
  help=(
218
224
  "Reviews to run after the task, comma-separated or repeated. "
219
225
  "Use 'all' for every review. With no description, only the "
220
- "reviews run."
226
+ "reviews run. Reviews may edit the working directory."
221
227
  ),
222
228
  )
223
229
  @click.option(
@@ -237,6 +243,13 @@ def _task_status(
237
243
  default=60,
238
244
  help="Minutes before the agent is killed (0 disables the limit).",
239
245
  )
246
+ @click.option(
247
+ "--retries",
248
+ default=1,
249
+ type=click.IntRange(min=1),
250
+ show_default=True,
251
+ help="Maximum total task-runner attempts, including the first.",
252
+ )
240
253
  @click.option(
241
254
  "--yolo/--no-yolo",
242
255
  default=True,
@@ -258,6 +271,7 @@ def exec_command(
258
271
  runner_name: str | None,
259
272
  model_name: str | None,
260
273
  time_limit: int,
274
+ retries: int,
261
275
  yolo: bool,
262
276
  keep: bool,
263
277
  runner_args: tuple,
@@ -285,6 +299,10 @@ def exec_command(
285
299
  if description or file or not reviews
286
300
  else None
287
301
  )
302
+ if prompt is None and retries > 1:
303
+ raise click.UsageError(
304
+ "--retries only applies when exec has a task description."
305
+ )
288
306
 
289
307
  # The runner must edit the caller's workspace, never the throwaway
290
308
  # directory that only holds this run's bookkeeping.
@@ -304,9 +322,8 @@ def exec_command(
304
322
  return
305
323
  scope_text = scope.describe(entries)
306
324
 
307
- # A one-shot spends one agent run: a silent retry would multiply the
308
- # caller's cost without their say.
309
- config = tasks.RoadmapConfig(retries=1, time_limit=time_limit)
325
+ # Extra attempts require opt-in because each can incur runner cost.
326
+ config = tasks.RoadmapConfig(retries=retries, time_limit=time_limit)
310
327
  if runner_name:
311
328
  config.runner = runner_name
312
329
  if model_name: