Docs/Desktop/Power Features/Deep Links

Deep Links

Launch Lanes from Linear, GitHub, scripts, or bookmarklets with a pre-filled new-issue draft, or open it straight on a settings page.

Lanes registers a custom URL scheme so other tools can put it somewhere useful. Click a lanes://... link in your browser, a Linear coding-tool button, a GitHub bot comment, or a shell script, and Lanes pops to the front with a new issue draft that already has the title, description, and upstream tracker fields filled in. It is the fastest way to capture an idea or kick off work without ever opening the app yourself.

There are two actions: new, which is that draft, and settings, which opens a settings page.

The URL Format

A deep link looks like this:

Code
lanes://new?prompt=<urlencoded>
            [&title=<urlencoded>]
            [&externalProvider=linear|github]
            [&externalKey=ABC-123]
            [&externalUrl=https%3A%2F%2F...]

Only prompt is required. Everything else is optional. The new action opens a draft issue in the backlog and surfaces it in the right-side panel, the same way Cmd+N does, except the fields are already populated.

Parameters

ParameterRequiredWhat it does
promptyesThe body of the issue. URL-encoded. If you omit title, the first non-empty line of prompt becomes the title (capped at 80 characters).
titlenoExplicit issue title. Max 80 characters. Useful when the first line of your prompt is not a good headline.
externalProvidernoUpstream tracker the issue is linked to. Only linear or github are accepted; any other value is dropped.
externalKeynoThe user-visible key of the upstream issue (e.g. FOO-123 for Linear, #456 for GitHub). Shown in the Lanes UI alongside the issue.
externalUrlnoFull URL to the upstream issue. Lanes uses this for the "open in Linear/GitHub" link on the issue.

Template safety. Any value containing {{ or }} is dropped at parse time. This is so that if you wire Lanes into a tool that substitutes placeholders (like Linear's coding-tool template fields) and that substitution fails, you do not end up with literal {{issue.identifier}} text written into your issue. The rest of the link still works; only the broken value is discarded.

Quick Examples

Minimal, just a prompt:

Code
lanes://new?prompt=Investigate%20the%20flaky%20auth%20test

A full Linear-style payload with every field set:

Code
lanes://new?prompt=Add%20dark%20mode%20toggle%0A%0AIssue%3A%20FOO-123&title=Add%20dark%20mode%20toggle&externalProvider=linear&externalKey=FOO-123&externalUrl=https%3A%2F%2Flinear.app%2Ffoo

That second link decodes to:

  • Title: Add dark mode toggle
  • Description: Add dark mode toggle\n\nIssue: FOO-123
  • External link: Linear issue FOO-123 at the given URL

Quick Setup for Linear

Linear has a dedicated integration point for tools like Lanes. Open Linear's coding-tools settings and paste this into the Custom link field:

Code
lanes://new?prompt={{prompt}}

That is the whole setup. Click the coding-tool button on any Linear issue and Lanes opens with a draft already populated.

Linear does not yet expose separate variables for the issue title or identifier in the URL, so today everything Linear sends comes through as the prompt. That is fine: the identifier, branch name, and full Linear context all land inside the issue description, and the first line of that description becomes the title automatically.

Use It From Anywhere Else

Deep links are just URLs, so any tool that can open a URL can feed Lanes.

Terminal (macOS):

Bash
open 'lanes://new?prompt=Look%20into%20PR%20%23482'

Browser bookmarklet skeleton:

javascript
javascript:location.href='lanes://new?prompt='+encodeURIComponent('Capture this page: '+document.title+'\n\n'+location.href)

Drag that into your bookmarks bar and you have a one-click "send the current page to Lanes" button.

Shell alias for quick capture:

Bash
alias lcap='f(){ open "lanes://new?prompt=$(python3 -c "import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1]))" "$*")"; }; f'

Then lcap "debug the rate limiter on /api/search" opens Lanes with that prompt waiting.

The only hard requirement is URL-encoding. Spaces become %20, newlines become %0A, ampersands become %26, and so on. Most languages have a one-liner for this (encodeURIComponent in JS, urllib.parse.quote in Python, jq -sRr @uri in shell).

Opening Settings

The second action takes one optional parameter:

Code
lanes://settings[?page=<settings-page-id>]

page names a page in the settings sidebar: integrations-link, integrations-github, agents-harness, appearance, and so on. Leave it off and Settings opens wherever it was.

Bash
open 'lanes://settings?page=integrations-link'

A page id Lanes does not have is not a broken link. Unlike an unknown action, which is dropped, an unrecognised page falls back to whatever page Settings was last on. That is deliberate: a link written against a newer or older version of Lanes still opens something real rather than appearing to do nothing.

This is what Lanes Link uses. Running lanes link desktop in a terminal opens exactly the link above, which is a shorter path to that page than talking someone through the menu. It needs Lanes 0.48.0 or newer; an older build is still registered for lanes://, so the link appears to succeed and the app simply ignores it.

Tips

  • Title fallback. If you skip title, Lanes uses the first non-empty line of prompt. Lead with a short headline, then a blank line, then the body, and you get a clean title-plus-description for free.
  • Unknown params are ignored. Lanes will gain new deep-link actions over time. Add custom query params today and they will be silently dropped, so links you build now stay forward-compatible.
  • The action is new for now. Today every deep link creates a new backlog issue. Future actions (focus an existing issue, open a session, jump to a view) will use the same scheme with different paths.
  • Cold-start works. If Lanes is not running when a deep link fires, macOS launches it and the link is delivered to the app once it boots. You do not need to keep Lanes open to use this.