limen README

The project's README from github.com/overment/limen. As one markdown file: README.md.

limen

MEGA.dev

Explore the full workflow → Towards Autonomous Product Development

This MEGA Drop explains the workflow behind limen, including a live video walkthrough with Pi, Herdr, and Grok Bot. MEGA.dev shares practical articles, repos, and tools for working with AI.

You talk to one coordinator in Herdr. It starts OMP or Pi workers and reviewers in isolated Git worktrees. Each job leaves a branch, task, log, state, and session. You decide what to build and what to merge. The coordinator runs the harness.

A coordinator starts workers and reviewers in isolated worktrees, then merges with ordinary Git

Experimental. Commands, prompts, and project files may still change.

Requires macOS or Linux, Node.js 24+, Git, and the selected engine (omp or pi) on PATH. Windows is unsupported. Last known-good: pi 0.84.2, Herdr 0.8.0 — recorded on each job, not a runtime gate.

Jobs can live on an always-on seat (a VPS on Tailscale) while your laptop is only a window. See docs/remote.md. The walkthrough we actually ran is docs/vps.md.

Finish webhooks (opt-in)

When a job reaches a terminal state (done / failed / stopped), limen can POST {job, status, branch} to one or more destinations so a bot or routine can wake. Off by default. Installing limen does not enable any project.

Opt in per project with a private, git-excluded file:

# <project>/.limen/finish-webhook.env  (mode 600; never commit)
LIMEN_FINISH_WEBHOOK_TARGETS='[{"url":"https://api2.cursor.sh/automations/webhook/…","auth":"Bearer …"}]'

Put that file beside the primary Git checkout (linked worktrees use the canonical root). Fresh spawns snapshot the path onto the job; continuations inherit the parent's choice. Home/legacy config does not opt a project into automation. An optional LIMEN_FINISH_WEBHOOK_AUTHOR_TARGETS map sends each finish only to the ticket author's configured bots; without it, every target still gets every finish.

What “accepted” means. HTTP 2xx means the sender reached the endpoint. It does not mean a bot finished a turn — expect latency, and confirm the wake in the bot chat / routine run. Inspect with limen jobs <id> (finish-webhook-env, finish-webhook-attempt, finish-webhook).

Configuration uses only LIMEN_FINISH_WEBHOOK_* keys; retired bot-specific keys no longer work. Existing private files and launchers need the migration steps. The helper filename remains tony-finish-ping.sh.

Full setup, multi-target notes, deliberate retry, and troubleshooting: docs/finish-webhooks.md.

Trust boundary

A spawned Pi job runs pi --approve as you; an OMP job runs omp --auto-approve. A worktree and process group provide separation, not a security sandbox. A worker can do anything your account can do. Look at the branch before you merge. See SECURITY.md.

Install

This part is yours. Once:

git clone https://github.com/overment/limen.git
cd limen
npm install
npm link

npm link puts that clone on PATH. The binary reads hook/ and templates/ next to itself. Projects do not copy those files. After git pull on the clone, /reload the coordinator.

Then in each project:

cd /path/to/your-project
limen init
export LIMEN_ENGINE=omp
LIMEN_COORDINATOR=1 omp --provider openai-codex --model gpt-6-sol --thinking xhigh

limen init plants what the project owns (vision, board, feature lanes, styleguide) and a stub that loads package hooks. It never overwrites existing project files. It always deletes leftover .pi/extensions/limen-*.ts hook copies so they cannot load beside the stub. limen init --drop-leftovers deletes only prompt copies that still match the package.

That interactive session is the coordinator (LIMEN_COORDINATOR=1), not a spawned job. From here you talk. You do not drive the job CLI. limen spawn starts workers and reviewers — not a coordinator; the same env var on a spawn shell does not change the job's role. Prefer a Herdr space named for the plant (limen, or alice limen), not a space named only workers. Label the coordinator tab clearly. Worker tabs come from spawn. The inherited shop manual (templates/agents.md; a project AGENTS.md overlays it) carries the same layout rules.

How you work

Tell the coordinator the outcome you want. It writes or moves the ticket, keeps spec/build.md aligned, commits the ticket so the worker can see it, and starts a job. Stay in that conversation. A wake arrives when a job finishes. Ask only when something looks wrong, or when the coordinator asks you — product ambiguity, a real tradeoff, credentials, or a merge.

A useful ask names the outcome and the first artifact, not a tour of the repo. The coordinator turns that into a short spawn plus a Ticket: pointer. It does not paste the ticket into the prompt.

done means the run ended cleanly: the selected engine exited 0, or a hosted session ended, without a final error or aborted stop reason. A provider-errored run records failed with that reason. Neither state means the ticket is finished or the branch is safe to merge. The coordinator inspects the record, the diff, and the checks, then either merges, resumes a repair, or asks you.

When the blast radius earns a second pair of eyes, the coordinator starts a fresh reviewer against the candidate. The reviewer reports a verdict; it does not rewrite the branch. You still merge.

What the coordinator runs

These commands are the harness. The coordinator types them. They are here so you can recognize a job ID, a wake, or a recovery step — not as a daily script.

limen spawn --label "F001 auth handler" \
  "Implement F001's session-handler slice. Start with the failing session test. One commit. Ticket: spec/features/active/F001-auth/ticket.md"

limen jobs
limen jobs <id|suffix|label>
git diff HEAD...<branch>

limen spawn --review --branch limen/<job-id> --label "F001 auth review" \
  "Review the F001 candidate against spec/features/active/F001-auth/ticket.md. Name the commit reviewed."

limen steer <id> "stay on the session test; do not widen"
limen stop <id> "reason"
limen spawn --branch limen/<job-id> "Focused resume instruction"

The last line of spawn is the durable job ID. A running job picks up a steer between tool calls. Stop sends TERM, then escalates. Resume reuses the branch and its worktree, uncommitted files included. The coordinator inspects that state first.

Finished jobs keep their files under .limen/jobs/. Extra checkouts do not stay: the next spawn drops finished worktrees, and limen prune does the same on demand. Resume with --branch keeps that checkout. limen prune --retire deletes finished job records whose branches are already merged or dropped; --dry-run prints the ids and removes nothing. Spawn and sweep never retire records.

To keep a finished job's conversation, run limen continue <job-id> "Follow-up instruction". If its checkout was pruned, Limen restores the recorded path from the surviving local branch and copies the saved session into a new linked job. Only committed branch contents return; pruned uncommitted files are lost. A missing branch or transcript prevents recovery, and a branch checked out elsewhere is not taken over.

A job is bounded by 90 minutes (--timeout 20m) and 900 tool-start events (LIMEN_MAX_TOOL_CALLS). A bound records failed; it does not finish the ticket. Do not run limen wait in the coordinator conversation — it blocks you.

Ticket authorship

For collaborators sharing a project, limen ticket-author spec/features/active/F001-auth/ticket.md reports the name, email, and commit that first added the ticket, following Git-recognized renames between lanes. Paths are relative to the current directory; absolute paths within the repository also work. The lookup reads the current branch's committed HEAD, never the current operator's Git config or GitHub session, and writes nothing.

A GitHub noreply email also yields its recorded login. Ordinary emails remain usable identities without a GitHub account or network access. This is the creation author, not the committer or latest editor; it is evidence from Git, not verified human identity. Shared bot credentials identify the bot, not the person who asked it to file the ticket. Keep distinct authors on filing commits when collaborators need distinct attribution.

Spawn records that creation @login (or an unavailable reason) on the job for finish routing. Uncommitted paths and shallow history report authorship unavailable rather than guessing. Commit a new ticket before looking it up; fetch complete history for a shallow clone. A move Git cannot recognize, a squash, or rewritten history can lose original attribution. Deleting and recreating a path starts a new ticket history. No author tags are added to ticket Markdown.

Models

Adam's standing defaults for Overment limen/Herdr plants (2026-09-23): prefer OMP for new sessions and jobs; use Pi only when the task truly needs it. Project choices live in spec/build.md, not another policy file.

Work Provider Model
Ordinary work, including coordination openai-codex (Codex on OMP) gpt-6-sol
Simple / cheap tasks xai-oauth grok-4.7
UI-related work anthropic claude-opus-5-5

Pass the engine, provider, model, and chosen reasoning explicitly. pi-claude is a Pi provider; on OMP use anthropic. New jobs default to OMP; use --engine pi or LIMEN_ENGINE=pi only when Pi is required.

Start a coordinator in an existing Herdr pane at a shell prompt, with the project as its working directory:

herdr agent start limen-peer --kind omp --pane <pane-id> -- \
  --provider openai-codex --model gpt-6-sol --thinking xhigh

Herdr forwards the arguments after --; it does not select Limen's model. Do not rely on old Pi project settings or a global model default. This policy does not rewrite either engine's settings or credentials.

For an ordinary worker:

limen spawn --engine omp \
  --provider openai-codex --model gpt-6-sol --thinking high \
  --label "short worker task" 'Implement the requested slice.'

In Herdr this is hosted; use --detached for a requested background worker. --provider, --model, and --thinking reach the selected engine as separate flag/value pairs in both modes. limen continue accepts the same flags, copies the parent engine, and refuses a conflicting --engine; continuing a Pi transcript still requires Pi.

Model precedence remains --model, then LIMEN_WORKER_MODEL (or LIMEN_REVIEWER_MODEL for --review), then the built-in fallback. Pass the standing choices explicitly rather than relying on that legacy fallback. Adam performs reviews; do not start an independent reviewer unless asked.

--engine pi|omp selects the job binary, overriding LIMEN_ENGINE. With neither set, new jobs use OMP. Old job records without an engine remain Pi for compatibility; continuation keeps the parent's engine. Pi and OMP keep separate auth stores (~/.pi, ~/.omp); authenticate OMP yourself. One wrapper and one stream parser serve both.

Adjacent-repository workspaces

A non-Git parent can hold several independent Git children. You initialize once at the parent (limen workspace init) and map the children in spec/workspace.md. After that, tell the coordinator which repo the work belongs in. It passes exactly one --repo per job. Tickets stay under the parent; branches, worktrees, diffs, and review stay in the selected child.

Project files

The installed limen is the default shop manual, role prompts, speech register, and hooks. limen init only creates what the project owns:

.agents/limen/styleguide.md           project coding practice
spec/vision.md                        durable product intent
spec/build.md                         TRACK / NOW / NEXT / PROVEN
spec/features/                        planned, active, done, and dropped work
.pi/extensions/limen.ts               stub: load hooks from the package
.limen/jobs/<id>/                     runtime evidence

Optional overlays replace a package default for that file only: AGENTS.md, .agents/limen/worker.md, .agents/limen/reviewer.md, .agents/limen/communication.md. A file that still matches the package is a leftover copy; the coordinator names it. Different bytes are an overlay — keep, drop, or edit. Never overwrite an overlay.

The communication hook puts the shop manual, speech register, vision, and styleguide on the system prompt once per model call (board digest last, so a NOW/NEXT change does not break the cached prefix). A short per-turn note names the audience and the reply rules; a wake cue lives there, not in the system prompt. After a write or edit, the tool result recalls the rule that applies. Updating the clone updates every project on that machine.

Recovery

The coordinator does this. You only need it if you are looking at a stuck tab yourself.

Symptom Safe next step
Quiet or repetitive job limen jobs <id>, the log, and the worktree. Stop only on evidence, then resume narrower.
Worker has a real question Read its durable note, answer it, resume the branch.
Wrapper is dead but state says running Verify the recorded PID, correct the plain state file, then resume.
Completion wake was missed Inspect .limen/jobs/ and Git. Job files remain canonical if a notification is missed.

Command reference

limen init
limen init --drop-leftovers
limen workspace init
limen spawn "instruction" [--label L] [--engine pi|omp] [--provider P] [--model M] [--thinking T] [--branch B] [--role NAME] [--timeout 20m] [--task-file F|-] [--prepare CMD]
limen spawn --repo R "instruction" [--label L] [--model M]
limen spawn --review --branch B --label L "instruction"
limen jobs [--running|--active|--all|--label PREFIX|<id|suffix|label>]
limen diff <id|suffix|label>
limen prune [--retire [--dry-run]]
limen steer <id|suffix|label> | --running "correction"
limen stop <id|suffix|label> [reason]
limen wait <id|suffix|label>
limen watch <id|suffix|label> | --running
limen unwatch <id|suffix|label> | --all
limen open <id|suffix|label>
limen close <FNNN>

IDs, unique suffixes, and unique labels are interchangeable where shown.

At a terminal, jobs renders an aligned table for eyes; piped, it prints the compact format tools parse. LIMEN_VIEW=human|compact forces a view; NO_COLOR drops the paint.

Develop

See CONTRIBUTING.md. CI runs the same checks on Linux and macOS:

npm run check

Limen has zero runtime dependencies. Capability belongs in src/; operating judgment belongs in templates and project files.

limen (overment/limen)

Searching Database…

230 ·GitHub
What is this?limen is a minimal one-human-many-agents harness built from files, Git, and one CLI: you talk to a single coordinator that starts OMP or Pi coding agents as workers and reviewers in isolated Git worktrees.
Is it a hosted service, or something I run on my own machine?It is a local CLI harness: installing a clone with npm link puts the limen binary on PATH, and you drive the coordinator from your own terminal or a Herdr pane.
How do I set it up on one of my projects?Run npm link on the clone once, then limen init inside each project — it plants the vision, board, feature lanes, and styleguide without overwriting any existing files.
What do I need installed before it will run?macOS or Linux with Node.js 24+, Git, and your chosen engine (omp or pi) on PATH; Windows is unsupported. The engines keep separate auth stores, so you authenticate OMP yourself.
The agents run as me — what stops one from wrecking my machine?Nothing hard: a Pi job runs pi --approve as you and OMP jobs run auto-approved. The worktree and process group are separation, not a sandbox — a worker can do anything your account can, so inspect the branch before merging.
Is this built for a solo developer, or can a team share it?It is built around one human directing many agents, but collaborators sharing a project get Git-based ticket attribution: limen ticket-author reports who first filed a ticket, and that author is recorded on the job.
Do the jobs have to run on my laptop?No — jobs can live on an always-on seat such as a VPS on Tailscale while your laptop is only a window into the coordinator; docs/remote.md and docs/vps.md cover the setup.
Which AI models and engines does it drive?The author's standing defaults: openai-codex running gpt-6-sol for ordinary work and coordination, grok-4.7 for simple or cheap tasks, and claude-opus-5-5 for UI work. New jobs default to the OMP engine; pick --engine pi only when Pi is truly needed.
After a job finishes, who merges the code?You do. 'done' or 'failed' only means the run ended — not that the branch is safe. The coordinator inspects the record, diff, and checks; for risky changes it spawns a fresh reviewer that reports a verdict but never rewrites the branch.
What happens to a job once it finishes?It leaves a branch, task, log, state, and session under .limen/jobs/. Jobs are capped at 90 minutes and 900 tool-start events; you can resume the branch, keep the conversation with limen continue, or clean up with limen prune.
Is it stable enough to rely on?The README marks it Experimental — commands, prompts, and project files may still change. Last-known-good versions (pi 0.84.2, Herdr 0.8.0) are recorded per job rather than enforced at runtime.
What are similar projects?ruflo, orca, zuse, ordewell, deer-flow, ralph, agentbox, codify
Creator
overment
Size
39.6 MB
Stars
230
Updated
CommitOct 17
Age
2mo
Commits · 90 Days