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.
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/PKG-INFO +69 -30
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/README.md +67 -29
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/SKILL.md +78 -7
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/docs/HOOKS.md +20 -5
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/pyproject.toml +2 -1
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/exec_cli.py +23 -6
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/exec_cli_test.py +248 -1
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/main_test.py +1 -1
- lemming_cli-0.5.1/src/lemming/cli/skill.py +7 -0
- lemming_cli-0.5.1/src/lemming/cli/skill_test.py +47 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/orchestrator.py +101 -46
- lemming_cli-0.5.1/src/lemming/prompts/hooks/60-testing.md +65 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/prompts/hooks/90-roadmap.md +4 -3
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/uv.lock +19 -1
- lemming_cli-0.4.6/src/lemming/cli/skill.py +0 -344
- lemming_cli-0.4.6/src/lemming/cli/skill_test.py +0 -151
- lemming_cli-0.4.6/src/lemming/prompts/hooks/60-testing.md +0 -48
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/.dockerignore +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/.github/workflows/ci.yml +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/.github/workflows/publish.yml +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/.github/workflows/screenshots.yml +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/.gitignore +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/.prettierignore +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/.prettierrc +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/Dockerfile +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/LICENSE +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/biome.json +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/docker-compose.yml +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/docs/EVALS.md +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/docs/screenshots/dashboard-desktop.png +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/docs/screenshots/dashboard-mobile.png +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/docs/screenshots/task-log-desktop.png +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/docs/screenshots/task-log-mobile.png +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/package-lock.json +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/package.json +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/playwright.config.js +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/pyrefly.toml +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/__init__.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/__init__.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/auth.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/auth_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/config.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/config_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/conftest.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/context.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/context_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/directories.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/directories_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/files.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/files_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/hooks.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/hooks_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/logging.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/logging_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/loop.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/loop_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/main.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/main_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/tasks.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api/tasks_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/api_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/brief_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/__init__.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/brief.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/config.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/config_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/goal.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/goal_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/hooks.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/hooks_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/machine_output_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/main.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/operations.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/operations_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/progress.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/progress_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/readability_cli.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/readability_cli_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/stop_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/tasks.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli/tasks_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/cli_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/conftest.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/__init__.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/__main__.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/cli.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/cli_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/container.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/container_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/fixtures.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/fixtures_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/harness.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/harness_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/metrics.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/metrics_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/base/README.md +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/base/calc/__init__.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/base/calc/legacy.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/base/calc/ops.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/base/calc/ops_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/clean/calc/ops.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/clean/calc/ops_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/dead-code/calc/ops.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/dead-code/calc/ops_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/duplicated-behavior/calc/ops.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/duplicated-behavior/calc/ops_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/false-reuse/calc/limits.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/false-reuse/calc/limits_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/lint-debt/calc/ops.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/readability/lint-debt/calc/ops_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/add-only/README.md +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/add-only/calc/__init__.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/add-only/calc/ops.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/add-only/calc/ops_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/buggy-subtract/README.md +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/buggy-subtract/calc/__init__.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/buggy-subtract/calc/ops.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/buggy-subtract/calc/ops_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/full-ops/README.md +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/full-ops/calc/__init__.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/full-ops/calc/ops.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/full-ops/calc/ops_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/unwired-cli/README.md +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/unwired-cli/calc/__init__.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/unwired-cli/calc/cli.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/unwired-cli/calc/cli_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/unwired-cli/calc/ops.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/roadmap/unwired-cli/calc/ops_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/task/hidden/stats/summary_hidden_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/task/summary/README.md +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/task/summary/stats/__init__.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/task/summary/stats/summary.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/projects/task/summary/stats/summary_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/readability.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/readability_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/report.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/report_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/roadmap.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/roadmap_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/scenarios.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/scenarios_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/suites.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/task.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/task_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/trial.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/evals/trial_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/hooks.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/hooks_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/integration_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/main.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/main_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/models.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/models_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/orchestrator_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/paths.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/paths_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/persistence.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/persistence_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/prompts/hooks/50-readability.md +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/prompts/hooks/70-ux.md +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/prompts/taskrunner.md +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/prompts.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/prompts_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/providers.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/providers_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/runner.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/runner_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/scope.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/scope_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/shutdown.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/shutdown_integration_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/shutdown_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/__init__.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/lifecycle.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/lifecycle_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/limits.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/operations.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/operations_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/progress.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/progress_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/queries.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/tasks/queries_test.py +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/dashboard.spec.js +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/dashboard.test.js +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/favicon.js +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/favicon.spec.js +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/files.html +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/files.spec.js +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/index.html +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/index.js +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/logs.html +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/logs.test.js +0 -0
- {lemming_cli-0.4.6 → lemming_cli-0.5.1}/src/lemming/web/mancha.js +0 -0
- {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.
|
|
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
|
|
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,
|
|
139
|
-
removed unless it failed — in which case it is kept, and its path
|
|
140
|
-
the log can be read. Kept directories live in
|
|
141
|
-
retired automatically a week later, so a
|
|
142
|
-
inspect. Stdout carries the agent's
|
|
143
|
-
stderr, so the output can be consumed
|
|
144
|
-
tasks file and task ID at startup; pass
|
|
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
|
|
188
|
+
each one spells its flags. Install or refresh it with:
|
|
157
189
|
|
|
158
190
|
```bash
|
|
159
|
-
# Cross-tool location
|
|
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
|
|
170
|
-
does not hold this skill, so a mistyped `--to` fails
|
|
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
|
|
213
|
-
|
|
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
|
|
262
|
-
|
|
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
|
|
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`
|
|
420
|
-
|
|
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.
|
|
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
|
|
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,
|
|
117
|
-
removed unless it failed — in which case it is kept, and its path
|
|
118
|
-
the log can be read. Kept directories live in
|
|
119
|
-
retired automatically a week later, so a
|
|
120
|
-
inspect. Stdout carries the agent's
|
|
121
|
-
stderr, so the output can be consumed
|
|
122
|
-
tasks file and task ID at startup; pass
|
|
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
|
|
165
|
+
each one spells its flags. Install or refresh it with:
|
|
135
166
|
|
|
136
167
|
```bash
|
|
137
|
-
# Cross-tool location
|
|
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
|
|
148
|
-
does not hold this skill, so a mistyped `--to` fails
|
|
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
|
|
191
|
-
|
|
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
|
|
240
|
-
|
|
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
|
|
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`
|
|
398
|
-
|
|
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.
|
|
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
|
|
52
|
-
|
|
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
|
|
75
|
-
|
|
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
|
|
115
|
-
|
|
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
|
|
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
|
|
58
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
-
#
|
|
308
|
-
|
|
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:
|