Skip to main content

jira-time-tracker

jtt answers one question about a Jira Cloud project: how much estimated work came into being over a period, on which issues, and by whom?

The estimate is whatever field your organisation tracks. That could be story points, an hours or days custom field, or Jira's own original estimate or time spent. You pick the field once per project.

jtt calculate, jtt contributions --by day and jtt export, run against a demo Jira project

Install

It needs Python 3.10 or newer and works the same on Linux, macOS and Windows.

uv tool install git+https://github.com/codeonym/jira-time-tracker   # or: pipx install git+…
jtt --help

To install from a local checkout, run uv tool install . or pipx install ..

Getting started

jtt login     # site URL, account email, API token (typed hidden)
jtt init      # for each project: choose the field that holds the estimate, and its unit
jtt calculate --period last-week
  1. jtt login checks the token against Jira before storing it. Create a token at https://id.atlassian.com/manage-profile/security/api-tokens. To switch account or rotate the token, run jtt logout first, then jtt login again.

  2. jtt init walks through every project you can see and lists its numeric fields. A ★ marks the fields on the project's create screens, and those come first. You pick one and say what its numbers mean: points, seconds, minutes, hours, days or weeks. For time units you also pick the unit reports should show. Jira's built-in time tracking fields always hold seconds, so the tool sets that unit for you. Your last choice is offered as the default for the next project. Type s to skip a project or q to stop; progress is saved after each project.

    To skip the questions, pass everything as options: jtt init -p DEMO --field customfield_10016 --unit points.

Commands

Command What it does
login / logout [--purge] / whoami [--check] Manage the account. logout keeps project settings; --purge forgets them too
init [-p KEY…] [--reconfigure] Choose each project's tracked field and unit
config show | path | default KEY | set KEY … | remove KEY | calendar … Inspect or edit settings without re-running init
projects [--configured] Projects you can see and what each one tracks
fields [-p KEY] [--counts] A project's numeric fields, optionally with how many issues hold a value
fetch Issues touched in a period, with their current value (--json for raw output)
calculate Net amount per issue for the whole project or one person, at four levels of detail
collaborators People who can be assigned to the project, with their current open, in-progress and done issues
contributions [--by day|week] Per-person net, added, removed, share, issues created and issues finished, plus statistics and a daily trend
export -o FILE [-k issues|changes|contributions|daily] Write CSV (opens in Excel), JSON or Markdown

Every report takes -p KEY (default: the project set by init), a period, and --as hours|days|… to show time amounts in another unit.

Periods

Periods are half-open: the start day is included and the end day is excluded. --from 2026-09-01 --to 2026-10-01 is all of September. Leave out --to and the period runs through today.

You can also use a named period instead: --period today | yesterday | this-week | last-week | this-month | last-month | this-quarter | last-quarter | this-year | last-7-days | last-30-days. Weeks start on Monday.

Days are the calendar days Jira shows in your Jira profile's time zone, which is also how Jira reads dates in queries. The tool never works out time zone offsets itself, because local time zone data can disagree with Jira's. For example, tzdata 2026d keeps Morocco at +00 after Ramadan 2026, while Jira still shows +01.

Choosing whose work to count (--user)

--user accepts me, an account id, or part of a name or email.

  • calculate --user X (the default, --attribution was) counts every change made in the period on issues X held at some point in the period.
  • --attribution holder only counts changes made while X held the issue.
  • contributions always credits each change to whoever held the issue when it happened. The value an issue was created with goes to the first person assigned to it. That way the per-person totals add up to the project total.

Levels of detail

-v, -vv (or --vv) and -vvv (or --vvv) work on calculate and contributions:

  • -v adds current value, type, status and current assignee (↪ marks a task that has since moved to someone else), and where each amount came from.
  • -vv also lists issues with no change, and adds a per-issue timeline of each change: when it happened, the value before and after, and who made it.
  • -vvv also shows the query sent to Jira, a trace of every API request, and changes outside the period (struck through).

How the delta is computed

For each issue touched in the period, the tool reads its full change history from Jira and adds up the changes to the tracked field that happened inside the period. Two Jira behaviours shape this:

  • The query can't use "last updated" as an end date. Jira only records when an issue was last updated. An issue edited inside the period and again afterwards would drop out of a query ending at the period's end. So the query only filters on that date from below, and the change history decides what falls inside the period.
  • A value entered when an issue is created leaves no history entry. Jira's history starts at the first edit. For an issue created inside the period, the tool adds back the value it was created with. That value is the "before" side of its first later change, or its current value if the field was never edited.

Dates in queries are always sent with an explicit 00:00. Tested on a live site, bare dates did not give exact bounds: assignee WAS X DURING ("2026-09-24", "2026-09-25") matched issues first assigned in the afternoon of the 25th, and DURING ("2026-09-25", "2026-09-25") matched nothing.

Where things are kept

What Where
Settings (site, projects, fields, units) config.json in the user config directory; jtt config path prints it. On Linux: ~/.config/jira-time-tracker, macOS: ~/Library/Application Support/jira-time-tracker, Windows: %LOCALAPPDATA%\jira-time-tracker
API token The system keyring: Windows Credential Manager, macOS Keychain, or Secret Service (GNOME Keyring / KWallet) on Linux. Where no keyring is available (headless servers, WSL, containers), it goes in credentials.json next to the settings, created 0600 inside a 0700 directory

The token is never written to config.json or printed.

Environment overrides:

  • JTT_CREDENTIAL_BACKEND=file|keyring forces where the token is stored.
  • JTT_API_TOKEN supplies a token for CI; it is never stored.
  • JTT_CONFIG_DIR moves the settings directory.

Development

uv sync
uv run pytest

The tests run the real CLI and HTTP client against a local fake Jira that replays issue data captured from a live site.

legacy/jira_tasks.py is the single-file script this project grew from, kept unchanged.

Metadata

Release files for jira-time-tracker 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jira-time-tracker 0.1.1
File Size Uploaded
jira_time_tracker-0.1.1.tar.gz 34.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for jira-time-tracker 0.1.1
File Interpreter ABI Platform
jira_time_tracker-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 74.3 kB

Release files / jira_time_tracker-0.1.1.tar.gz

Download URL jira_time_tracker-0.1.1.tar.gz
Size 34.7 kB
Tags Source
SHA-256 checksum
How to use checksums
26ab0575bab9bc038484d8dc4e36432af079b03239bb447022ccaa018215467b
BLAKE2b-256 checksum
How to use checksums
917c4a59ec7e9247379e6fd1d2a223efab801bc6de3d6b2606ac4a9d90f4ce2d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 28, 2026.

Transparency log

Release files / jira_time_tracker-0.1.1-py3-none-any.whl

Download URL jira_time_tracker-0.1.1-py3-none-any.whl
Size 39.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
70f3f0ba867bea3d3ce8d100a8a1e8ed8a4a306fbe21f6e5d7f842b5ead1e9bd
BLAKE2b-256 checksum
How to use checksums
e2a393129a5e91bd3e0dd8d13a3786ba700824bb281a6006e4aa09bcdff2e996
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 28, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page