Configuration¶
One file, ~/.config/laneway/config.yaml, for the terminal and the
browser. The first laneway (or the setup page of laneway web) writes it,
readable only by you. Both settings screens (, in the terminal, g , in
the browser) edit the ui: options in place, comments kept.
A bad value keeps its default and is reported; an unknown key warns with a
"did you mean". One value where a list goes (projects: ABC) is a list of
one. An existing ~/.config/jiratui or matterbox config (its jira: and
ui:) is picked up as a fallback.
Jira¶
jira:
base_url: https://your-instance.atlassian.net
email: you@example.com
name: Work # how this site is labelled in the site picker and the web's header
api_token: ... # or JIRA_API_TOKEN (overrides it), or:
# api_token_cmd: [secret-tool, lookup, service, laneway] # prints the token (pass, op read, …)
projects: [ABC] # listed first in the project picker
repos: {ABC: ~/src/abc} # checkouts: start work, your commits in the standup and worklog proposals
start_statuses: {ABC: Doing} # where start work moves ABC issues, over ui.start_status ("" for none)
start_prompt: "Start on {key}." # what start work hands the agent; default a built-in prompt, none for no prompt
story_points_field: customfield_10016 # else found by name ("Story point…")
timeout: 20s # one request's limit (an attachment's: without progress)
sites: # more Jira instances, same keys as jira:
club: {base_url: https://club.atlassian.net, email: you@example.com, api_token: ...}
gitlab: # GitLab instances for merge requests; a host not listed uses glab's login (glab auth login --hostname <host>)
- base_url: https://git.example.com
token: ... # read_api; api to approve, merge, edit and comment. Or token_cmd: [...]
repos: {group/project: ~/src/project} # checkouts for an agent review; else found among jira.repos by origin
laneway setup adds a site under sites:; given a URL already there, it
replaces that site's email and token (an expired token). Where there is a
keyring (secret-tool, macOS Keychain) it offers to keep the token there,
writing only the command that reads it back. @ (in the app) switches
sites and is remembered: the terminal, laneway web, laneway prompt and
completion start on the last one picked; the script commands, rules and
hook use jira: unless given -site.
laneway only reads your Jira until you act: moving a card, editing a field or commenting.
ui options¶
Every option is optional. , (terminal) and g , (browser) list them by
topic with their value, default and what they do. Options marked
restart apply on the next start (the browser's Settings > Server >
Restart starts laneway web again); the rest apply at once.
Board and cards¶
| Option | Default | |
|---|---|---|
default_mode |
lanes |
lanes or list, before one is remembered per board. Restart |
card_fields |
all | what cards and list rows show, in order: type priority status points assignee avatar parent pr deploy subtasks due flagged age |
card_layout |
lane cards' fields around the summary: top, top_right, bottom, bottom_right; any of card_fields plus key, labels and custom fields |
|
card_styles |
restyle the cards a / query matches: when, edge, tint (accent ok warn err info or #rrggbb), fade, bold, hide, show; a later match wins |
|
card_colors |
ribbon |
the board's own card colours as a bar on cards and rows; off |
empty_lanes |
show |
hide: lanes the filters leave empty |
lane_layouts |
your own lanes over a board's columns, alt+l switches; see Lane layouts |
|
custom_fields |
Jira fields by name on cards and rows, searchable as "test type":e2e. Restart |
|
card_limit |
500 |
most cards one view fetches (50–5000); a view, search or planning side it cuts off says how many Jira has. Charts and the roadmap count up to 5000. Restart |
kanban_done_days |
14 |
done work older than this leaves kanban boards |
stale_days |
5 |
an in-progress card's age turns red past this |
flag_value |
Impediment |
the Flagged option flag sets. Restart |
icons |
nerd |
issue type glyphs need a Nerd Font; plain draws letters. Terminal |
ui:
card_layout:
top: [type, key, flagged]
top_right: [status, points]
bottom: [parent, due, labels]
bottom_right: [age, avatar]
card_styles:
- {when: "prio>=high", edge: err, bold: true}
- {when: "is:done", fade: true}
- {when: "-due<7d", hide: [due]} # show: keeps fields off cards it doesn't match
Views and filters¶
| Option | Default | |
|---|---|---|
home |
start on the home screen with these widgets, in order: work inbox sprint timer filters |
|
quick_filters |
{name, jql} presets before the board's own |
|
board_quick_filters |
on |
the board's own quick filters from Jira; off: only quick_filters |
views |
{name, jql} views of every board, after its own |
|
saved_filters |
on |
your starred Jira filters as views |
remember_filters |
on |
the assignee filter (mine) and each board's quick filters stay on next time |
filters |
{name, query}: named / queries, recalled from the palette |
|
my_work_jql |
yours, open or resolved this week | the query of My work |
ui:
quick_filters: [{name: Bugs, jql: "type = Bug"}]
views: [{name: Mine, jql: "assignee = currentUser()"}]
filters: [{name: Stale review, query: "status:review age>3d"}]
Panel¶
| Option | Default | |
|---|---|---|
panel_width |
50 |
the issue panel's share of the width in percent (20–80); dragging its border remembers another |
empty_fields |
show |
hide folds empty fields behind a row |
date_format |
2006-01-02 15:04 |
a Go time layout; within a week the panel says 2d ago |
images |
auto |
inline images in kitty and Ghostty; off. Terminal, restart |
image_max_rows |
16 |
the tallest an inline image gets (1–200). Terminal, restart |
templates |
a new issue's description by type, markdown | |
code_theme |
the theme's | a chroma style for code blocks. Terminal |
threaded_replies |
on |
reply in Jira's thread; off posts a new comment quoting it. Restart |
comment_order |
oldest |
newest puts the latest comment first; a thread keeps its replies oldest first |
comment_layout |
threaded |
flat lists comments by date, a reply under a truncated line quoting its parent |
ui:
templates:
Bug: "## Steps\n\n1. \n\n## Expected\n\n## Actual"
Refresh¶
| Option | Default | |
|---|---|---|
auto_refresh |
2m |
how often an idle board refetches; off |
stale_after |
1m |
an older board refetches on focus |
full_refresh |
10m |
idle refreshes fetch changes only, the whole board again after this. Terminal |
Time and worklogs¶
| Option | Default | |
|---|---|---|
timer_round |
to the minute | logged timer time rounded up to this (15m; up to 8h) |
timer_on_start |
off |
start work also starts the timer |
workday_start |
09:00 |
when work logged on another day starts |
workdays |
mon–fri | for the standup's previous workday and the week's gaps |
capacity |
sprint points per person, {Ada: 13, default: 10} |
|
activity |
commands printing time<TAB>KEY what lines of a day, for worklog proposals |
|
calendar |
an iCalendar file, https or webcal URL, or a vdir: meetings are proposed as worklogs and taken off your capacity. Needs meeting_key |
|
meeting_key |
the issue meetings are logged on |
Start work and agents¶
| Option | Default | |
|---|---|---|
start_assigns |
off |
start work also assigns the issue to you |
start_status |
and moves it there (In Progress), unless the move has a screen |
|
branch_template |
{key}-{summary} |
the copied branch name: {key} {summary} {type} {project} |
work_branch_template |
issue/{key}-{summary} |
start work's new branch; branch_template when that is set |
work_agent |
claude |
the herdr agent start work offers first |
work_args |
its arguments before the prompt; {key} is replaced |
|
work_create |
the command that makes a missing worktree ({branch} {base} {key}); unset: herdr |
|
agent_view |
fullscreen |
panel attaches an agent in the panel. Terminal |
llm |
claude -p when on the PATH |
the ask command: the question last, the issue on stdin (llm, ollama run llama3) |
actions |
your own commands on an issue, see Actions |
ui:
work_args: [--append-system-prompt, "User is working on {key}"]
work_create: [wt, switch, --create, "{branch}", --base, "{base}", --no-cd]
Planning, roadmap and charts¶
| Option | Default | |
|---|---|---|
velocity_sprints |
8 |
closed sprints in the velocity chart (1–50) |
report_done |
Jira's resolution | the column the charts count done from, by board id: {"12": In review} is that column and every one right of it. d on the charts sets it |
report_backwards |
live |
an issue moved back before the done line: live stops counting it, first counts it from its first crossing |
roadmap_epic_type |
Epic |
the issue type the roadmap shows and creates (Initiative, …) |
roadmap_done_days |
90 |
resolved epics older than this leave the roadmap |
Inbox¶
| Option | Default | |
|---|---|---|
inbox_every |
5m |
inbox sync, for the unread count; off |
inbox_lookback |
168h |
how far back the inbox reaches |
inbox_issues |
30 |
recently updated issues the inbox and standup read (1–200). Restart |
Standup¶
| Option | Default | |
|---|---|---|
standup_start |
everyone |
first: open on the first person |
standup_lookback |
1 |
workdays back the standup starts (1–10); a Monday covers Friday |
standup_length |
15m |
the whole standup, split over the people for each turn |
standup_timebox |
each person's turn instead of the split | |
standup_shuffle |
off |
go round in a random order |
standup_timer |
off |
a timer for each turn and the whole standup |
Look and feel¶
| Option | Default | |
|---|---|---|
theme |
the terminal's colours | see Terminal theme; the browser has its own under Settings › Appearance |
mouse |
on |
off leaves the mouse to the terminal. Terminal |
double_click |
400ms |
how quickly a second click opens (100ms–2s). Terminal |
keys |
rebind actions by name: terminal, browser | |
web_keys |
rebind browser keys without a terminal action, by id: browser. Browser | |
delight |
on |
small celebrations: confetti on a card into done, a sprint's points against the last ones |
language |
en |
the language laneway shows: en or nl; LANEWAY_LANG overrides it |
skin_tone |
the emoji tone for people: light medium_light medium medium_dark dark |
System¶
| Option | Default | |
|---|---|---|
open |
xdg-open / open |
opens URLs and attachments (wslview) |
clipboard_image |
probed | prints the clipboard's PNG (wl-paste --type image/png) |
download_dir |
$XDG_DOWNLOAD_DIR, else ~/Downloads |
where attachments are saved |
update_check |
on |
a daily look for a newer release, ↑ v1.2 in the header |
Lane layouts¶
ui.lane_layouts are your own lanes over a board's columns: in your order,
several columns stacked in one lane under a header each, a column's
statuses split over lanes, renamed, some hidden. alt+l steps through the board's own columns and each layout that
fits it, remembered per board; nothing changes in Jira.
The browser's settings draw a layout over a board's real columns: drag a
column onto a lane, between lanes or onto Hidden, split a column (its
button, or s) to place its statuses one by one, drag lanes to reorder,
type their names, tick the boards it is on or Every board it fits. In
the terminal alt+L arranges the board's layout in place (a new one when
it shows none), s splitting a column there too. Both write the config
for you; by hand:
A lane lists statuses by id, so boards on the same workflow share a
layout. A column whose statuses are in one lane is stacked there whole; one
whose statuses are spread over lanes is a section in each, named by its
statuses there. A status a layout doesn't list stays with its column's
first listed one. A layout fits a board where it places at least two
columns; site: keeps it to the Jira it was made on (the editors write
it: another site's status ids mean other statuses), boards: to those
board ids. A column it doesn't place
keeps a lane of its own after its left neighbour's; hidden: takes
statuses off the board, and the header counts their cards.
ui:
lane_layouts:
- name: Dev
site: acme.atlassian.net # optional
boards: [12, 34] # optional
lanes:
- statuses: ["10000"] # To do; the name defaults to the column's
- name: Doing
statuses: ["3", "10020"] # In progress, Blocked
- name: Done
statuses: ["10010", "10011", "10012", "10001"] # Test, UAT, Deploy, Done
hidden: ["10030"] # Won't do
A lane's limit is its columns' limits added up, when each has one; a
split column's limit counts in none. H and
L step a card through a stacked lane's columns one by one; a column of
several statuses asks which one; a drag shows a drop zone per status. z folds a
stacked column, remembered per board.
Actions¶
ui.actions are your own commands on an issue: each is in the palette, and
on its key when it has one no built-in uses. It runs with the selected
issue (in the panel, the panel's; on the board, the marked cards when there
are) as JSON on stdin, LANEWAY_KEY and LANEWAY_KEYS in the
environment. The output's last line shows as a message, or all of it with
show: pager; refresh: true reloads the board and issue after. where:
is board, panel or both.
ui:
actions:
- {name: open in my notes, key: "!", command: [sh, -c, 'obsidian "jira/$LANEWAY_KEY"']}
- {name: estimate, command: [./estimate.sh], where: panel, show: pager, refresh: true}
In the browser they run on the machine laneway web runs on.
Terminal theme¶
ui:
theme:
preset: tokyonight
accent: "#7aa2f7"
dim: "244"
theme: gruvbox alone works too. Colours take ANSI 0–255, #rrggbb or
#rgb.
- Dark presets: tokyonight, tokyonight-storm, catppuccin, catppuccin-macchiato, catppuccin-frappe, gruvbox, dracula, nord, solarized-dark, onedark, rosepine, rosepine-moon, kanagawa, kanagawa-dragon, monokai.
- Light presets: tokyonight-day, catppuccin-latte, gruvbox-light, solarized-light, rosepine-dawn, kanagawa-lotus, onelight.
mono(orNO_COLORset) draws no colour at all: the cursor and a drop in reverse, the accent bold, the dim faint, code blocks plain.
Colour names: accent dim selection_fg selection_bg selection_idle error
mention link code attachment over_limit drop_fg priority_highest
priority_high priority_low priority_lowest type_bug type_story type_epic
type_subtask type_other type_alert highlight roadmap_done roadmap_todo
status_todo status_progress status_done, and shade.
status_*colour the lane marks and the panel's status lozenges; unset they followselection_bg,roadmap_todoandroadmap_done.type_*colour issue type icons by Jira's colour for the icon: redtype_bug, greentype_story, purpletype_epic, bluetype_other, orangetype_alert(unset it followshighlight).shade:autosteps off the terminal's own background (faint for the canvas, list zebra rows; stronger for the panel's trail, section bars, the board title, lane heads and status line),off, or one colour for all.- On a light terminal the default
selection_idleturns light grey (253).
Files¶
| File | Holds |
|---|---|
~/.config/laneway/config.yaml |
this configuration |
~/.config/laneway/state.json |
last project, board, view and filters, cached boards, the timer, drafts, the offline queue, starred queries; state-club.json for a site |
~/.config/laneway/notes/ABC-12.md |
private notes; notes-club/ for a site |
~/.config/laneway/rules.log |
what log rule actions wrote |
~/.cache/laneway/index-jira.db |
the local index of every issue read; index-club.db for a site |
~/.cache/laneway/avatars |
avatar images |