Commands

Every subcommand the parser accepts, in the order it defines them, with the flags that belong to each. For the order you would meet them in a day’s work, read usage.

Accepted everywhere

-h, --help
print help; accepted by the root command and by every subcommand.
-V, --version
print the version; the root command only.

lane init

scaffolds .lane/, adds the union merge rule, writes the AGENTS.md protocol, and probes reflink support.

Takes no flags of its own.

$ lane init
wrote /w/proj/AGENTS.md protocol
initialized .lane/, union merge rules, AGENTS.md protocol
reflink on this filesystem: yes (reflink available)
commit hooks are current

lane new

creates a branch and a copy-on-write worktree under .lane/trees/, cloning everything git ignores by reference.

--base<ref>
ref the lane branches from; defaults to the repo's trunk.
--dirty
carry uncommitted work into the lane.
$ lane new fix-login
  reflink: yes (reflink available)
  1284 files cloned (612.4 MiB shared, 0 copied)
/w/proj/.lane/trees/fix-login

lane ls

lists every lane's landing state, dirty state, and pending note count.

--json
print the lane inventory as machine-readable JSON.
$ lane ls --json
[{"name":"agent-a","path":"/w/proj/.lane/trees/agent-a","branch":"agent-a","state":"open","dirty":false,"pending_notes":3}]

lane enter

changes directory into a lane. Or `switch` alias.

Takes no flags of its own.

$ lane enter fix-login
/w/proj/.lane/trees/fix-login

lane exit

changes directory back to the main worktree.

Takes no flags of its own.

$ lane exit
/w/proj

lane anchors

lists every canonical anchor in source order with its inclusive line range; @file is always present.

--json
print exact anchor, start, and end fields as machine-readable JSON.
$ lane anchors src/auth.rs
@file	1-8
fn verify	1-4
fn refresh	6-8

lane note add

records a pending finding; supplied text never prompts, while omitted text opts into the anchor selector and one-line prompt.

-a, --anchor<anchor>
what in the file the note is about; defaults to @file.
$ lane note add src/auth.rs -a "fn verify" \
    "must stay constant-time; early return leaks length"
noted -> src/auth.rs#fn verify

lane note edit

shows a live note and interactively chooses one lifecycle action: confirm, replace text, retire, or toggle pinning.

Takes no flags of its own.

$ lane note edit 01M0B4KQTX
Editing 01M0B4KQTX7H3EZ8FE7S6BJ91N
  src/auth.rs#fn verify
  status: content-changed
  must stay constant-time
Action:
  1. confirm — still true
  2. replace — change the text
  3. retire — no longer applies
  4. pin — protect from eviction
Choose [1-4]: 1
confirmed -> 01M0B4KQTX7H3EZ8FE7S6BJ91N

lane note replace

queues a successor that inherits the live predecessor's path and anchor; promotion retires the predecessor.

-p, --path<path>
override the predecessor's path.
-a, --anchor<anchor>
override the predecessor's anchor.
$ lane note replace 01M0B4KQTX "constant-time; no early return"
replacement queued -> 01M0B4KQTX7H3EZ8FE7S6BJ91N src/auth.rs#fn verify

lane note confirm

re-vouches for a drifted live note and refreshes its fingerprint.

Takes no flags of its own.

$ lane note confirm 01M0B4KQTX
confirmed -> 01M0B4KQTX7H3EZ8FE7S6BJ91N

lane note retire

moves a live note to the attic without rewriting its bytes.

Takes no flags of its own.

$ lane note retire 01M0B4KQTX
retired -> 01M0B4KQTX7H3EZ8FE7S6BJ91N

lane note restore

moves a retired note back to live memory without rewriting its bytes.

Takes no flags of its own.

$ lane note restore 01M0B4KQTX
restored -> 01M0B4KQTX7H3EZ8FE7S6BJ91N

lane note pin

protects a live note from missing-anchor and budget eviction.

Takes no flags of its own.

$ lane note pin 01M0B4KQTX
pinned -> 01M0B4KQTX7H3EZ8FE7S6BJ91N

lane note unpin

removes eviction protection from a live note.

Takes no flags of its own.

$ lane note unpin 01M0B4KQTX
unpinned -> 01M0B4KQTX7H3EZ8FE7S6BJ91N

lane why

prints the notes for a path in compact form, or for every path beneath it when the path is a directory. A pure read; it changes nothing.

-a, --anchor<anchor>
show only the notes on this anchor.
--json
print full note fields as machine-readable JSON.
$ lane why src/auth.rs --json
[{"id":"01M0B4KQTX7H3EZ8FE7S6BJ91N","path":"src/auth.rs","anchor":"fn verify","created":"2026-08-19T00:00:00Z","note":"must stay constant-time"}]

lane check

counts the notes in each staleness tier, lists the ones that are not fresh under their tier, and exits 1 if any anchor is missing.

--json
print each note as JSON, with current spans on non-fresh work items.
$ lane check
fresh              7
content-changed    1
contract-changed   0
anchor-missing     0
unverifiable       0

[content-changed]
~ 01M0B4KQTX  src/auth.rs#fn verify

lane audit

promotes pending notes, re-anchors across renames, reports drift, ranks what is left, and evicts whatever is over budget.

--base<ref>
ref to diff against for touched paths and rename detection; empty by default.
--max-notes<n>
keep at most this many notes per path and anchor; default 5.
--max-chars<n>
keep at most this many characters per path and anchor; default 1200.
--json
print the outcome as JSON instead of the report.
$ lane audit
memory: +2 new; checked 8: 7 fresh, 1 content-changed,
        0 contract-changed, 0 missing
  drift   src/sync.rs#fn reconnect

lane merge

rebases the lane onto its base, audits memory, commits it, fast-forwards the base, and removes the lane.

--base<ref>
ref to rebase onto and advance; defaults to the lane's recorded base.
--keep
keep the lane worktree and branch after landing.
--squash
squash the lane's commits into one landing commit.
--max-notes<n>
keep at most this many notes per path and anchor; default 5.
--max-chars<n>
keep at most this many characters per path and anchor; default 1200.
$ lane merge
rebased onto main
memory: +2 new; checked 8: 7 fresh, 1 content-changed,
        0 contract-changed, 0 missing
committed memory update
fast-forwarded main
removed lane fix-login

lane push

rebases the lane onto its base, audits and commits memory, then pushes it for a pull request.

--base<ref>
ref to rebase onto; defaults to the lane's recorded base.
--max-notes<n>
keep at most this many notes per path and anchor; default 5.
--max-chars<n>
keep at most this many characters per path and anchor; default 1200.
$ lane push
rebased onto main
pushed fix-login to origin

lane prune

removes every lane that has landed in trunk, seen through a squash or rebase merge, skipping any that is dirty, holds work trunk does not have, or is the directory you are in.

--dry-run
list what would go, remove nothing.
$ lane prune
removed fix-login
skipped rate-limit: uncommitted changes

lane rm

discards a lane without landing it, keeping the branch if it holds commits trunk does not have.

--force
discard commits trunk does not have.
$ lane rm keeper
removed lane keeper; kept branch keeper, it has
commits main does not
  git worktree add <path> keeper   to get back
  lane rm keeper --force           to discard

lane install hooks

installs the post-commit and prepare-commit-msg hooks that capture Why: trailers.

Takes no flags of its own.

$ lane install hooks
installed .git/hooks/post-commit
installed .git/hooks/prepare-commit-msg

lane install skill

writes the lane skill, which teaches an agent the daily loop, to .agents/skills/lane/SKILL.md.

Takes no flags of its own.

$ lane install skill
installed /w/proj/.agents/skills/lane/SKILL.md

lane uninstall hooks

removes lane's block from the post-commit and prepare-commit-msg hooks.

Takes no flags of its own.

$ lane uninstall hooks
removed lane block from .git/hooks/post-commit
removed lane block from .git/hooks/prepare-commit-msg

lane uninstall skill

deletes the installed skill file at .agents/skills/lane/SKILL.md.

Takes no flags of its own.

$ lane uninstall skill
removed /w/proj/.agents/skills/lane/SKILL.md

lane shellenv

prints the shell function that makes new, cd and merge leave you in the right directory.

Takes no flags of its own.

$ eval "$(lane shellenv)"
$ lane shellenv
lane() {
  local p
  case "$1" in
    new|enter|switch|exit) p=$(command lane "$@") || return; cd "$p" ;;
    merge) p=$(command lane exit) || return; command lane "$@" || return
           cd "$PWD" 2>/dev/null || cd "$p" ;;
    *)     command lane "$@" ;;
  esac
}

lane capture

reads Why: trailers from one commit and queues them as pending notes. Hidden, and run for you by the post-commit hook.

Takes no flags of its own.

$ lane capture HEAD
captured -> src/auth.rs#fn verify