pre-1.0for people and AI agents
todoer is one binary. Agents and people claim todos, work in git worktrees, and review the pull requests on the command line. No database, no server, no account.
A todo is a file in .todoer/todos/. Its name is its id. A pull request is a folder in .todoer/prs/, committed on the branch that it goes into. There is no settings file. A person and an agent can read every file, and git history keeps every change.
A todo. The file name is its id and its title. todoer claim sets the assignee and commits the file, so you can push the claim at once. The front matter is optional.
--- assignee: you@example.com labels: [auth] --- Steps to reproduce: sign in with an expired token. The app stops after the third retry.
This todo waits for another one. todoer ls shows it as blocked while the other todo file exists. todoer done and todoer pr merge remove a todo file.
--- labels: [auth] dependsOn: [fix-the-login-crash] --- Limit the sign-in attempts for each account.
The pull request. The folder name is its id and its title. pr.md holds the author, the base and the todos. It names no branch: the branch that holds the folder is the branch that it goes into. --update writes the whole file again, and keeps the old description and todos when you do not give new ones.
--- author: you@example.com base: f9582bb76d212ae8cfec79eeb2ced593240cf464 todos: [fix-the-login-crash] --- Use the retry constant. Add a test.
The latest submit as one squashed commit. todoer pr merge applies it on the current branch with git am --3way. Next to it, pr.diff holds the combined diff for the review.
From 5a49e712aa8c0b763a4057f2910c84ea08044048 Mon Sep 17 00:00:00 2001 From: You <you@example.com> Subject: [PATCH] todoer: merge fix-the-login-crash diff --git a/src/auth.rs b/src/auth.rs --- a/src/auth.rs +++ b/src/auth.rs @@ -1,4 +1,4 @@ fn login() { - let retries = 3; + let retries = MAX_RETRIES; connect(retries); }
The review of the latest patch: only the comments. pr comment writes the file, and you commit it when the review is done. There is no verdict: a merge accepts the pull request.
### c1 `src/auth.rs:2` you@example.com > let retries = MAX_RETRIES; Add a test for the retry path.
A label rule. The file name is the label. The text tells in plain words which todos must have the label. todoer does not read it: the agent reads the rules before todoer add and adds the labels that match.
Add this label to a todo that changes the login, the sessions or the tokens. Do not add it to a todo that only changes the docs.
The areas of the code. The patterns use the gitignore rules. The last pattern that matches a path wins. pr summary shows how many files and lines each area changes. -a security shows the diff of these areas only. -x e2e-tests,unit-tests hides them.
security: /src/api/auth tests: /tests e2e-tests: /tests/e2e unit-tests: *.test.js
Each step uses git and the files above. The help text, todoer help, shows every command on one screen.
add writes .todoer/todos/<name>.md. The text can come on stdin. show prints all the data of a todo. done removes the file. check reports bad todos.
todoer add fix-the-login-crash -l auth
dep add refuses a cycle. A todo can wait for one todo or for all the todos of a label. ls --available lists the todos that can start now, and dep show prints the tree.
todoer dep add new-login-page -l auth-backend-refactor
A label groups related todos. progress shows which are in progress, in a pull request or not started. A label rule tells the agent in plain words which todos get the label.
$ todoer progress auth auth 1 in progress, 0 in a pull request, 1 not started [=-]
todoer knows no main branch. claim commits the todo on your branch, so you can push it at once. Claim one todo, a list or a whole --label. A claim refuses a todo of another person or a blocked todo.
One command for the agent: pr submit --branch main -n <name> squashes every commit since the work started from main into one, and commits the pull request on main. There is nothing to push and no hosting service.
skill --init writes the workflow as a SKILL.md for Claude Code, Codex and Cursor, in the repository, or outside a repository in your home folder. todoer skill prints it.
The pull request lands on your branch, so you review and merge it there. pr merge applies the patch and removes the pull request and its todos, in one commit: todoer: merge <name>. On a conflict, nothing changes.
There is no approve and no verdict. A committed review asks for changes. pr submit -n <pr> --update writes the whole pull request again and removes the review. pr merge stops while the review has a comment.
On a branch of your own, pr apply <pr> puts the patch in your working tree, with no commit. Run the code, or change it and update the pull request with -n <pr> --update.
Name the parts of the code in .todoer/areas, such as security or e2e-tests. pr summary shows how many files and lines each area changes. -a security shows only these files. -x unit-tests hides the tests.
Ask a second agent, not the one that wrote the code, to explain the patch and to add your comments. It runs pr details and pr comment. Or read it yourself with todoer pr review <pr>. When the review is done, commit review.md. Select a target:
A target can also name a file that the pull request does not change, to point to code that must change too.
You plan and decide. Agents claim, write the code, submit and update. Every step is a commit on your branch, so you can push it at any time.
$ cd ~/code/my-project $ todoer skill --init wrote .agents/skills/todoer/SKILL.md (Codex, Cursor) wrote .claude/skills/todoer/SKILL.md (Claude Code, Cursor) $ todoer add fix-the-login-crash -l auth "Steps to reproduce: ..." .todoer/todos/fix-the-login-crash.md
Step by step, with what to tell your agent: read the guide.
fix-the-login-crash”, a list of todos, or a label. todoer claim assigns the todos to you and commits them on your branch. Push the commit when you want.todoer pr submit --branch main -n <name>. It squashes every commit since the work started from main into one, and commits the pull request on main. Name any branch.todoer pr comment. Then commit the review.todoer pr submit --branch main -n <pr> --update, which writes the whole pull request again and removes the review.todoer pr merge <pr>. There is no approve: a merge accepts the pull request. It adds one commit, todoer: merge <pr>, and stops while the review has comments.curl -fsSL sobanieca.github.io/todoer/install.sh | bash
The script installs todoer to /usr/local/bin, for all users. If that folder is not writable, the script stops with an error. Then run it with sudo:
curl -fsSL sobanieca.github.io/todoer/install.sh | sudo bash
Or pick your own folder with INSTALL_DIR. It must be a folder on your PATH:
curl -fsSL sobanieca.github.io/todoer/install.sh | INSTALL_DIR=~/.local/bin bash
A single binary for Linux and macOS (x64 and arm64), no runtime needed. Update it any time with todoer update. Run todoer help to see every command. todoer is not released yet: until version 1.0.0, any part of it can change.