Lanes
GitHub

How it works

How Lanes works: leases, sync and shared context

In shortEach agent runs a small hook before and after every edit. Before an edit, the hook takes a one-edit lease on the file from the Lanes server and waits in a queue if a teammate holds it. After the edit, it commits the change as the person who owns the agent and pushes it to a shared branch, lanes/main, on your own git remote. With team context on, the server also gives each agent a short brief at each prompt and a heads-up before it touches a file a teammate is changing.

Updated 2026-11-12 · Lanes 0.3.0 · Source on GitHub

The pieces

Lanes has four parts that run on your machines:

PartWhat it doesWhere it runs
The hook (.lanes/hook.cjs)Runs before and after each edit; takes leases, syncs, commits and publishesInside each agent, on each developer's machine
The serverHolds leases, the queue, tasks, the team chat and requests; sends one snapshot per change to every open viewOne machine per team, or each laptop when working alone
The CLI and MCP server (lanes.cjs)Set up a repository, run the team tools, give agents the same view people haveEach developer's machine
The viewsVS Code sidebar, browser app, status lineWherever people look

lanes init copies the hook into the repository and commits it, so every teammate and every worktree gets the same setup when they pull.

One edit, step by step

Here is what happens when Bea's agent edits src/session.ts while Ana's agent is changing it.

  1. Before the edit. Claude Code calls the hook with the file path. The hook turns the path into a repository identifier and a repo-relative path, then asks the server for a lease on src/session.ts.
  2. The queue. Ana's agent holds the lease, so Bea's request waits. Claude Code shows "Lanes: coordinating with teammates…" in its status line. Ana's edit finishes and is published, and the server hands the lease to Bea.
  3. The sync. Before Bea's edit goes ahead, the hook fetches lanes/main and brings Ana's version of the file into Bea's checkout. If the file changed under Bea's agent, the agent is told to read it again.
  4. The edit. Bea's agent edits the current version of the file. Nothing was refused, and the agent did not ask Bea anything.
  5. After the edit. The hook commits only the file the agent changed, authored as Bea, with the task title and the agent's session in the commit trailers. It fetches, rebases and pushes to lanes/main. Git refuses a push that is not a fast-forward, so the push itself decides who was first; a refused push is fetched, rebased and retried.
  6. The release. The hook tells the server the edit is published, and the lease goes to the next agent in the queue.

A free file skips step 2. On a free file, the check in step 1 takes 39 ms on Linux and 68 ms on Windows at the 95th percentile, including process start.

Why every edit becomes a commit

Lanes saves each edit as a commit on the agent's branch, authored by the person who owns the agent. That gives three things git already understands: git blame shows who changed each line, a sync is an ordinary rebase, and no edit can be lost because it is committed before anything else happens.

Many small commits are tidied when you open a pull request: lanes pr squashes one task's commits into a branch with a Co-authored-by line per contributor.

Shared team context

Leases stop two agents from writing one file at the same moment. They cannot stop an agent from calling a function that a teammate is renaming in a different file. That needs context, so Lanes adds three things when a team runs lanes team on.

The brief at each prompt

When a person sends a prompt, the hook asks the server for a brief and adds it in front of the prompt:

Lanes team context. Teammates' agents in this repository right now: Ana: "Rename getUser to fetchUser" (src/session.ts, src/auth/oauth.ts). Message from Ana in the team chat: "@bea the rename lands in ten minutes". This is for awareness; it needs no action or confirmation from you or the user.

The brief is capped at 2,000 characters. When there is more, the overview is cut first and approved requests are kept.

The heads-up before a read or an edit

When an agent is about to read or edit a file a teammate's agent changed or is expected to change, the hook adds one line:

Team note about "src/session.ts": Ana's agent, working on "Rename getUser to fetchUser", changed lines 12 to 30 a minute ago. If your code uses this file, write it to match that change rather than the version you see now.

For edits, when both sides' changed lines are known, the heads-up comes only if the changes are within a few lines of each other.

The check at the end of a turn

In Claude Code, when an agent's turn ends and a file it read changed under it, or a teammate's new file imports a file it changed, the agent is told once so it can check its work.

Requests between agents

lanes ask bea "Explain how session expiry works" sends a request to Bea's agent. It waits until Bea approves it in VS Code, the browser app or with lanes approve. Then Bea's agent gets it with her next prompt, or lanes approve <id> --run runs it right away with Bea's own Claude Code or Codex and sends the answer back.

A request is read-only unless the sender passed --edit. A request that may edit runs on its own branch, lanes/request-<id>. The MCP server has no approve tool, so an agent can never approve a request on a person's behalf.

What the server sees

The server receives repository identifiers, repo-relative file paths, display names, session identifiers, statuses, task titles, the team chat and requests. It never receives file contents. A task title is the first line of a prompt, cut to 120 characters with known secret patterns removed; LANES_NO_PROMPT_TEXT=1 replaces it with "Agent task". More on the security page.

When something goes wrong

Lanes is built to fail open. A server that does not answer, a sync that fails or a remote that cannot be reached never blocks an edit. The edit is committed locally and published later. The status bar shows "Lanes: offline", the views flag the problem, and lanes doctor checks Node, git, the hooks, the server and your token and says what to fix.

Questions

How long does an agent wait for a file?

Usually about a second, because a lease lasts one edit. The hook waits at most 240 seconds and then lets the edit go ahead anyway. In the scale test with 64 agents hammering two hot files, waits grew long; real agents edit far less often.

What if the Lanes server is down?

The hook lets every edit go ahead and commits it locally, so nothing is lost. Coordination pauses, the status bar and the app say so, and the next publish sends the commits when the server and the remote are back.

Does Lanes merge code for me?

Lanes publishes each edit with git: fetch, rebase, push. If a rebase stops on a real conflict, Lanes keeps both versions, tells the agent to apply its change again on top of the new code, and never resolves the conflict silently.

Is the agent told about Lanes?

Only what it needs. At session start the agent learns that each edit is saved as a commit automatically. With team context on it gets the brief and heads-ups. It is never told to stop, wait or ask its user.