Skip to content

devgony/rein

Repository files navigation

rein

LLM task journal + shared inbox manager.

rein (as in the reins of a harness) is the interface for steering an LLM: it keeps the task documents you hand to an LLM as local Markdown, lets the LLM run and check them off safely, and connects to GitHub issues/PRs only when you need to share or review.

  • The source of truth is the Markdown in a local store. GitHub is a publishing and review surface, not the truth.
  • State changes go through CLI mutation commands (check/log/fail), not direct Markdown edits — so the LLM can't corrupt the document.
  • See PLAN.md for the design rationale and decisions.

Install

cargo install reins   # the installed command is `rein`

Or from source:

cargo install --path .

The crate is published as reins (the singular rein was taken); the command you run is rein. Requires git. GitHub integration (issue/pull/push, etc.) requires the gh CLI.

Concepts

  • store: a per-repo local store (~/.local/share/rein/<key>/). The key is a UUID that rein init writes to git config rein.store, so the store is immune to worktree and directory moves, and living outside the repo means task docs are never committed by accident. Override the location with REIN_ROOT.
  • state = directory: inbox/active/done/YYYY-MM/, plus canceled/. The status in frontmatter is derived.
  • item IDs: the <!-- task:N --> on a checklist item is a stable integer assigned once and kept (not a line number). The tool assigns it whenever it touches the document, and rein check <N> uses that number.
  • task resolution order: --task <id> → worktree pointer → REIN_TASK → the store's current file.

Workflows

A. Solo, local (the basics)

rein new "settings cleanup"   # create a draft in inbox (prints id + path)
rein open settings-cleanup    # write Goal/Tasks/Validation in $EDITOR
rein start settings-cleanup   # inbox → active, sets current to this task

Then hand it to Claude Code; following the skill rules, the LLM proceeds:

rein todo                     # list remaining unchecked items (skill entry point)
rein check <item-id>          # check off a completed item
rein log "implementation note"
rein fail <item-id> --reason ""   # record a blocker when stuck

When done:

rein done                     # active → done/YYYY-MM/ (clears current)

You don't have to add <!-- task:... --> IDs by hand — the tool assigns them (check needs an ID).

B. Parallel worktrees (Claude Code multi-agent)

rein start feat-a --worktree  # creates ../proj-wt/feat-a + branch rein/feat-a
rein start feat-b --worktree

Each worktree is bound to its own task, so an agent just runs commands from its own cwd:

cd ../proj-wt/feat-a && rein current   # → feat-a (resolved from cwd)
cd ../proj-wt/feat-b && rein check x   # → edits only feat-b, no cross-talk

Clean up explicitly from the parent session (rein done feat-a / rein cancel feat-b --force). Running a mutation without a task in the main repo is blocked by a guard when two or more tasks are active — pass --task or run it from the right worktree.

C. GitHub shared inbox / PRs

rein issue settings-cleanup   # publish a GitHub issue (rein label, marker-wrapped)
rein pull-inbox               # import rein-labeled issues (idempotent)
rein pull                     # apply remote issue-body changes
rein push                     # push local changes into the issue/PR managed section

Only the managed section between the rein:begin/rein:end markers is updated on the remote body; human text outside the markers is preserved. Conflicts are detected by a 3-way hash, backed up under conflicts/, and force-pushed with rein push --resolved after you resolve them. Attach a PR with rein start … --draft-pr or rein attach-pr <n>, then update it with rein push (the Agent Log folds into a <details>).

TUI (rein ui)

A single dashboard across all your projects. Launched inside a repo, it pre-scopes to that project; press P to pick another.

key action
j/k move
Tab cycle status (all/inbox/active/done/canceled)
P pick project (project > task hierarchy)
Enter edit in $EDITOR
n new task
s start (inbox → active)
m move to any state (i/a/d/c)
d done
p publish issue or push
/ filter (matches project name too)
q quit

Editing is always delegated to $EDITOR — there is no built-in Markdown editor in the TUI.

Command summary

rein init [--skill]                  create the store + register git config rein.store (--skill: scaffold SKILL.md)
rein new <title> [--shared]          create a task draft in inbox
rein list [--status <s>]             list tasks
rein todo [--all] [--task <id>]      resolved task's unchecked items (--all: all items + state)
rein open [task]                     open in $EDITOR (fuzzy picker with no argument)
rein current [--path]                print the resolved task (read-only)
rein use <task>                      switch the task binding (worktree pointer / current file)
rein move <task> <status>            move to any state (plain relocation, no side effects)
rein start <task> [--worktree] [--branch <b>] [--draft-pr]
rein check / uncheck <item-id> [--task <id>]
rein log <text> [--task <id>]
rein fail <item-id> --reason <text> [--task <id>]
rein issue <task> | pull-inbox | pull | push [--resolved]
rein attach-issue <n> | attach-pr <n>
rein done [task] [--keep-worktree]
rein cancel [task] [--keep-worktree] [--force]
rein doctor                          rebuild state/, fix frontmatter drift
rein status | root | ui

LLM integration (Claude skill)

rein init --skill   # scaffold .claude/skills/run-rein-task/SKILL.md

The skill gets remaining items via rein todo and changes state only through rein check/log/fail (never editing the Markdown directly). The full rules live in the scaffolded SKILL.md.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages