diff --git a/plugins/jira-auto-worklog/README.md b/plugins/jira-auto-worklog/README.md
new file mode 100644
index 000000000..607690533
--- /dev/null
+++ b/plugins/jira-auto-worklog/README.md
@@ -0,0 +1,43 @@
+# JIRA auto-worklog
+
+This plugin automatically logs time to Atlassian's [JIRA](https://www.atlassian.com/software/jira) bug tracking software when on a git branch with a JIRA issue ID in the branch name.
+
+## Installation
+
+Add the plugin to the list of plugins for Oh My Zsh to load (inside `~/.zshrc`):
+
+    ```sh
+    plugins=(
+        # other plugins...
+        jira-auto-worklog
+    )
+    ```
+
+
+## Usage
+
+Every time the command prompt is generated, the time spent on a JIRA branch is accumulated. Once the accumulated time exceeds a threshold, the time is logged in the background. By default, the time is logged every minute.
+
+To prevent AFK time from being counted, no time is logged if there is no activity on a JIRA branch for a certain amount of time. By default the AFK threshold is 30m.
+
+## Setup
+
+The URL for your JIRA instance is located in the following places, in order of precedence:
+
+1. `$JIRA_URL` environment variable
+2. `./.jira-url` file in the current directory
+3. `~/.jira-url` file in your home directory
+
+The PAT for your JIRA instance is located in the following places, in order of precedence:
+
+1. `./.jira-pat` file in the current directory
+2. `~/.jira-pat` file in your home directory
+
+Run `jira-auto-worklog-check` in this directory to check if the plugin is correctly configured.
+
+### Variables
+
+* `$JIRA_URL` - Your JIRA instance's URL
+* `$JIRA_AUTO_WORKLOG_AFK_THRESHOLD` - The number of minutes of AFK time before no time is logged. Defaults to 30
+* `$JIRA_AUTO_WORKLOG_COMMENT` - The comment to add to the work log. Defaults to an empty string
+* `$JIRA_AUTO_WORKLOG_PRECISION` - The size of the chunks of time that are logged. Must be greater than zero. Defaults to 1. For example, `JIRA_AUTO_WORKLOG_PRECISION=15` will log 15 minutes after being active for 15 minutes a JIRA branch.
\ No newline at end of file
diff --git a/plugins/jira-auto-worklog/jira-auto-worklog b/plugins/jira-auto-worklog/jira-auto-worklog
new file mode 100755
index 000000000..889c11f32
--- /dev/null
+++ b/plugins/jira-auto-worklog/jira-auto-worklog
@@ -0,0 +1,108 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+require 'net/http'
+require 'json'
+require 'yaml'
+require 'date'
+
+JIRA_REGEX = /([A-Z]+-\d+)/.freeze
+CONFIG_PATH = "#{Dir.home}/.jira-auto-worklog"
+
+def jira_url
+  ENV.fetch('JIRA_URL', nil) ||
+    (File.read('./.jira-url').chomp if File.exist?('./.jira-url')) ||
+    (File.read("#{Dir.home}/.jira-url").chomp if File.exist?("#{Dir.home}/.jira-url")) ||
+    nil
+end
+
+def jira_pat
+  (File.read('./.jira-pat').chomp if File.exist?('./.jira-pat')) ||
+    (File.read("#{Dir.home}/.jira-pat").chomp if File.exist?("#{Dir.home}/.jira-pat")) ||
+    nil
+end
+
+def afk_threshold
+  ENV.fetch('JIRA_AUTO_WORKLOG_AFK_THRESHOLD', 30).to_i
+end
+
+def comment
+  ENV.fetch('JIRA_AUTO_WORKLOG_COMMENT', '')
+end
+
+def precision
+  ENV.fetch('JIRA_AUTO_WORKLOG_PRECISION', 1).to_i
+end
+
+unless jira_url
+  puts 'JIRA URL not found.'
+  puts
+  puts 'Valid Locations are, in order of precedence:'
+  puts '  1. JIRA_URL environment variable'
+  puts '  2. ./.jira-url'
+  puts '  3. ~/.jira-url'
+  exit(1)
+end
+
+unless jira_pat
+  puts 'JIRA Personal Access Token not found.'
+  puts
+  puts 'Valid Locations are, in order of precedence:'
+  puts '  1. ./.jira-pat'
+  puts '  2. ~/.jira-pat'
+  exit(1)
+end
+
+unless precision > 0
+  puts 'Precision must be a positive integer.'
+  exit(1)
+end
+
+branch = `command git rev-parse --abbrev-ref --symbolic-full-name HEAD 2> /dev/null`
+exit(0) unless (match = branch.match(JIRA_REGEX))
+
+ticket = match[1]
+
+# load the config
+data = {}
+if File.exist?(CONFIG_PATH)
+  data = YAML.safe_load(File.read(CONFIG_PATH), permitted_classes: [Time])
+end
+data['overflow'] ||= 0
+data['last_updated'] ||= Time.now
+
+# Calculate the delta
+delta_s = Time.now.utc.to_i - data['last_updated'].to_i
+data['last_updated'] = Time.now.utc
+
+if (delta_s / 60) > afk_threshold
+  File.write(CONFIG_PATH, YAML.dump(data))
+  exit(0)
+end
+
+time_spent = delta_s + data['overflow']
+precision_s = precision * 60
+minutes = (time_spent / precision_s)
+data['overflow'] = (time_spent % precision_s)
+File.write(CONFIG_PATH, YAML.dump(data))
+
+exit(0) if minutes.zero?
+
+uri = URI("#{jira_url}/rest/api/2/issue/#{ticket}/worklog")
+
+request = Net::HTTP::Post.new(uri)
+request['Authorization'] = format('Bearer %s', jira_pat)
+request['Content-Type'] = 'application/json'
+request.body = JSON.generate({
+                               'timeSpent' => minutes,
+                               'comment' => comment
+                             })
+
+Net::HTTP.start(uri.host, uri.port, use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_PEER) do |http|
+  res = http.request(request)
+  if res.is_a?(Net::HTTPSuccess)
+    puts "Logged #{minutes} minutes to #{ticket}"
+  else
+    puts "Failed to log time to #{ticket}"
+  end
+end
\ No newline at end of file
diff --git a/plugins/jira-auto-worklog/jira-auto-worklog-check b/plugins/jira-auto-worklog/jira-auto-worklog-check
new file mode 100755
index 000000000..9774104e9
--- /dev/null
+++ b/plugins/jira-auto-worklog/jira-auto-worklog-check
@@ -0,0 +1,65 @@
+#!/usr/bin/env ruby
+# frozen_string_literal: true
+
+require 'net/http'
+require 'json'
+require 'yaml'
+require 'date'
+
+JIRA_REGEX = /([A-Z]+-\d+)/.freeze
+
+def jira_url
+  ENV.fetch('JIRA_URL', nil) ||
+    (File.read('./.jira-url').chomp if File.exist?('./.jira-url')) ||
+    (File.read("#{Dir.home}/.jira-url").chomp if File.exist?("#{Dir.home}/.jira-url")) ||
+    nil
+end
+
+def jira_pat
+  (File.read('./.jira-pat').chomp if File.exist?('./.jira-pat')) ||
+    (File.read("#{Dir.home}/.jira-pat").chomp if File.exist?("#{Dir.home}/.jira-pat")) ||
+    nil
+end
+
+def precision
+  ENV.fetch('JIRA_AUTO_WORKLOG_PRECISION', 1).to_i
+end
+
+unless jira_url
+  puts 'JIRA URL not found.'
+  puts
+  puts 'Valid Locations are, in order of precedence:'
+  puts '  1. JIRA_URL environment variable'
+  puts '  2. ./.jira-url'
+  puts '  3. ~/.jira-url'
+  exit(1)
+end
+
+unless jira_pat
+  puts 'JIRA Personal Access Token not found.'
+  puts
+  puts 'Valid Locations are, in order of precedence:'
+  puts '  1. ./.jira-pat'
+  puts '  2. ~/.jira-pat'
+  exit(1)
+end
+
+unless precision > 0
+  puts 'Precision must be a positive integer.'
+  exit(1)
+end
+
+uri = URI("#{jira_url}/rest/api/2/myself")
+
+request = Net::HTTP::Get.new(uri)
+request['Authorization'] = format('Bearer %s', jira_pat)
+request['Content-Type'] = 'application/json'
+
+Net::HTTP.start(uri.host, uri.port, use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_PEER) do |http|
+  res = http.request(request)
+  if res.is_a?(Net::HTTPSuccess)
+    puts "Jira auto-worklog is configured correctly. Time will be logged."
+  else
+    puts "Jira auto-worklog is not configured correctly. Please check your JIRA URL and Personal Access Token."
+  end
+end
diff --git a/plugins/jira-auto-worklog/jira-auto-worklog.plugin.zsh b/plugins/jira-auto-worklog/jira-auto-worklog.plugin.zsh
new file mode 100644
index 000000000..b313b2d31
--- /dev/null
+++ b/plugins/jira-auto-worklog/jira-auto-worklog.plugin.zsh
@@ -0,0 +1,20 @@
+# zle-line-init widget (don't redefine if already defined)
+(( ! ${+functions[_jira-auto-worklog_zle-line-init]} )) || return 0
+
+# Get the directory of this file
+dir="$(dirname "$0")"
+
+case "$widgets[zle-line-init]" in
+  # Simply define the function if zle-line-init doesn't yet exist
+  builtin|"") function _jira-auto-worklog_zle-line-init() {
+      ($dir/jira-auto-worklog &> /dev/null)
+    } ;;
+  # Override the current zle-line-init widget, calling the old one
+  user:*) zle -N _jira-auto-worklog_orig_zle-line-init "${widgets[zle-line-init]#user:}"
+    function _jira-auto-worklog_zle-line-init() {
+      ($dir/jira-auto-worklog &> /dev/null)
+      zle _jira-auto-worklog_orig_zle-line-init -- "$@"
+    } ;;
+esac
+
+zle -N zle-line-init _jira-auto-worklog_zle-line-init