Repository navigation
v0.15.0
v0.15.0 collects the 0.14.11–0.14.20 cycle into one release: a Task can now be handed off and left to finish. One Graph carries it from first step to merged PR, lf ship or Auto-Ship lands it, and it can run on a Machine you own or one you rent. Two people can share a repository without crossing claims or branches. The store has been cut down to facts, so installs, live views and idle processes stop slowing down as history grows. Each Wave's setup now lives in one committed file, with lf set for your own overrides. This release changes the store format: lf < 0.15.0 can no longer open the store (raised by: wave_setup). Upgrade every lf that shares ~/.lf together, including the macOS app.
Hand a Task off and let it finish
The cycle started with three overlapping models of a Task's progress: Flows, Workflow stages and routes, and per-Task automation holds for CI. It ends with one. Flow became Graph everywhere (#1643). Workflows then folded into the Graph file itself, which now says where a person takes part (#1733). Bare lf task run returns once the Graph is running (#1675), and lf ship runs the rest of it through CI repair and merge (#1652).
- One Graph per Task. A Task captures one Graph and its position in it.
interactive:steps run in place underlf graph. Underlf task run, the run stops before them and the Task waits in its conversation.-i/-bchoose for every step, and--from <step>starts anywhere. A Task with no Graph takes its Wave's default, then repositorygraph:, then builtincode. (#1733) - Runs leave your shell.
lf task runreturns once the Graph registers.lf -b task runstill waits.lf task interruptnow stops a running Graph. It used to record a request that nothing acted on. (#1675, #1678) - Steps default to headless. A Graph started from a terminal no longer opens every step as a conversation. Headless Claude steps stay alive until any commands they backgrounded have finished. (#1628, #1688)
- Ship in one move. Click Auto-Ship or run
lf ship, and Loopflow runs the remaining steps, repairs CI, merges the PR and completes the Task. A route intoendalso approves Auto-Ship. A two-tier approval that briefly stopped this (#1736) was reverted (#1741).lf ship --stopwithdraws approval. (#1652, #1741) - Agents handle conflicts themselves. A PR that conflicts with or falls behind
mainis synced and resolved by the agent; it no longer goes to a person as ready for review. Graphsynckeeps branch commits and checkpoints uncommitted edits before merging, so conflicts reach the resolver rather than a stash. (#1624, #1672, #1748) - Choose a direction before building. The feature Graph starts at
explore. It lays out several visions as pages you can read in Desktop's Files view, so you pick one before any code is written. (#1687) - Finished work goes quiet. Completed and abandoned Tasks with old failed runs no longer ask for attention. Completed Tasks stay complete through Linear rate limits and unrelated edits. (#1621, #1742)
Set up a Wave once
Setting up an area of work used to take a separate command for each setting, split between GOAL.md frontmatter and the store, and nothing showed which value a launch used. (#1751)
- Committed Wave config.
.lf/wave/<name>/config.yamlhas the same shape as.lf/config.yamland holds only what the Wave changes:graph,agent,skill_agents,context_budgets, plus the Wave'sid,linear.initiativeandchat. Launches in a Wave layer it over the repository's config and~/.lf/config.yaml. Repository-only keys are an error there. (#1751) lf set <key> <value>andlf unset <key>store your own values on this Machine and never edit committed config. They apply to this repository by default, to a Wave withlf --wave <wave> set, or everywhere with--global. Keys aregraph,agent,skill_agents.<skill>,machine,machine.tasks,machine.sessionandaccount.<provider>. (#1751)lf wave statusshows each setting and where it came from. (#1751)- Removed:
lf wave graph set(usegraph:in the Wave'sconfig.yaml, orlf --wave <wave> set graph),lf ops machine use(uself set machine) andlf account route set(uself set account.<provider>). (#1751)
Land PRs without babysitting the merge queue
Landing and release each guessed why a PR's auto-merge had disappeared, and they guessed in opposite directions. Now only a person removing the merge request stops them (#1680). Every other kind of removal gets repaired.
- Removals Loopflow makes itself during CI repair, and drops by GitHub's merge queue, are repaired instead of read as withdrawal.
lf landno longer drops the request on PRs that are already green. (#1673, #1679, #1684) - CI repair and sync run alongside an open Session in the Task checkout, and sync no longer holds its lock across network fetches or conflict resolution. (#1714)
lf landmergesmainonly when GitHub or the queue requires it. Other repairs push on top of the base CI already tested. (#1749)- Rust-only PRs skip hosted macOS runners. macOS jobs run once per PR, and only when the PR's paths can affect them.
mainis tested after merge, and a failure is bisected to open an unarmed revert PR. (#1646, #1749)
Run work on a Machine you own or one you rent
Tasks used to run where they started. Now each has a single owner: a person on a Machine, or nobody. That owner can be claimed, handed to another Machine or released (#1610). A Task can also go to free capacity and come back with its history.
- Ownership is explicit. Claims follow the repository's Git
user.emailrather than display names. Moving a Task to another of your Machines carries its conversation, which is no longer completed on the way. (#1610, #1651, #1720) - Rent capacity.
lf task run --pool lab --rent codesends a Task to a free owned Machine or rents one, and gives it back with its history afterwards (#1653). By the end of the cycle the providers are Daytona, Modal, RunPod and AWS, with GPU and spot options where the provider has them. A Wave can send its Tasks to rented machines by default. (#1704, #1707) - Fly is gone. Fly arrived in #1707 and was removed in #1743. AWS rentals now use a pinned region, a working Claude login, a Git identity for claims, and Linear planning. (#1743)
- Fresh Linux machines work. Claude, Codex, OpenCode and Pi run on a newly rented Linux box. The fixes cover OpenCode login forwarding, Pi startup, Codex under Ubuntu's default umask, and npm-installed agents over SSH. (#1649)
- Conversations move with their history.
lf resumemoves a conversation to another login or Machine with its native history intact. Open Codex conversations are pinned to their login so a move finds them, and the terminal a conversation left closes and says where it went. (#1720, #1740, #1746) - Launch on the account with the most room. Shared-mode Claude and Codex launches pick the account with the most remaining usage. They no longer stay on the signed-in account until it reaches 95%. (#1717)
Share a repository with someone else
Before this cycle, two people in one repository saw separate plans, and a takeover opened a new branch and PR. Now they share one plan and one branch per Task.
- Git planning defaults to the shared ref
refs/loopflow/planning/shared/mainonorigin. (#1639) - A takeover keeps the Task's branch and PR. Comments and crons stay with the person who owns them. (#1651)
repo-operateandwave-operatework only on your own existing Tasks. They no longer edit plans, file Tasks or reach into other people's work. (#1642)- Asana and Notion can be a repository's tracker as well as Linear, set in
.lf/config.yaml. (#1607) - Briefs for new Tasks name any open PRs already rewriting the same files. (#1682)
- The website, README and docs now lead with building software together and with what
lfdoes for you. Reference detail has moved into the docs. (#1637, #1671)
Desktop shows the work you're doing
Desktop used to treat opening a Task and arranging panes as the same act. Its views also re-rendered and re-read far more than they displayed.
- Dashboards and a working sidebar. Saved Dashboards put Tasks side by side, and pane layouts and drafts survive relaunch. At every scope the sidebar lists only started Tasks of the selected Wave or Dashboard, and ⌘1–9 follow those rows. (#1580, #1660, #1669, #1703)
- Wave standup board. A Wave opens as one board beside its conversation, showing what's waiting, in progress, shipping and landed. (#1705)
- Less churn. Scrolling and hovering no longer re-render every row and tile. The Files view no longer re-reads itself from the journal trace it causes. Each Desktop part runs its own
--watchread over open Tasks. (#1641, #1660, #1719) - Scriptable from
lf desktop. Agents can arrange panes and read back the result, and exit status distinguishes a missing pane from an unreachable Desktop.lf desktopandlf openaddress the Desktop they run inside, Loopflow Dev included. (#1664, #1677) - Checked against real data. Every public Desktop read decodes output from a source-built
lf-world, so a Rust wire change can't silently break a screen. (#1619, #1617, #1640)
A smaller, cheaper store
On Jack's store (about 10 GB, 943k processes, 2.7M session events), lf install took minutes, idle relays burned CPU scanning Sessions nobody watched, and a single live reader cost about 48 s of CPU per minute. The store now keeps only the facts Loopflow reads back.
- Facts only. The duplicate provider stream copy is gone. The store keeps one usage row per provider turn, and
events.jsonlis no longer written. Conversations are read from provider transcripts, andlf historyshows what a provider will remove next. (#1666, #1698, #1700, #1706) - Fewer Process rows. Hooks and Desktop polls no longer create Processes, and finished rows nothing references are deleted. Store retention is in
lf monitor prune. (#1667, #1718, #1744) - Faster opens and idle checks. Each store's schema is read once per process instead of on each of the ~17 opens per launch. Sessions are indexed by execution owner. Idle relays and the Desktop feed stop rescanning. (#1650, #1690, #1692)
--watchon ordinary reads.lf task list,lf task status,lf session list,lf wave show,lf psand more stream{answers, unavailable, body}lines and exit when their reader goes away. This replaceslf monitor work. (#1719)- Lock contention has a name.
lf.logandlf doctorname the process and binary holding the write lock. The hourly prune waits for the lock instead of failing, and usage updates no longer scansession_eventsunder it. (#1713, #1724, #1726)
Commands you can see and run
lf's root help listed about thirty unordered peer groups, and Graphs, Desktop and hooks drove it through hidden __ commands.
- Root help leads with Task, Wave, Session, Graph and Skill. Delivery, machine and account plumbing moved under
lf ops. (#1708) - Hidden commands became ordinary, documented ones, so
lf helpshows what Graphs and Desktop run. (#1697) - Undesigned surface was removed, including the public
lf transportgroup, the--create-pralias and cron-only global flags.lf skill customizewas added. (#1615) lf wave workflow,lf task workflow,lf graph route,lf monitor work,lf monitor activeandlf diskare gone. See Operational notes for their replacements. (#1719, #1733, #1744)
Sessions that behave in your terminal
lfkeeps your screen, scrollback and the "Continue with: lf resume …" hint. Warnings and diagnostics-path banners go to logs, not the terminal. (#1635, #1691)- Inside tmux,
lf openopens Work in tmux. A Session whose terminal closed reads as reconnectable, andlf connect <Task-ID>connects right away; it used to search provider history for about 26 s. (#1635, #1674) lf resumecontinues the last conversation in a worktree no Task, Wave or repository owns. (#1665)- An unviewed Session stops its agent after a day (
session.end_detached_after). (#1638) - Claude opens in lf-created worktrees without a folder-trust prompt. Steers and Task context keep arriving after
/clear. Codex Sessions receive Loopflow's context hooks again. (#1648, #1731, #1734) - Sessions started under an older
lfstay stoppable after an upgrade removes a hook they still call. (#1629, #1630) - A viewer whose execution owner stalls names the owner; it no longer dies with
EAGAIN. Steps whose agent exited under heavy load now finish. (#1644, #1689) - Selected documents (
--docs, config and skilldocs:) reach the agent as full bodies, matching preview and capture. (#1752)
Cleanup that keeps your work
Cleanup policy used to live in three places. Under some of those rules it could delete the only copy of committed work.
scripts/disk-cleanup.sh installruns an hourly cleanup skill from the main checkout.~/.lfrotates by age, after seven days, instead of chasing a 20 GB budget it could never meet. Idle ignored build output is reclaimed. (#1696, #1744)- Live caches like SwiftPM's are left intact, the uv cache lock no longer hangs cleanup, and staging directories from killed draft builds are removed. (#1628, #1633, #1727)
lf wt pruneremoves a checkout only when a merged or closed PR matches its exact local head. (#1753)lf synccheckpoints ordinary edits and leaves.lf/tmp/as it found it. That fixes automatic sync stopping partway on Apple Git 2.50.1. (#1754)
Operational notes
- Store floor. Releases in this cycle raised the store's minimum reader at 0.14.12, 0.14.15, 0.14.16, 0.14.17, 0.14.19 and 0.14.20. v0.15.0 raises it again: upgrade every CLI, Desktop helper and cron install that shares the store at the same time. A Wave graph chosen with
lf wave graph setlived inwaves.graph, which this release drops; addgraph:to the Wave'sconfig.yamlbefore upgrading to keep it. (#1751) - Find stale processes. Running Sessions and Graph runners keep the binary they started with.
lf monitor psshows which ones are behind, and idle Sessions can move to the new install. (#1729) - Update scripts.
lf wave workflow→lf wave graph.lf task workflowandlf graph route→lf task run,--fromandlf task status.lf monitor work→--watchon each read.lf monitor active→lf session list --watchwithlf ps --watch.lf disk→scripts/disk-cleanup.shandlf monitor prune. Plumbing commands now live underlf ops. (#1708, #1719, #1733, #1744) - Repository
workflow:is still accepted as an alias forgraph:. LOO-637 tracks its removal. (#1733) - Old records still read. Task events recorded as
flow_finishedand Graph records that usehumanboth still load after the renames. Cron jobs installed by 0.14.14 with--flowkeep running. (#1655, #1668, #1722) - Release and cron host. Rerun
scripts/bootstrap-cron-host.sh. It retires leftover launchd agents, accepts a Wave with no Machine default, and keeps crontab commands under cron's 999-byte limit. (#1711, #1732, #1738) - Release run.
lf release runbuilds fixes merged after an unbuilt release PR, and repair cuts no longer fail promotion over an existingBREAKING.md. A release stops when someone takes its PR out of the queue. Hotfixes promote from a plain release build and are labeled as hotfixes; thehotfixskill describes how. (#1661, #1662, #1668, #1712, #1730) - Install cleanup. Run
scripts/disk-cleanup.sh installand check the cron entry. Checkouts lost to the old pruning rules are not recovered, and checkouts with no matching PR now need explicit disposal. (#1744, #1753) - macOS regressions surface after merge. A PR the classifier skipped can break macOS on
main. The revert PR the bisect opens is unarmed, so someone has to merge it. (#1749)
Small changes
- Rust tests no longer write test logins into your real Codex or Claude home. (#1693)
- Each provider has one decoder and one writer for what it records. (#1702)
- Agent ancestry that was never recorded is repaired, and
lf self doctorpasseslineageagain. (#1747) - cmux workspaces are named
<Task title> · …and keep names you set by hand. (#1716) - Gate and implement run only the tests a change reaches, one build at a time. PRs fail when their tests run too long and name the slow ones. Swift tests fail on a leaked continuation. (#1647, #1683, #1745)
lf-worldSwift tests were removed until world builds are fast (LOO-564). The Swift 6.2.3 release-optimizer crash is avoided. (#1645, #1699)lf wt prune --brancheskeeps its protections and summary in one place.lf syncborrows its plan instead of cloning it. (#1626, #1676)TESTING.mdsays to reproduce races by delaying or repeating tests, never by loading the CPU. (#1686)- The Desktop workspace drops its outer border and squares its top corners. (#1728)
- ruff 0.17.1. (#1657)