Skip to content
open tomato/ rafa
GitHub
rafa pages
  1. rafa
  2. rafa stretch

rafa stretch

Open a stretch with its integration branch and operators, run one item through plan, loop and merge, and end it into main.

WARN

Stretches and their operators are alpha: tested on rafa's own development, and the files and steps may change between versions.

rafa stretch runs a batch of issues on one integration branch, stretch/<n>, and lands the batch into the default branch at once. Stretches walks the whole flow; this page is the reference for each action.

Spends: 🪙 start, one session per operator it starts; item, one planning session and the loop it starts. end starts none. --dry-run on each prints every step and runs none. Changes: pushes stretch/<n>, sets pr.base to it and back, writes under .rafa/stretch/<n>/, merges item pull requests into the stretch branch, opens the stretch's pull request. Needs: gh with push access and Claude Code; tmux to open the three operators in one session (without it, start runs the engineer in this terminal and prints the lines for the other two); see Prerequisites.

NOTE

In the target layout this code's package is not decided yet: the migration places it in a later pass (#801). In 0.47.0 it lives in the root package's src/. Either way it ships inside @open-tomato/rafa. [TBD: target package]

Actions

ActionDoes
startopen a stretch: push stretch/<n>, point pr.base at it, copy the operators and start them in tmux 🪙 unless --dry-run
itemplan one issue of a stretch and start its loop, logging into the stretch folder 🪙 unless --dry-run
endopen the stretch branch into the default branch, then put pr.base back once it has merged

rafa stretch start

Open a stretch: push stretch/<n>, point pr.base at it, copy the operators and start them in tmux.

rafa stretch start [-n=<number>] [--remote-control] [--role=<string>]
  [--dry-run]

Opens the next stretch, or --n: refuses while a stretch of the project is live or a loop of it runs, then fetches the default branch, pushes it to stretch/<n> on origin, records the pr.base it found in .rafa/stretch/<n>/stretch.json and sets pr.base to stretch/<n> with every comment kept, copies the operators from the installed package into .rafa/stretch/<n>/operators/ once and prints the rafa version they came from, and opens the engineer, watchtower and analyst in the tmux session stretch-<project>-<n>. Without tmux it starts the engineer in this terminal and prints the lines for the other two. --role starts that one operator session here and nothing else, which is what each tmux window runs. --dry-run prints every step in order and runs none. Exit code 1 for a refusal, 2 for a step that failed, naming the steps already done.

Spends: 🪙 unless --dry-run: one session per operator it starts

FlagType and defaultWhat it does
-nnumberThe stretch number; the next one when left out.
--remote-controlbooleanStart each session with Remote Control, so another device drives it from claude.ai.
--rolestringStart this one operator session here: engineer, watchtower or analyst.
--dry-runbooleanPrint every step in order, and run none of them.

Examples:

  • rafa stretch start --dry-run: Prints the push, the pr.base edit, the copy and the tmux lines.
  • rafa stretch start: Opens the next stretch and attaches to its tmux session.
  • rafa stretch start --role=watchtower --n=5: Starts the watchtower of stretch 5 in this terminal.

Output formats: text.

rafa stretch item

Plan one issue of a stretch and start its loop, logging into the stretch folder.

rafa stretch item <issue> [--wait] [--dry-run]

Takes the integration branch from pr.base, refusing one that names no stretch/<n> branch, then runs rafa plan create --issue=<issue> on this terminal, keeping a plan of the issue already in plan.dir instead, and starts rafa loop start --plan=<plan> --as-worktree --no-ci-wait detached with RAFA_OUTPUT=events, its output appended to .rafa/stretch/<n>/loop-<issue>.log. It waits for the loop's session record and prints its id. With --wait it then runs rafa loop wait --session-id=<id>; once the loop has opened a pull request it refuses one whose base is not a stretch/* branch, runs rafa pr merge <pr> --skip-checks --yes, waits for the run on the merge commit to end, appends the item to .rafa/stretch/<n>/items.ndjson and prints the pit-stop readings. A loop that opened no pull request has its reason printed, merges nothing and exits with loop wait's code. --dry-run prints every step in order and runs none. Exit code 1 for a refusal, 2 for a step that failed, and the code of plan create, loop wait or pr merge when it fails.

Spends: 🪙 unless --dry-run: one planning session and the loop it starts

ArgumentTypeWhat it is
issuestring, requiredThe number of the type:spec issue to plan and run.
FlagType and defaultWhat it does
--waitbooleanWait on the loop through rafa loop wait, then merge its pull request into the integration branch with checks skipped, wait for CI and print the pit-stop readings.
--dry-runbooleanPrint every step in order, and run none of them.

Examples:

  • rafa stretch item 812 --dry-run: Prints the plan create line and the detached loop line.
  • rafa stretch item 812 --wait: Plans #812, starts its loop, waits on it and merges its pull request.

Output formats: text.

rafa stretch end

Open the stretch branch into the default branch, then put pr.base back once it has merged.

rafa stretch end [--dry-run]

Ends the stretch pr.base names, refusing a pr.base that names no stretch/<n> branch and a stretch with no .rafa/stretch/<n>/report.md. Run before the merge, it writes the report with every Closes line of the item ledger appended to .rafa/stretch/<n>/pr-body.md and opens stretch/<n> into the default branch through the pr open logic, printing the pull request already open from it instead when there is one. Run once that pull request has merged, it sets pr.base back to what .rafa/stretch/<n>/stretch.json recorded, with every comment kept. --dry-run prints every step in order and runs none. Exit code 1 for a refusal, 2 for a provider that is not gh or a file that could not be written. Starts no session.

FlagType and defaultWhat it does
--dry-runbooleanPrint every step in order, and run none of them.

Examples:

  • rafa stretch end --dry-run: Prints the body file and the pr open line, or the pr.base edit after the merge.
  • rafa stretch end: Opens stretch/<n> into the default branch; run again after the merge to put pr.base back.

Output formats: text.