/lanes-sessions
Use when managing Lanes issues or driving Claude Code sessions through the lanes_* MCP tools: creating issues, starting/stopping/inspecting sessions, batch-launching work across worktrees, reading terminal output, attaching labels and components by UUID, or moving issues between
Claude Code
$ npx -y skills add lanes-sh/app --skill lanes-sessions --agent claude-code
Codex
$ npx skills add lanes-sh/app --skill lanes-sessions -a codex -y
Cursor
$ npx skills add lanes-sh/app --skill lanes-sessions -a cursor -y
Gemini CLI
$ npx skills add lanes-sh/app --skill lanes-sessions -a gemini-cli -y
GitHub Copilot
$ npx skills add lanes-sh/app --skill lanes-sessions -a github-copilot -y
OpenCode
$ npx skills add lanes-sh/app --skill lanes-sessions -a opencode -y
Windsurf
$ npx skills add lanes-sh/app --skill lanes-sessions -a windsurf -y
SKILL.md
lanes-sessions.SKILL.mdname: lanes-sessions
description: Use when managing Lanes issues or driving Claude Code sessions through the lanes_* MCP tools: creating issues, starting/stopping/inspecting sessions, batch-launching work across worktrees, reading terminal output, attaching labels and components by UUID, or moving issues between the board's statuses (backlog, planning, implementation, review, done, or ones the user added, such as todo). Skill applies whenever a request mentions "Lanes", "lanes board", "lanes issue", "lanes session", or any lanes_* tool name. Also applies when Claude Code is itself running inside a Lanes session (`LANES_TERMINAL=1`, `LANES_SESSION=<issue id>`). Every worktree you create must be linked to the issue with lanes_update_issue, or the issue's Changes tab points at an empty diff instead of at your work.
Lanes sessions
Lanes is a desktop app that puts every AI coding session on an issue board. It exposes a local MCP server (SSE on `http://localhost:5353/sse`) with a set of `lanes_`-prefixed tools for issue CRUD, session orchestration, history, and metadata lookups.
A single issue can host **multiple concurrent CLI sessions** (Claude, Codex, shell). Session-targeting tools take an optional `session` ref (UUID, auto-assigned slot, or name) to pick which one — see the "Multi-session model" section below.
Use this skill whenever the user wants to look at, create, or run work on the Lanes board through chat.
Verify the MCP is connected
Before doing anything, sanity-check that the Lanes MCP is reachable:
- Call `lanes_list_components`. If it returns an array (possibly empty), you're good.
- If the tool isn't available at all, the MCP isn't installed. Tell the user to run the `/lanes-desktop:setup-mcp` slash command (shipped alongside this skill) or, if they have raw skills only, run:
claude mcp add --transport sse lanes-desktop http://localhost:5353/sse --scope user
Then restart Claude Code so the new MCP loads. Lanes itself must also be running (the desktop app must be open).
Working inside a Lanes session
Everything else here assumes you are driving the board from outside. When Lanes launched *you*, three environment variables say so:
| Variable | Meaning | |---|---| | `LANES_TERMINAL` | `1` when Lanes spawned this shell. Unset means this section does not apply. | | `LANES_SESSION` | The **issue ID** you are working on. This is what to pass as `id` / `issueId`. | | `LANES_SESSION_UUID` | This session's Lanes ref, for the `session` param. |
Read them with `echo $LANES_SESSION`. If `LANES_TERMINAL` is unset you are an ordinary Claude Code session with no issue to report against, so skip to the tool inventory.
Link every worktree you create
**Every `git worktree add` you run is followed by `lanes_update_issue { id: $LANES_SESSION, branch: "<branch>" }`.** Not conditionally, not once you are finished. A worktree Lanes did not create is a worktree the issue does not know about, and until you link it the Changes tab and `lanes_get_issue_changes` both show an empty diff, so your work reads as never having happened.
Setting `branch` is the whole job. Lanes finds the worktree that branch is checked out in and fills `worktreeStrategy`, `worktreePath` and `worktreeName` from it, so do not set those three yourself.
Then check it took:
lanes_get_issue { id: $LANES_SESSION }`worktreeStrategy` should be `"select"` and `worktreePath` should be the folder you are working in. If `worktreeStrategy` came back `"none"`, Lanes could not find a worktree for that branch. Call `lanes_list_worktrees`, find your folder in the list, and pass its `path`:
lanes_update_issue { id: $LANES_SESSION, worktreePath: "<path from the list>" }If your folder is not in that list either, you are in a repository Lanes has no working folder linked for, and there is nothing to link the issue to. Say so rather than retrying.
When Lanes started you inside a worktree it made, `lanes_get_issue` already reports `"create"` or `"select"` and there is nothing to do. Checking costs one call and is worth it before you assume.
Linking is not the same as asking for a worktree. `worktreeStrategy: "create"` only affects the *next* session on the issue and never relocates a running agent, so setting it mid-session will not move you.
Tool inventory
| Group | Tool | Purpose | |---|---|---| | Issues | `lanes_list_issues` | Filter by `step` / `tags` (any-match) / `componentId` / `search`. **Defaults are scoped**: at most 20, active project only, every Done status excluded. Pass `limit` (no upper bound), `allProjects: true`, or `includeDone: true` to widen. Filtering by a Done status includes it. Returns an envelope `{ issues, appliedFilters, truncated, totalAvailable }`, so check `truncated` before concluding a search found nothing. | | | `lanes_get_issue` | Full details by `id`. Does **not** include sessions. | | | `lanes_create_issue` | Required: `title`. | | | `lanes_update_issue` | Patch by `id`; pass `null` to clear nullable fields. | | | `lanes_delete_issue` | By `id`. Permanent. | | | `lanes_move_issue` | Shorthand for `update_issue` with only `step`. | | Sessions | `lanes_start_session` | Required: `issueId`. Spawns Claude Code (default), Codex, or `shell`. **Always adds a new session**; returns its slot + UUID. | | | `lanes_stop_session` | Stop a session for `issueId`. Optional `session` (UUID/slot/name) to disambiguate when >1. | | | `lanes_resume_session` | Re-attach Claude to a stopped session. **Claude-only.** Optional `session`. | | | `lanes_delete_session` | Permanently delete a session (stops it first if running). Optional `session`. | | | `lanes_get_session_status` | With `issueId`: bare array of every session for that issue (status under both `status` and `runtimeStatus`). Without: envelope `{ sessions, appliedFilters, truncated, totalAvailable }` capped at 20. | | History | `lanes_get_issue_changes` | `git diff` for the issue's cwd, by `id`. | | | `l
Read more
name: lanes-sessions description: Use when managing Lanes issues or driving Claude Code sessions through the lanes_* MCP tools: creating issues, starting/stopping/inspecting sessions, batch-launching work across worktrees, reading terminal output, attaching labels and components by UUID, or moving issues between the board's statuses (backlog, planning, implementation, review, done, or ones the user added, such as todo). Skill applies whenever a request mentions "Lanes", "lanes board", "lanes issue", "lanes session", or any lanes_* tool name. Also applies when Claude Code is itself running inside a Lanes session (`LANES_TERMINAL=1`, `LANES_SESSION=<issue id>`). Every worktree you create must be linked to the issue with lanes_update_issue, or the issue's Changes tab points at an empty diff instead of at your work.
Lanes sessions
Lanes is a desktop app that puts every AI coding session on an issue board. It exposes a local MCP server (SSE on `http://localhost:5353/sse`) with a set of `lanes_`-prefixed tools for issue CRUD, session orchestration, history, and metadata lookups.
A single issue can host **multiple concurrent CLI sessions** (Claude, Codex, shell). Session-targeting tools take an optional `session` ref (UUID, auto-assigned slot, or name) to pick which one — see the "Multi-session model" section below.
Use this skill whenever the user wants to look at, create, or run work on the Lanes board through chat.
Verify the MCP is connected
Before doing anything, sanity-check that the Lanes MCP is reachable:
- Call `lanes_list_components`. If it returns an array (possibly empty), you're good.
- If the tool isn't available at all, the MCP isn't installed. Tell the user to run the `/lanes-desktop:setup-mcp` slash command (shipped alongside this skill) or, if they have raw skills only, run:
claude mcp add --transport sse lanes-desktop http://localhost:5353/sse --scope user
Then restart Claude Code so the new MCP loads. Lanes itself must also be running (the desktop app must be open).
Working inside a Lanes session
Everything else here assumes you are driving the board from outside. When Lanes launched *you*, three environment variables say so:
| Variable | Meaning | |---|---| | `LANES_TERMINAL` | `1` when Lanes spawned this shell. Unset means this section does not apply. | | `LANES_SESSION` | The **issue ID** you are working on. This is what to pass as `id` / `issueId`. | | `LANES_SESSION_UUID` | This session's Lanes ref, for the `session` param. |
Read them with `echo $LANES_SESSION`. If `LANES_TERMINAL` is unset you are an ordinary Claude Code session with no issue to report against, so skip to the tool inventory.
Link every worktree you create
**Every `git worktree add` you run is followed by `lanes_update_issue { id: $LANES_SESSION, branch: "<branch>" }`.** Not conditionally, not once you are finished. A worktree Lanes did not create is a worktree the issue does not know about, and until you link it the Changes tab and `lanes_get_issue_changes` both show an empty diff, so your work reads as never having happened.
Setting `branch` is the whole job. Lanes finds the worktree that branch is checked out in and fills `worktreeStrategy`, `worktreePath` and `worktreeName` from it, so do not set those three yourself.
Then check it took:
lanes_get_issue { id: $LANES_SESSION }`worktreeStrategy` should be `"select"` and `worktreePath` should be the folder you are working in. If `worktreeStrategy` came back `"none"`, Lanes could not find a worktree for that branch. Call `lanes_list_worktrees`, find your folder in the list, and pass its `path`:
lanes_update_issue { id: $LANES_SESSION, worktreePath: "<path from the list>" }If your folder is not in that list either, you are in a repository Lanes has no working folder linked for, and there is nothing to link the issue to. Say so rather than retrying.
When Lanes started you inside a worktree it made, `lanes_get_issue` already reports `"create"` or `"select"` and there is nothing to do. Checking costs one call and is worth it before you assume.
Linking is not the same as asking for a worktree. `worktreeStrategy: "create"` only affects the *next* session on the issue and never relocates a running agent, so setting it mid-session will not move you.
Tool inventory
| Group | Tool | Purpose | |---|---|---| | Issues | `lanes_list_issues` | Filter by `step` / `tags` (any-match) / `componentId` / `search`. **Defaults are scoped**: at most 20, active project only, every Done status excluded. Pass `limit` (no upper bound), `allProjects: true`, or `includeDone: true` to widen. Filtering by a Done status includes it. Returns an envelope `{ issues, appliedFilters, truncated, totalAvailable }`, so check `truncated` before concluding a search found nothing. | | | `lanes_get_issue` | Full details by `id`. Does **not** include sessions. | | | `lanes_create_issue` | Required: `title`. | | | `lanes_update_issue` | Patch by `id`; pass `null` to clear nullable fields. | | | `lanes_delete_issue` | By `id`. Permanent. | | | `lanes_move_issue` | Shorthand for `update_issue` with only `step`. | | Sessions | `lanes_start_session` | Required: `issueId`. Spawns Claude Code (default), Codex, or `shell`. **Always adds a new session**; returns its slot + UUID. | | | `lanes_stop_session` | Stop a session for `issueId`. Optional `session` (UUID/slot/name) to disambiguate when >1. | | | `lanes_resume_session` | Re-attach Claude to a stopped session. **Claude-only.** Optional `session`. | | | `lanes_delete_session` | Permanently delete a session (stops it first if running). Optional `session`. | | | `lanes_get_session_status` | With `issueId`: bare array of every session for that issue (status under both `status` and `runtimeStatus`). Without: envelope `{ sessions, appliedFilters, truncated, totalAvailable }` capped at 20. | | History | `lanes_get_issue_changes` | `git diff` for the issue's cwd, by `id`. | | | `l
Run many CLI (Coding) Agents in parallel lanes: issues, worktrees, sessions, and loops on one board. The agentic development environment.
Other skills on app.
More skills from other plugins.
brainstorming
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
ask-matt
Ask which skill or flow fits your situation. A router over the skills in this repo.
Questions about lanes-sessions.
- Which coding agents can use lanes-sessions?
- lanes-sessions installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

