lemming-cli 0.3.3__tar.gz → 0.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/.gitignore +1 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/PKG-INFO +198 -12
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/README.md +195 -9
- lemming_cli-0.4.0/SKILL.md +86 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/docs/HOOKS.md +9 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/pyproject.toml +7 -2
- lemming_cli-0.4.0/src/lemming/api/auth.py +57 -0
- lemming_cli-0.4.0/src/lemming/api/auth_test.py +73 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/main.py +20 -1
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/tasks_test.py +25 -0
- lemming_cli-0.4.0/src/lemming/brief_test.py +106 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/cli/__init__.py +3 -0
- lemming_cli-0.4.0/src/lemming/cli/brief.py +70 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/cli/config.py +11 -1
- lemming_cli-0.4.0/src/lemming/cli/config_test.py +114 -0
- lemming_cli-0.4.0/src/lemming/cli/exec_cli.py +372 -0
- lemming_cli-0.4.0/src/lemming/cli/exec_cli_test.py +418 -0
- lemming_cli-0.4.0/src/lemming/cli/machine_output_test.py +103 -0
- lemming_cli-0.4.0/src/lemming/cli/main.py +105 -0
- lemming_cli-0.4.0/src/lemming/cli/main_test.py +149 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/cli/operations.py +109 -2
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/cli/progress.py +2 -2
- lemming_cli-0.4.0/src/lemming/cli/skill.py +344 -0
- lemming_cli-0.4.0/src/lemming/cli/skill_test.py +151 -0
- lemming_cli-0.4.0/src/lemming/cli/stop_test.py +112 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/cli/tasks.py +109 -18
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/cli/tasks_test.py +70 -1
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/models.py +5 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/orchestrator.py +117 -6
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/orchestrator_test.py +234 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/paths.py +89 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/paths_test.py +70 -0
- lemming_cli-0.4.0/src/lemming/persistence.py +360 -0
- lemming_cli-0.4.0/src/lemming/persistence_test.py +378 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/prompts/hooks/50-readability.md +26 -15
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/prompts/hooks/60-testing.md +6 -2
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/prompts/hooks/70-ux.md +5 -1
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/prompts/taskrunner.md +1 -1
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/prompts.py +27 -1
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/prompts_test.py +81 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/providers.py +20 -18
- lemming_cli-0.4.0/src/lemming/providers_test.py +150 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/runner.py +291 -35
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/runner_test.py +388 -1
- lemming_cli-0.4.0/src/lemming/scope.py +169 -0
- lemming_cli-0.4.0/src/lemming/scope_test.py +117 -0
- lemming_cli-0.4.0/src/lemming/shutdown.py +58 -0
- lemming_cli-0.4.0/src/lemming/shutdown_integration_test.py +187 -0
- lemming_cli-0.4.0/src/lemming/shutdown_test.py +53 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/tasks/__init__.py +4 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/tasks/lifecycle.py +26 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/tasks/lifecycle_test.py +28 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/tasks/limits.py +6 -5
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/tasks/operations.py +7 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/tasks/operations_test.py +17 -1
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/web/dashboard.spec.js +30 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/web/index.js +11 -1
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/uv.lock +5 -5
- lemming_cli-0.3.3/src/lemming/api/auth.py +0 -34
- lemming_cli-0.3.3/src/lemming/api/auth_test.py +0 -40
- lemming_cli-0.3.3/src/lemming/cli/config_test.py +0 -53
- lemming_cli-0.3.3/src/lemming/cli/main.py +0 -42
- lemming_cli-0.3.3/src/lemming/cli/main_test.py +0 -29
- lemming_cli-0.3.3/src/lemming/persistence.py +0 -205
- lemming_cli-0.3.3/src/lemming/persistence_test.py +0 -164
- lemming_cli-0.3.3/src/lemming/providers_test.py +0 -73
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/.github/workflows/ci.yml +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/.github/workflows/publish.yml +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/.github/workflows/screenshots.yml +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/.prettierignore +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/.prettierrc +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/Dockerfile +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/LICENSE +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/biome.json +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/docker-compose.yml +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/docs/EVALS.md +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/docs/screenshots/dashboard-desktop.png +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/docs/screenshots/dashboard-mobile.png +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/docs/screenshots/task-log-desktop.png +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/docs/screenshots/task-log-mobile.png +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/package-lock.json +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/package.json +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/playwright.config.js +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/__init__.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/__init__.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/config.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/config_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/conftest.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/context.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/context_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/directories.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/directories_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/files.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/files_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/hooks.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/hooks_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/logging.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/logging_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/loop.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/loop_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/main_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api/tasks.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/api_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/cli/goal.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/cli/goal_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/cli/hooks.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/cli/hooks_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/cli/operations_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/cli/progress_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/cli/readability_cli.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/cli/readability_cli_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/cli_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/conftest.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/__init__.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/__main__.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/cli.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/cli_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/container.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/container_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/fixtures.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/fixtures_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/harness.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/harness_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/readability.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/readability_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/roadmap.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/roadmap_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/scenarios.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/scenarios_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/suites.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/trial.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/evals/trial_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/hooks.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/hooks_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/integration_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/main.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/main_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/models_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/prompts/hooks/90-roadmap.md +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/tasks/progress.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/tasks/progress_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/tasks/queries.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/tasks/queries_test.py +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/web/dashboard.test.js +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/web/favicon.js +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/web/favicon.spec.js +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/web/files.html +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/web/files.spec.js +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/web/index.html +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/web/logs.html +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/web/logs.test.js +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/web/mancha.js +0 -0
- {lemming_cli-0.3.3 → lemming_cli-0.4.0}/src/lemming/web/screenshots.spec.js +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: lemming-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
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
|
|
@@ -15,7 +15,7 @@ Requires-Dist: fastapi>=0.124.4
|
|
|
15
15
|
Requires-Dist: markdownify>=0.14.1
|
|
16
16
|
Requires-Dist: pydantic>=2.12.5
|
|
17
17
|
Requires-Dist: pyyaml>=6.0.3
|
|
18
|
-
Requires-Dist: readability-cli>=0.
|
|
18
|
+
Requires-Dist: readability-cli>=0.7.0
|
|
19
19
|
Requires-Dist: requests>=2.32.3
|
|
20
20
|
Requires-Dist: uvicorn>=0.33.0
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
@@ -102,6 +102,71 @@ lemming run -- --model claude-3-5-sonnet
|
|
|
102
102
|
|
|
103
103
|
---
|
|
104
104
|
|
|
105
|
+
## One-Off Tasks Without a Roadmap
|
|
106
|
+
|
|
107
|
+
`lemming exec` runs a single task and exits. It is the same agent-CLI
|
|
108
|
+
normalization the orchestrator uses, addressable on its own: name a task and a
|
|
109
|
+
runner, and the agent's closing message comes back on stdout.
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
# Delegate one task to a different agent, e.g. to spare another's quota
|
|
113
|
+
lemming exec "Fix the flaky test in runner_test.py" --runner codex
|
|
114
|
+
|
|
115
|
+
# Pipe a longer handoff instead of fighting shell quoting
|
|
116
|
+
cat handoff.md | lemming exec -f - --runner agy
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
With no description there is nothing for a task runner to do, so only the
|
|
120
|
+
reviews run — against work that already exists.
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Review uncommitted work before opening a pull request
|
|
124
|
+
lemming exec --review readability
|
|
125
|
+
|
|
126
|
+
# Review someone else's branch, checked out in a worktree
|
|
127
|
+
lemming exec -C ../review-worktree --review testing --scope main...HEAD
|
|
128
|
+
|
|
129
|
+
# Do the work, then gate it
|
|
130
|
+
lemming exec "Add pagination to the tasks API" --review all
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
`--scope` takes paths, which pass through untouched, or a git revision range,
|
|
134
|
+
which is resolved to the files it changed. It defaults to uncommitted work, or
|
|
135
|
+
to the whole tree outside a git repository.
|
|
136
|
+
|
|
137
|
+
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
|
|
141
|
+
are retired automatically a week later, so a recent failure is always still
|
|
142
|
+
there to inspect. Stdout carries the agent's message alone and everything
|
|
143
|
+
else goes to stderr, so the output can be consumed directly.
|
|
144
|
+
|
|
145
|
+
Note that the agent runs unattended (`--yolo` by default), so it does not
|
|
146
|
+
inherit the permission prompts of whatever launched it.
|
|
147
|
+
|
|
148
|
+
### Teaching Your Agent to Use It
|
|
149
|
+
|
|
150
|
+
Lemming ships an Agent Skill so that an agent already running — Claude Code,
|
|
151
|
+
Gemini CLI, Cursor — can reach any other agent CLI without knowing how each
|
|
152
|
+
one spells its flags. Install it once:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
# Cross-tool location (~/.agents/skills), and report any tool-specific ones
|
|
156
|
+
lemming skill install
|
|
157
|
+
|
|
158
|
+
# Cover every agent tool detected on this machine
|
|
159
|
+
lemming skill install --all
|
|
160
|
+
|
|
161
|
+
# This repository only
|
|
162
|
+
lemming skill install --to .agents/skills
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
`lemming skill uninstall` reverses it. Both refuse to touch a directory that
|
|
166
|
+
does not hold this skill, so a mistyped `--to` fails instead of deleting work.
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
105
170
|
## The Web Dashboard
|
|
106
171
|
|
|
107
172
|
Lemming includes a modern, fast Web UI to monitor your projects.
|
|
@@ -244,16 +309,36 @@ See [docs/EVALS.md](docs/EVALS.md) for details.
|
|
|
244
309
|
|
|
245
310
|
## Command Reference
|
|
246
311
|
|
|
312
|
+
### Global Options
|
|
313
|
+
|
|
314
|
+
These come before the subcommand and apply to all of them.
|
|
315
|
+
|
|
316
|
+
- **`-C, --project-dir <dir>`**: Run as if invoked from `<dir>`, addressing
|
|
317
|
+
that project's roadmap. Relative paths in other options resolve against it.
|
|
318
|
+
See [Working across projects](#working-across-projects).
|
|
319
|
+
- **`--tasks-file <path>`**: Point at a specific tasks file instead of the one
|
|
320
|
+
derived from the current directory.
|
|
321
|
+
- **`-v, --verbose`**: Show verbose output.
|
|
322
|
+
|
|
247
323
|
### Roadmap Management
|
|
248
324
|
|
|
249
325
|
- **`status [<id>]`**: Queue/history overview or deep-dive into a specific
|
|
250
|
-
task, including supersession lineage
|
|
251
|
-
times. Superseded and failed history
|
|
252
|
-
`--verbose` also shows routine
|
|
326
|
+
task, including supersession lineage, the last resolved runner command, and
|
|
327
|
+
runner/orchestrator-hook execution times. Superseded and failed history
|
|
328
|
+
stays visible in the default overview; `--verbose` also shows routine
|
|
329
|
+
completed/cancelled history.
|
|
330
|
+
- `--json`: Emit machine-readable JSON instead of formatted text, so
|
|
331
|
+
scripts never have to parse the internal state file.
|
|
332
|
+
- `--brief`: Omit task descriptions, which otherwise dominate the output.
|
|
253
333
|
- **`goal [<text>]`**: Set or view the long-term goal shared by all tasks.
|
|
254
334
|
Supports `-f/--file`.
|
|
255
|
-
- **`add <desc>`**: Append a new task. Supports `--index
|
|
256
|
-
|
|
335
|
+
- **`add <desc>`**: Append a new task. Supports `--index`, `--runner`, and
|
|
336
|
+
`--model`.
|
|
337
|
+
- **`edit <id>`**: Modify a task's description, runner, model, or position.
|
|
338
|
+
- **`brief <id> [text]`**: View or set a task's long-form brief. Unlike the
|
|
339
|
+
description it has no length cap, and it is appended to the runner prompt
|
|
340
|
+
automatically — the right home for measured timings, exact failing
|
|
341
|
+
selectors, or why a previous attempt was wrong. Supports `-f/--file`.
|
|
257
342
|
- **`delete <id>`**: Remove an unstarted task while retaining its runner log.
|
|
258
343
|
Tasks with execution history require `--force`; autonomous restructuring
|
|
259
344
|
should use `supersede`. Supports `--all` and `--completed` for bulk cleanup,
|
|
@@ -265,9 +350,11 @@ See [docs/EVALS.md](docs/EVALS.md) for details.
|
|
|
265
350
|
- `add <id> <finding>`: Record a new technical detail.
|
|
266
351
|
- `edit <id> <index> <text>`: Modify an existing progress entry.
|
|
267
352
|
- `delete <id> <index>`: Remove a progress entry.
|
|
268
|
-
- **`config`**: Manage project configuration (runner, retries
|
|
353
|
+
- **`config`**: Manage project configuration (runner, model, retries,
|
|
354
|
+
time limit).
|
|
269
355
|
- `list`: View current configuration.
|
|
270
|
-
- `set <key> <value>`: Update a setting.
|
|
356
|
+
- `set <key> <value>`: Update a setting. `set model default` clears a
|
|
357
|
+
pinned model without touching the runner.
|
|
271
358
|
- **`hooks`**: Manage orchestrator hooks.
|
|
272
359
|
- `list`: View available and active hooks.
|
|
273
360
|
- `install`: Install built-in hooks to the global directory.
|
|
@@ -295,6 +382,7 @@ See [docs/EVALS.md](docs/EVALS.md) for details.
|
|
|
295
382
|
- **`logs [<id>]`**: Print a task's execution log to stdout, including retained
|
|
296
383
|
logs for removed tasks. If no ID is provided, it defaults to the active or
|
|
297
384
|
most recent task. Orchestrator hook output is automatically appended.
|
|
385
|
+
Supports `--json` to wrap the log with its task ID and path.
|
|
298
386
|
|
|
299
387
|
### Execution
|
|
300
388
|
|
|
@@ -303,7 +391,39 @@ See [docs/EVALS.md](docs/EVALS.md) for details.
|
|
|
303
391
|
- `--yolo`: Run the runner in auto-approve mode (default: True).
|
|
304
392
|
- `--env`: Set environment variables for the runner (e.g., `--env KEY=VALUE`).
|
|
305
393
|
- `--no-defaults`: Skip default flag injection for known runners.
|
|
306
|
-
- `--`: Use `--` to pass any flag directly to the underlying runner.
|
|
394
|
+
- `--`: Use `--` to pass any flag directly to the underlying runner. A
|
|
395
|
+
per-task `--runner`/`--model` overrides anything passed here.
|
|
396
|
+
- **`exec [<description>]`**: Run one task, or one set of reviews, outside any
|
|
397
|
+
roadmap. Prints the agent's closing message to stdout and everything else to
|
|
398
|
+
stderr. Exits non-zero if the task did not complete. See
|
|
399
|
+
[One-off tasks](#one-off-tasks-without-a-roadmap).
|
|
400
|
+
- `-f/--file`: Read the description from a file, or `-` for stdin. Unlike
|
|
401
|
+
`add`, there is no length cap.
|
|
402
|
+
- `--review <names>`: Reviews to run after the task, comma-separated or
|
|
403
|
+
repeated; `all` selects every one. With no description, only the reviews
|
|
404
|
+
run. Hooks that revise the roadmap cannot be selected.
|
|
405
|
+
- `--scope <path|range>`: What the reviews look at. Paths pass through; a
|
|
406
|
+
git revision range is resolved to the files it changed. Defaults to
|
|
407
|
+
uncommitted work, or the whole tree outside a repository.
|
|
408
|
+
- `--runner`, `--model`: Which agent CLI and model to use.
|
|
409
|
+
- `--time-limit`: Minutes before the agent is killed (default 60, 0 for no
|
|
410
|
+
limit).
|
|
411
|
+
- `--yolo/--no-yolo`: Run the agent unattended (default: True).
|
|
412
|
+
- `--keep`: Keep the run's state directory even when it succeeds.
|
|
413
|
+
- **`skill install`**: Install the packaged Agent Skill so agents discover
|
|
414
|
+
Lemming. Writes to `~/.agents/skills` by default and names any tool-specific
|
|
415
|
+
directories it found.
|
|
416
|
+
- `--to <dir>`: Install into a specific skills directory.
|
|
417
|
+
- `--all`: Also cover every detected tool's own skills directory.
|
|
418
|
+
- `--link`: Symlink instead of copying, so upgrades take effect immediately.
|
|
419
|
+
- `--force`: Replace an existing installation of this skill.
|
|
420
|
+
- `--dry-run`: Print what would happen, refusals included.
|
|
421
|
+
- **`skill uninstall`**: Remove it again. Same `--to`, `--all`, and
|
|
422
|
+
`--dry-run`.
|
|
423
|
+
- **`stop`**: Stop the running loop and its runner.
|
|
424
|
+
- `--after-current-task`: Drain instead — let the running task finish, then
|
|
425
|
+
stop before claiming another. This is the safe way to change the runner
|
|
426
|
+
or model without stranding work in flight.
|
|
307
427
|
- **`serve`**: Launch the interactive Web UI.
|
|
308
428
|
- `--port`: The port to bind the server to (default: 8999).
|
|
309
429
|
- `--host`: The host address to bind the server to (default: 127.0.0.1).
|
|
@@ -314,6 +434,36 @@ See [docs/EVALS.md](docs/EVALS.md) for details.
|
|
|
314
434
|
|
|
315
435
|
---
|
|
316
436
|
|
|
437
|
+
## Working across projects
|
|
438
|
+
|
|
439
|
+
When work on one project turns up something that belongs to another — a bug in
|
|
440
|
+
a dependency you also maintain, a doc fix in a sibling repo — file it directly
|
|
441
|
+
on that project's roadmap with `-C` instead of routing it through an external
|
|
442
|
+
issue tracker:
|
|
443
|
+
|
|
444
|
+
```bash
|
|
445
|
+
# From inside project A, queue work on project B
|
|
446
|
+
lemming -C ~/src/other-project add "check --fix drops the trailing newline"
|
|
447
|
+
|
|
448
|
+
# Attach the evidence; the brief has no length cap
|
|
449
|
+
lemming -C ~/src/other-project brief <id> --file repro.md
|
|
450
|
+
|
|
451
|
+
# Read the other project's roadmap without leaving yours
|
|
452
|
+
lemming -C ~/src/other-project status
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
`-C` works whether or not the target keeps a `tasks.yml` in its repo, so you
|
|
456
|
+
never have to know where its isolated state lives. Because it changes the
|
|
457
|
+
working directory, everything else follows too: the target's `.env`, its
|
|
458
|
+
`.lemming/hooks`, and the directory the runner executes in.
|
|
459
|
+
|
|
460
|
+
When an agent files a task this way from inside a `lemming run`, the new task
|
|
461
|
+
records the task it came from via `parent` and `parent_tasks_file`. The
|
|
462
|
+
downstream runner then sees a **Parent Task Context** section in its prompt
|
|
463
|
+
describing why the work was requested, so the report doesn't lose its origin.
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
317
467
|
## Advanced: Runner Customization
|
|
318
468
|
|
|
319
469
|
Lemming uses **fuzzy matching** to automatically inject the correct "YOLO"
|
|
@@ -326,17 +476,53 @@ Lemming uses **fuzzy matching** to automatically inject the correct "YOLO"
|
|
|
326
476
|
- **Codex**: Runs non-interactively via `codex exec`, adds `--json`, and, in
|
|
327
477
|
YOLO mode, adds `--dangerously-bypass-approvals-and-sandbox`
|
|
328
478
|
|
|
479
|
+
### Choosing a model
|
|
480
|
+
|
|
481
|
+
The model is a first-class setting, separate from the runner, so switching
|
|
482
|
+
provider does not silently discard it:
|
|
483
|
+
|
|
484
|
+
```bash
|
|
485
|
+
lemming config set model gemini-3.6-flash-high # project default
|
|
486
|
+
lemming add "Fix the flaky test" --model fast # just this task
|
|
487
|
+
lemming config set model default # let the runner decide
|
|
488
|
+
```
|
|
489
|
+
|
|
490
|
+
Precedence, highest first: an explicit `--model` inside a runner string, the
|
|
491
|
+
task's `--model`, the project's `config model`, then anything passed after
|
|
492
|
+
`lemming run --`. A per-task setting always wins over the loop-wide
|
|
493
|
+
passthrough — the conflicting global flag is dropped rather than duplicated
|
|
494
|
+
on the command line.
|
|
495
|
+
|
|
496
|
+
### Runner strings
|
|
497
|
+
|
|
498
|
+
A runner is not limited to a binary name: any extra arguments in the string
|
|
499
|
+
are appended to the command, which is another way to pin per-task behaviour.
|
|
500
|
+
|
|
501
|
+
```bash
|
|
502
|
+
lemming add "Try the fast model" --runner "agy --model fast"
|
|
503
|
+
```
|
|
504
|
+
|
|
329
505
|
You can disable default flag injection with `--no-defaults` (`codex exec`
|
|
330
506
|
remains the Codex execution interface), or use a **template** to fully control
|
|
331
507
|
the command layout:
|
|
332
508
|
|
|
333
509
|
```bash
|
|
334
|
-
lemming
|
|
510
|
+
lemming config set runner "my-tool --input={{prompt}} --json"
|
|
335
511
|
```
|
|
336
512
|
|
|
337
513
|
When `{{prompt}}` is present in the runner string, Lemming replaces it with the
|
|
338
514
|
prompt text and skips all default flag injection.
|
|
339
515
|
|
|
516
|
+
### Knowing what actually ran
|
|
517
|
+
|
|
518
|
+
Each attempt records the command it launched, with the prompt elided, so the
|
|
519
|
+
runner and model behind a finished task stay recoverable:
|
|
520
|
+
|
|
521
|
+
```bash
|
|
522
|
+
lemming status <id> # includes "Last Command:"
|
|
523
|
+
lemming status --json # same data, machine-readable
|
|
524
|
+
```
|
|
525
|
+
|
|
340
526
|
---
|
|
341
527
|
|
|
342
528
|
## Releasing
|
|
@@ -80,6 +80,71 @@ lemming run -- --model claude-3-5-sonnet
|
|
|
80
80
|
|
|
81
81
|
---
|
|
82
82
|
|
|
83
|
+
## One-Off Tasks Without a Roadmap
|
|
84
|
+
|
|
85
|
+
`lemming exec` runs a single task and exits. It is the same agent-CLI
|
|
86
|
+
normalization the orchestrator uses, addressable on its own: name a task and a
|
|
87
|
+
runner, and the agent's closing message comes back on stdout.
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Delegate one task to a different agent, e.g. to spare another's quota
|
|
91
|
+
lemming exec "Fix the flaky test in runner_test.py" --runner codex
|
|
92
|
+
|
|
93
|
+
# Pipe a longer handoff instead of fighting shell quoting
|
|
94
|
+
cat handoff.md | lemming exec -f - --runner agy
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
With no description there is nothing for a task runner to do, so only the
|
|
98
|
+
reviews run — against work that already exists.
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# Review uncommitted work before opening a pull request
|
|
102
|
+
lemming exec --review readability
|
|
103
|
+
|
|
104
|
+
# Review someone else's branch, checked out in a worktree
|
|
105
|
+
lemming exec -C ../review-worktree --review testing --scope main...HEAD
|
|
106
|
+
|
|
107
|
+
# Do the work, then gate it
|
|
108
|
+
lemming exec "Add pagination to the tasks API" --review all
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
`--scope` takes paths, which pass through untouched, or a git revision range,
|
|
112
|
+
which is resolved to the files it changed. It defaults to uncommitted work, or
|
|
113
|
+
to the whole tree outside a git repository.
|
|
114
|
+
|
|
115
|
+
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
|
|
119
|
+
are retired automatically a week later, so a recent failure is always still
|
|
120
|
+
there to inspect. Stdout carries the agent's message alone and everything
|
|
121
|
+
else goes to stderr, so the output can be consumed directly.
|
|
122
|
+
|
|
123
|
+
Note that the agent runs unattended (`--yolo` by default), so it does not
|
|
124
|
+
inherit the permission prompts of whatever launched it.
|
|
125
|
+
|
|
126
|
+
### Teaching Your Agent to Use It
|
|
127
|
+
|
|
128
|
+
Lemming ships an Agent Skill so that an agent already running — Claude Code,
|
|
129
|
+
Gemini CLI, Cursor — can reach any other agent CLI without knowing how each
|
|
130
|
+
one spells its flags. Install it once:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# Cross-tool location (~/.agents/skills), and report any tool-specific ones
|
|
134
|
+
lemming skill install
|
|
135
|
+
|
|
136
|
+
# Cover every agent tool detected on this machine
|
|
137
|
+
lemming skill install --all
|
|
138
|
+
|
|
139
|
+
# This repository only
|
|
140
|
+
lemming skill install --to .agents/skills
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
`lemming skill uninstall` reverses it. Both refuse to touch a directory that
|
|
144
|
+
does not hold this skill, so a mistyped `--to` fails instead of deleting work.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
83
148
|
## The Web Dashboard
|
|
84
149
|
|
|
85
150
|
Lemming includes a modern, fast Web UI to monitor your projects.
|
|
@@ -222,16 +287,36 @@ See [docs/EVALS.md](docs/EVALS.md) for details.
|
|
|
222
287
|
|
|
223
288
|
## Command Reference
|
|
224
289
|
|
|
290
|
+
### Global Options
|
|
291
|
+
|
|
292
|
+
These come before the subcommand and apply to all of them.
|
|
293
|
+
|
|
294
|
+
- **`-C, --project-dir <dir>`**: Run as if invoked from `<dir>`, addressing
|
|
295
|
+
that project's roadmap. Relative paths in other options resolve against it.
|
|
296
|
+
See [Working across projects](#working-across-projects).
|
|
297
|
+
- **`--tasks-file <path>`**: Point at a specific tasks file instead of the one
|
|
298
|
+
derived from the current directory.
|
|
299
|
+
- **`-v, --verbose`**: Show verbose output.
|
|
300
|
+
|
|
225
301
|
### Roadmap Management
|
|
226
302
|
|
|
227
303
|
- **`status [<id>]`**: Queue/history overview or deep-dive into a specific
|
|
228
|
-
task, including supersession lineage
|
|
229
|
-
times. Superseded and failed history
|
|
230
|
-
`--verbose` also shows routine
|
|
304
|
+
task, including supersession lineage, the last resolved runner command, and
|
|
305
|
+
runner/orchestrator-hook execution times. Superseded and failed history
|
|
306
|
+
stays visible in the default overview; `--verbose` also shows routine
|
|
307
|
+
completed/cancelled history.
|
|
308
|
+
- `--json`: Emit machine-readable JSON instead of formatted text, so
|
|
309
|
+
scripts never have to parse the internal state file.
|
|
310
|
+
- `--brief`: Omit task descriptions, which otherwise dominate the output.
|
|
231
311
|
- **`goal [<text>]`**: Set or view the long-term goal shared by all tasks.
|
|
232
312
|
Supports `-f/--file`.
|
|
233
|
-
- **`add <desc>`**: Append a new task. Supports `--index
|
|
234
|
-
|
|
313
|
+
- **`add <desc>`**: Append a new task. Supports `--index`, `--runner`, and
|
|
314
|
+
`--model`.
|
|
315
|
+
- **`edit <id>`**: Modify a task's description, runner, model, or position.
|
|
316
|
+
- **`brief <id> [text]`**: View or set a task's long-form brief. Unlike the
|
|
317
|
+
description it has no length cap, and it is appended to the runner prompt
|
|
318
|
+
automatically — the right home for measured timings, exact failing
|
|
319
|
+
selectors, or why a previous attempt was wrong. Supports `-f/--file`.
|
|
235
320
|
- **`delete <id>`**: Remove an unstarted task while retaining its runner log.
|
|
236
321
|
Tasks with execution history require `--force`; autonomous restructuring
|
|
237
322
|
should use `supersede`. Supports `--all` and `--completed` for bulk cleanup,
|
|
@@ -243,9 +328,11 @@ See [docs/EVALS.md](docs/EVALS.md) for details.
|
|
|
243
328
|
- `add <id> <finding>`: Record a new technical detail.
|
|
244
329
|
- `edit <id> <index> <text>`: Modify an existing progress entry.
|
|
245
330
|
- `delete <id> <index>`: Remove a progress entry.
|
|
246
|
-
- **`config`**: Manage project configuration (runner, retries
|
|
331
|
+
- **`config`**: Manage project configuration (runner, model, retries,
|
|
332
|
+
time limit).
|
|
247
333
|
- `list`: View current configuration.
|
|
248
|
-
- `set <key> <value>`: Update a setting.
|
|
334
|
+
- `set <key> <value>`: Update a setting. `set model default` clears a
|
|
335
|
+
pinned model without touching the runner.
|
|
249
336
|
- **`hooks`**: Manage orchestrator hooks.
|
|
250
337
|
- `list`: View available and active hooks.
|
|
251
338
|
- `install`: Install built-in hooks to the global directory.
|
|
@@ -273,6 +360,7 @@ See [docs/EVALS.md](docs/EVALS.md) for details.
|
|
|
273
360
|
- **`logs [<id>]`**: Print a task's execution log to stdout, including retained
|
|
274
361
|
logs for removed tasks. If no ID is provided, it defaults to the active or
|
|
275
362
|
most recent task. Orchestrator hook output is automatically appended.
|
|
363
|
+
Supports `--json` to wrap the log with its task ID and path.
|
|
276
364
|
|
|
277
365
|
### Execution
|
|
278
366
|
|
|
@@ -281,7 +369,39 @@ See [docs/EVALS.md](docs/EVALS.md) for details.
|
|
|
281
369
|
- `--yolo`: Run the runner in auto-approve mode (default: True).
|
|
282
370
|
- `--env`: Set environment variables for the runner (e.g., `--env KEY=VALUE`).
|
|
283
371
|
- `--no-defaults`: Skip default flag injection for known runners.
|
|
284
|
-
- `--`: Use `--` to pass any flag directly to the underlying runner.
|
|
372
|
+
- `--`: Use `--` to pass any flag directly to the underlying runner. A
|
|
373
|
+
per-task `--runner`/`--model` overrides anything passed here.
|
|
374
|
+
- **`exec [<description>]`**: Run one task, or one set of reviews, outside any
|
|
375
|
+
roadmap. Prints the agent's closing message to stdout and everything else to
|
|
376
|
+
stderr. Exits non-zero if the task did not complete. See
|
|
377
|
+
[One-off tasks](#one-off-tasks-without-a-roadmap).
|
|
378
|
+
- `-f/--file`: Read the description from a file, or `-` for stdin. Unlike
|
|
379
|
+
`add`, there is no length cap.
|
|
380
|
+
- `--review <names>`: Reviews to run after the task, comma-separated or
|
|
381
|
+
repeated; `all` selects every one. With no description, only the reviews
|
|
382
|
+
run. Hooks that revise the roadmap cannot be selected.
|
|
383
|
+
- `--scope <path|range>`: What the reviews look at. Paths pass through; a
|
|
384
|
+
git revision range is resolved to the files it changed. Defaults to
|
|
385
|
+
uncommitted work, or the whole tree outside a repository.
|
|
386
|
+
- `--runner`, `--model`: Which agent CLI and model to use.
|
|
387
|
+
- `--time-limit`: Minutes before the agent is killed (default 60, 0 for no
|
|
388
|
+
limit).
|
|
389
|
+
- `--yolo/--no-yolo`: Run the agent unattended (default: True).
|
|
390
|
+
- `--keep`: Keep the run's state directory even when it succeeds.
|
|
391
|
+
- **`skill install`**: Install the packaged Agent Skill so agents discover
|
|
392
|
+
Lemming. Writes to `~/.agents/skills` by default and names any tool-specific
|
|
393
|
+
directories it found.
|
|
394
|
+
- `--to <dir>`: Install into a specific skills directory.
|
|
395
|
+
- `--all`: Also cover every detected tool's own skills directory.
|
|
396
|
+
- `--link`: Symlink instead of copying, so upgrades take effect immediately.
|
|
397
|
+
- `--force`: Replace an existing installation of this skill.
|
|
398
|
+
- `--dry-run`: Print what would happen, refusals included.
|
|
399
|
+
- **`skill uninstall`**: Remove it again. Same `--to`, `--all`, and
|
|
400
|
+
`--dry-run`.
|
|
401
|
+
- **`stop`**: Stop the running loop and its runner.
|
|
402
|
+
- `--after-current-task`: Drain instead — let the running task finish, then
|
|
403
|
+
stop before claiming another. This is the safe way to change the runner
|
|
404
|
+
or model without stranding work in flight.
|
|
285
405
|
- **`serve`**: Launch the interactive Web UI.
|
|
286
406
|
- `--port`: The port to bind the server to (default: 8999).
|
|
287
407
|
- `--host`: The host address to bind the server to (default: 127.0.0.1).
|
|
@@ -292,6 +412,36 @@ See [docs/EVALS.md](docs/EVALS.md) for details.
|
|
|
292
412
|
|
|
293
413
|
---
|
|
294
414
|
|
|
415
|
+
## Working across projects
|
|
416
|
+
|
|
417
|
+
When work on one project turns up something that belongs to another — a bug in
|
|
418
|
+
a dependency you also maintain, a doc fix in a sibling repo — file it directly
|
|
419
|
+
on that project's roadmap with `-C` instead of routing it through an external
|
|
420
|
+
issue tracker:
|
|
421
|
+
|
|
422
|
+
```bash
|
|
423
|
+
# From inside project A, queue work on project B
|
|
424
|
+
lemming -C ~/src/other-project add "check --fix drops the trailing newline"
|
|
425
|
+
|
|
426
|
+
# Attach the evidence; the brief has no length cap
|
|
427
|
+
lemming -C ~/src/other-project brief <id> --file repro.md
|
|
428
|
+
|
|
429
|
+
# Read the other project's roadmap without leaving yours
|
|
430
|
+
lemming -C ~/src/other-project status
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
`-C` works whether or not the target keeps a `tasks.yml` in its repo, so you
|
|
434
|
+
never have to know where its isolated state lives. Because it changes the
|
|
435
|
+
working directory, everything else follows too: the target's `.env`, its
|
|
436
|
+
`.lemming/hooks`, and the directory the runner executes in.
|
|
437
|
+
|
|
438
|
+
When an agent files a task this way from inside a `lemming run`, the new task
|
|
439
|
+
records the task it came from via `parent` and `parent_tasks_file`. The
|
|
440
|
+
downstream runner then sees a **Parent Task Context** section in its prompt
|
|
441
|
+
describing why the work was requested, so the report doesn't lose its origin.
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
295
445
|
## Advanced: Runner Customization
|
|
296
446
|
|
|
297
447
|
Lemming uses **fuzzy matching** to automatically inject the correct "YOLO"
|
|
@@ -304,17 +454,53 @@ Lemming uses **fuzzy matching** to automatically inject the correct "YOLO"
|
|
|
304
454
|
- **Codex**: Runs non-interactively via `codex exec`, adds `--json`, and, in
|
|
305
455
|
YOLO mode, adds `--dangerously-bypass-approvals-and-sandbox`
|
|
306
456
|
|
|
457
|
+
### Choosing a model
|
|
458
|
+
|
|
459
|
+
The model is a first-class setting, separate from the runner, so switching
|
|
460
|
+
provider does not silently discard it:
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
lemming config set model gemini-3.6-flash-high # project default
|
|
464
|
+
lemming add "Fix the flaky test" --model fast # just this task
|
|
465
|
+
lemming config set model default # let the runner decide
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
Precedence, highest first: an explicit `--model` inside a runner string, the
|
|
469
|
+
task's `--model`, the project's `config model`, then anything passed after
|
|
470
|
+
`lemming run --`. A per-task setting always wins over the loop-wide
|
|
471
|
+
passthrough — the conflicting global flag is dropped rather than duplicated
|
|
472
|
+
on the command line.
|
|
473
|
+
|
|
474
|
+
### Runner strings
|
|
475
|
+
|
|
476
|
+
A runner is not limited to a binary name: any extra arguments in the string
|
|
477
|
+
are appended to the command, which is another way to pin per-task behaviour.
|
|
478
|
+
|
|
479
|
+
```bash
|
|
480
|
+
lemming add "Try the fast model" --runner "agy --model fast"
|
|
481
|
+
```
|
|
482
|
+
|
|
307
483
|
You can disable default flag injection with `--no-defaults` (`codex exec`
|
|
308
484
|
remains the Codex execution interface), or use a **template** to fully control
|
|
309
485
|
the command layout:
|
|
310
486
|
|
|
311
487
|
```bash
|
|
312
|
-
lemming
|
|
488
|
+
lemming config set runner "my-tool --input={{prompt}} --json"
|
|
313
489
|
```
|
|
314
490
|
|
|
315
491
|
When `{{prompt}}` is present in the runner string, Lemming replaces it with the
|
|
316
492
|
prompt text and skips all default flag injection.
|
|
317
493
|
|
|
494
|
+
### Knowing what actually ran
|
|
495
|
+
|
|
496
|
+
Each attempt records the command it launched, with the prompt elided, so the
|
|
497
|
+
runner and model behind a finished task stay recoverable:
|
|
498
|
+
|
|
499
|
+
```bash
|
|
500
|
+
lemming status <id> # includes "Last Command:"
|
|
501
|
+
lemming status --json # same data, machine-readable
|
|
502
|
+
```
|
|
503
|
+
|
|
318
504
|
---
|
|
319
505
|
|
|
320
506
|
## Releasing
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lemming
|
|
3
|
+
description: Delegate a single coding task to another AI agent CLI (agy, claude, codex) through one interface, or run a code review — readability, testing, UX — over changed files, a PR branch, or a path. Use when handing work to a different agent to spare a quota or play to its strengths, or when reviewing a diff before opening a pull request. Not for driving a multi-task project; that is a roadmap.
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# lemming
|
|
8
|
+
|
|
9
|
+
One interface over several agent CLIs. You do not need to know how `agy`,
|
|
10
|
+
`claude`, or `codex` spell their flags — only `lemming exec`.
|
|
11
|
+
|
|
12
|
+
## Delegate one task
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
lemming exec "Fix the flaky heartbeat test in src/runner_test.py" --runner codex
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The agent's closing message comes back on **stdout**; progress and the event
|
|
19
|
+
trace go to stderr. Exit code is 0 only if the task completed. That message is
|
|
20
|
+
the return value — read it instead of hunting through logs.
|
|
21
|
+
|
|
22
|
+
Pipe a longer handoff rather than fighting shell quoting. There is no length
|
|
23
|
+
limit, unlike a roadmap task description:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
cat handoff.md | lemming exec -f - --runner agy
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Delegate when another agent's quota, price, or strengths suit the work better
|
|
30
|
+
than yours. Give the task everything it needs: it starts with an empty context
|
|
31
|
+
and sees nothing of your conversation.
|
|
32
|
+
|
|
33
|
+
## Run a review
|
|
34
|
+
|
|
35
|
+
With no description there is nothing for a task runner to do, so only the
|
|
36
|
+
reviews run — against work that already exists.
|
|
37
|
+
|
|
38
|
+
```sh
|
|
39
|
+
lemming exec --review readability # uncommitted work
|
|
40
|
+
lemming exec --review testing --scope main...HEAD
|
|
41
|
+
lemming exec --review all --scope src/api/
|
|
42
|
+
lemming exec "Add pagination" --review all # do the work, then gate it
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`--scope` takes paths, which pass through untouched, or a git revision range,
|
|
46
|
+
which is resolved to the files it changed. It defaults to uncommitted work.
|
|
47
|
+
A clean tree stops the run rather than reviewing everything.
|
|
48
|
+
|
|
49
|
+
Reviews **edit the workspace**: readability applies fixes and reruns checks.
|
|
50
|
+
That is the point — but it means a review is not read-only.
|
|
51
|
+
|
|
52
|
+
## Reviewing someone else's branch
|
|
53
|
+
|
|
54
|
+
Check it out in a worktree so your own tree is untouched, and point `-C` at it:
|
|
55
|
+
|
|
56
|
+
```sh
|
|
57
|
+
git worktree add /tmp/pr-123 && (cd /tmp/pr-123 && gh pr checkout 123)
|
|
58
|
+
lemming -C /tmp/pr-123 exec --review testing --scope main...HEAD
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## What to know before running it
|
|
62
|
+
|
|
63
|
+
- **The agent runs unattended.** `--yolo` is the default, so it does not
|
|
64
|
+
inherit the permission prompts of whatever launched it. Treat `lemming exec`
|
|
65
|
+
as granting an agent unsupervised write access to the working directory.
|
|
66
|
+
- **One agent run, no retry.** A failure is final; it does not silently try
|
|
67
|
+
again. `--time-limit` caps the wall clock (default 60 minutes).
|
|
68
|
+
- **Interrupting leaves partial edits.** The workspace is not restored, so
|
|
69
|
+
there is no atomicity to rely on.
|
|
70
|
+
- **Failures keep their log.** The state directory path is printed on stderr;
|
|
71
|
+
read it with `lemming logs` pointed at that tasks file.
|
|
72
|
+
|
|
73
|
+
## Running several at once
|
|
74
|
+
|
|
75
|
+
Concurrent runs in one checkout will interleave their edits. Give each write
|
|
76
|
+
task its own worktree and address it with `-C`. Read-only work parallelizes
|
|
77
|
+
safely as-is.
|
|
78
|
+
|
|
79
|
+
## When not to use it
|
|
80
|
+
|
|
81
|
+
`exec` is for one unit of work. Anything needing more context than a single
|
|
82
|
+
agent run can hold — a migration across a large codebase, a multi-step feature
|
|
83
|
+
— belongs on a roadmap: `lemming add`, then `lemming run`. In particular,
|
|
84
|
+
`--scope .` over a large repository *samples*; it does not cover.
|
|
85
|
+
|
|
86
|
+
Run `lemming exec --help` for the full flag list.
|
|
@@ -158,6 +158,9 @@ Your hook template can use the following placeholders:
|
|
|
158
158
|
description, recent progress, and a recent execution-log excerpt capped at
|
|
159
159
|
16 KiB).
|
|
160
160
|
- `{{finished_task_id}}`: The ID of the task that just finished.
|
|
161
|
+
- `{{scope}}`: What the hook should look at, and how broadly. Under `lemming
|
|
162
|
+
run` this names the work the finished task left behind; under `lemming exec
|
|
163
|
+
--review` it is whatever `--scope` resolved to.
|
|
161
164
|
- `{{tasks_file_name}}`: The filename of the tasks YAML file.
|
|
162
165
|
- `{{tasks_file_path}}`: The full path to the tasks YAML file.
|
|
163
166
|
|
|
@@ -166,6 +169,12 @@ over older completed history. Readability, testing, and UX hooks receive a
|
|
|
166
169
|
smaller roadmap summary because their primary context is the finished task and
|
|
167
170
|
the workspace.
|
|
168
171
|
|
|
172
|
+
A review hook should take its breadth from `{{scope}}` rather than narrowing
|
|
173
|
+
itself in prose. Hardcoding "the files changed in the last task" makes the hook
|
|
174
|
+
unusable outside the orchestrator loop, where there is no last task. Depth
|
|
175
|
+
limits are different and belong in the prompt: "verification, not a security
|
|
176
|
+
audit" describes the kind of review, not its extent.
|
|
177
|
+
|
|
169
178
|
## Developer Ergonomics
|
|
170
179
|
|
|
171
180
|
### Listing Hooks
|