jira
The jira extension bidirectionally syncs
Jira issues
with the Thurbox
task list
: your issues show up as tasks, and marking a task done moves the issue to a
Done-category status. A
jira-tick
automation
(every 15 min,
cron:*/15 * * * *
) runs a deterministic
Exec
command —
{home}/scripts/sync.sh
— that reconciles the JQL filters in
trackers.md
with the task list. There is
no agent, no LLM, no tokens
: Thurbox's scheduler runs the script (TUI or headless heartbeat) and records its output
in the automation run history. The script only calls
thurbox-cli
and talks to Jira Cloud's REST API v3 over
curl
; no Jira app, no webhook.
Experimental. jira is new and under active testing — its sync scripts and manifest may change between releases.
Overview #
Pull is the default direction: Jira issues become Thurbox tasks. Jira is authoritative for
an issue's
title, URL, and open-vs-done state
; your local
todo
↔
in_progress
distinction is preserved. Status maps by
statusCategory
:
new
→
todo
,
indeterminate
→
in_progress
,
done
→
done
. Imported tasks carry
source=jira
and
external_id="<issue key>"
(e.g.
ENG-7
), so re-syncing never duplicates them — dedup is by
(source, external_id)
.
Descriptions are not synced. Jira v3 descriptions are ADF (rich JSON); converting them to text is out of scope, so tasks carry title + URL only .
Requirements #
-
thurbox-cli≥ 0.141 onPATH— the sync uses thetask --source/--external-id/--external-urlflags added there (check withthurbox-cli version). -
curlandjqonPATH.
Get a Jira API token #
Create a token at
id.atlassian.com
. Because the sync runs
headless
(via the automation, with no shell session to inherit your environment), hand it the
three values via a
credentials.env
file in the install home —
sync.sh
sources it before running:
$ mkdir -p ~/.config/thurbox/extensions/jira
$ cat > ~/.config/thurbox/extensions/jira/credentials.env <<'EOF'
JIRA_BASE_URL=https://your-domain.atlassian.net
JIRA_EMAIL=you@example.com
JIRA_API_TOKEN=your-atlassian-api-token
EOF
$ chmod 600 ~/.config/thurbox/extensions/jira/credentials.env
(Exporting the three vars from your shell profile is an alternative, but it only reaches
the headless run if the scheduler inherits your profile — so
credentials.env
is recommended.) Auth is HTTP Basic (
-u "$JIRA_EMAIL:$JIRA_API_TOKEN"
). Confirm the credentials:
$ curl -fsSL -u "$JIRA_EMAIL:$JIRA_API_TOKEN" "$JIRA_BASE_URL/rest/api/3/myself"
Install #
jira is a Thurbox
extension
(a declarative
extension.toml
manifest):
$ thurbox-cli extension install jira # or ./extensions/jira
$ thurbox-cli extension uninstall jira # --purge also deletes ~/.config/thurbox/extensions/jira
Installing lays down the
~/.config/thurbox/extensions/jira/
home (override with
--home
; it holds
scripts/sync.sh
+ helpers and the seeded
trackers.md
) and activates the
jira-tick
automation —
self-healed
by Thurbox if deleted.
Configure trackers.md #
Edit
~/.config/thurbox/extensions/jira/trackers.md
— one row per filter. The
query
is a
JQL
string: the whole cell is one JQL value (it contains spaces and is
not
word-split), e.g.
project = ENG AND statusCategory != Done
. Keep
push_back = no
for the first run.
| name | query | push_back |
|--------|-----------------------------------------------------|-----------|
| mine | assignee = currentUser() AND statusCategory != Done | no |
| triage | project = WEB AND labels = needs-triage | no |
First sync & verify #
The automation fires every 15 min. To run it now, trigger it from the
Automations
pane (
Ctrl+P
→ select
jira-tick
→
r
) or headless:
$ thurbox-cli automation run <id> # id from: thurbox-cli automation list
$ ~/.config/thurbox/extensions/jira/scripts/sync.sh # or run the script directly
Then inspect the imported tasks:
$ thurbox-cli task list --json | jq -c '.[] | select(.source=="jira") | {id,status,external_id,title}'
Status maps by
statusCategory
(
new
→
todo
,
indeterminate
→
in_progress
,
done
→
done
). Re-running is
idempotent
— dedup by
(source, external_id)
leaves unchanged issues alone, and the
source=jira
tag keeps these tasks distinct from any other tracker's. The run's output
(created/updated/unchanged counts) shows in the automation run history.
Two-way sync #
Once the pull looks right, set
push_back = yes
on a tracker row. Now marking an imported task
done
transitions its Jira issue into the Done category, and moving it back to
todo
reopens it — only the
open↔done axis
is pushed. The sync runs
push-then-pull
(
push-status.sh
then per-tracker
fetch.sh | upsert.sh
), so your local change reaches Jira before the pull reads state back. Push uses the
workflow's
transitions
: to close, the first transition landing in the Done category; to reopen, the first
non-Done (preferring
new
) transition. If the workflow lacks a suitable transition the issue is surfaced in the
run output and skipped, not failed.
All-or-nothing push-back.
A Jira issue key can't be tied back to the specific JQL row that returned it, so
push-back is
all-or-nothing
— if
any
row is
yes
, push acts on
all
source=jira
tasks.
Files #
See
extensions/jira
for the
extension.toml
manifest, the seeded
trackers.md
, the
README.md
, and the sync scripts (
scripts/sync.sh
,
scripts/fetch.sh
,
scripts/upsert.sh
,
scripts/push-status.sh
).