Luxe

Mention sources

Add your own tab to the @ picker: Jira issues, Asana tasks, anything a program can list.

View as Markdown

A mention source adds a tab to the @ picker, filled by a program of yours. Pick a row, and the agent receives the text your program gave for it.

Add a source

~/.config/luxe/config.json
{
  "mentions": [
    { "name": "Jira", "command": "jira-mentions", "icon": "\udb80\udf03" },
    { "name": "Asana", "kind": "task", "command": "asana-mentions", "args": ["--mine"] }
  ]
}
KeyDoes
nameThe tab’s name
command, argsThe program to run, found on PATH or given as a full path, and its arguments
kindThe mention’s prefix, as in @[task:1209…]. By default the name in lowercase, with anything but letters and digits as -: Jira Cloud is jira-cloud.
iconOne Nerd Font glyph for the tab, as the character or a JSON escape. Without one, the tab shows a tag; without a Nerd Font, a plain mark.

Sources are read from your own config only, since each one runs a program. Their tabs come after Luxe’s own: Files, Skills, GitHub and MCP, whose kinds file, skill, github and mcp are taken. Two sources with the same kind get one tab, the first’s.

What the program prints

Luxe runs the program, in the project, the first time its tab opens, and lists what it prints: one JSON object per line. The rows are kept until Luxe exits, so a new ticket, or a change to your script, shows up the next time you start Luxe. The program has no terminal and no stdin, so it cannot prompt for a sign-in.

{"id": "PROJ-12", "label": "PROJ-12 Login fails on Safari", "detail": "In progress", "text": "Jira issue PROJ-12 \"Login fails on Safari\" (In progress) https://acme.atlassian.net/browse/PROJ-12"}
FieldIs
idRequired, a string or a number, without ]. Goes in the mention: @[jira:PROJ-12].
labelRequired. The row in the picker, up to 200 characters.
detailShown beside the label, up to 200 characters
textWhat the agent receives, up to 600 characters. The label when missing.

A program has 15 seconds and up to 500 rows. A line that is not JSON, is over 8 KB, or lacks an id or label is skipped without a word, so a tab that stays empty usually means the output is wrong. If the program fails, the tab shows the last line it wrote to stderr, or its exit status, and it runs again the next time the tab opens.

Make text enough for the agent to find the rest: a title and a link, or an ID it can look up with a CLI or an MCP server. A mention you type by hand, or one not picked since Luxe started, reaches the agent as Jira PROJ-12 alone. What a tracker says is other people’s words, and it reaches your model provider once you mention it.

Example: your open Jira issues

~/bin/jira-mentions
#!/bin/sh
site=https://acme.atlassian.net
curl -sSf -u "$JIRA_USER:$JIRA_TOKEN" -G "$site/rest/api/3/search/jql" \
  --data-urlencode 'jql=assignee = currentUser() AND statusCategory != Done ORDER BY updated DESC' \
  --data-urlencode 'fields=summary,status' |
jq -c --arg site "$site" '.issues[] | {
  id: .key,
  label: "\(.key) \(.fields.summary)",
  detail: .fields.status.name,
  text: "Jira issue \(.key) \"\(.fields.summary)\" (\(.fields.status.name)) \($site)/browse/\(.key)"
}'

Make it executable (chmod +x), put it on your PATH, and add the Jira entry above. For Asana, see Recipes. Or ask Luxe to write one for the tracker you use.