bryan-cox/taskledger

TaskLedger is a command-line interface (CLI) tool for tracking work and generating reports from a YAML log file. It helps you maintain a structured log of your daily tasks, calculate hours worked, and generate progress reports in a clean, human-readable format.

★ 1Forks 3GoGitHub ↗Compare

README

TaskLedger

TaskLedger is a command-line interface (CLI) tool for tracking work and generating reports from a YAML log file. It helps you maintain a structured log of your daily tasks, calculate hours worked, and generate progress reports in both human-readable text and formatted HTML.

Disclaimer: AI-Assisted Development

This project heavily utilizes artificial intelligence for code generation. While AI has been a powerful tool in the development process, it's important to understand the following:

  • No Guarantees: The code is provided on an "as-is" basis. There is no guarantee that it is free of bugs, security vulnerabilities, or other issues.
  • Use with Caution: You are solely responsible for any outcomes that result from using this code. Always review and test the code thoroughly before implementing it in a production environment.
  • AI Is Not Perfect: The AI may have generated code that is suboptimal or contains inaccuracies.

By using the code in this repository, you acknowledge and agree to these terms.

Features

  • Log daily work entries, including tasks, status, and blockers.
  • Calculate total hours worked for any given day or date range.
  • Generate human-readable reports with emoji sections:
    • 🦀 Thing I've been working on - Completed tasks grouped by Jira ticket
    • :starfleet: Thing I plan on working on next - In-progress tasks without blockers
    • 🤦 Thing that is blocking me - Tasks with blockers that need attention
  • JIRA Integration:
    • Automatic conversion of JIRA ticket references to clickable links
    • Fetch and display JIRA ticket summaries (when JIRA_PAT is configured)
    • Support for both ticket IDs and full JIRA URLs
  • HTML Output Options:
    • Export reports as formatted HTML files
    • Automatically open HTML reports in default browser
    • Copy HTML to system clipboard (when clipboard tools are available)
    • Display HTML source in terminal
  • Support for GitHub PR tracking and upnext descriptions
  • Simple and extensible command structure powered by Cobra
  • Structured logging with slog for easy integration with other tools

Installation & Setup

  1. Clone the repository:

    git clone [https://github.com/your-username/taskledger.git](https://github.com/your-username/taskledger.git)
    cd taskledger
  2. Initialize Go Module (if not already done):

    go mod init [github.com/your-username/taskledger](https://github.com/your-username/taskledger)
    go mod tidy
  3. Build the binary: Use the provided Makefile to build the application.

    make build

    This will create an executable at ./bin/taskledger.

The worklog.yml File

TaskLedger reads from a worklog.yml file in the project root by default. You can create this file and structure it as follows:

# A log of work, organized by date.
# Each date is a top-level key in "YYYY-MM-DD" format.
"2024-07-26":
  work_log:
    - start_time: "09:05"
      end_time: "12:15"
    - start_time: "13:00"
      end_time: "17:30"
  tasks:
    - jira_ticket: "PROJ-1234"
      description: "Implemented a new OAuth 2.0 authentication flow for user login. This included front-end and back-end changes."
      status: "completed" # Can be: not started, in progress, completed
      qc_goal: "Q1-2024-Strategic-5" # Optional: for tracking quarterly goals
      github_pr: "https://github.com/example/repo/pull/123"
      upnext_description: ""
      blocker: "" # Leave empty if not blocked

    # Alternative: Use descriptions array for multiple updates on same ticket
    - jira_ticket: "PROJ-2000"
      descriptions:
        - "Morning: Reviewed architecture and identified performance issues"
        - "Afternoon: Implemented caching layer for database queries"
        - "Evening: Verified 40% improvement in response times"
      status: "completed"
      github_pr: "https://github.com/example/repo/pull/456"
      upnext_description: ""
      blocker: ""

"2024-07-27":
  work_log:
    - start_time: "09:00"
      end_time: "17:00"
  tasks:
    - jira_ticket: "PROJ-5678"
      description: "Investigating a bug where the quarterly report fails to generate for large datasets. The issue seems to be a memory leak."
      status: "in progress"
      github_pr: ""
      upnext_description: "Continue debugging the memory leak issue"
      blocker: "Waiting for access to the production database logs to replicate the issue."

JIRA Integration

TaskLedger can automatically convert JIRA ticket references into clickable links and fetch ticket summaries from the Red Hat JIRA instance.

Slack Integration

TaskLedger's HTML output is specifically optimized for Slack compatibility:

  • Nested List Structure: HTML reports use proper <ul> and <li> tags that Slack interprets correctly
  • Simple Formatting: Removes complex CSS that Slack doesn't support
  • Copy/Paste Friendly: HTML can be copied directly from browser and pasted into Slack with preserved formatting
  • Maintains Hierarchy: JIRA tickets appear as main bullets with task details as sub-bullets

Usage for Slack: Generate an HTML report, open it in your browser with --open-html, then copy the content and paste directly into Slack for properly formatted status updates.

Configuration

To enable JIRA ticket summary fetching, set the JIRA_PAT environment variable with your Personal Access Token:

export JIRA_PAT="your_personal_access_token_here"

Getting a JIRA Personal Access Token

  1. Log into Red Hat JIRA
  2. Go to your Account Settings → Security → Create and manage API tokens
  3. Click Create API token
  4. Give it a name (e.g., "TaskLedger CLI")
  5. Copy the generated token and set it as the JIRA_PAT environment variable

JIRA Integration Features

  • Without JIRA_PAT: JIRA references become clickable links (e.g., CNTRLPLANE-123 → link to ticket)
  • With JIRA_PAT: Links include ticket summaries (e.g., CNTRLPLANE-123: FBC Integration)
  • Supported formats:
    • Ticket IDs: PROJ-123, CNTRLPLANE-456
    • Full URLs: https://issues.redhat.com/browse/PROJ-123
  • Error handling: If API calls fail, falls back to basic links with warning logs

Example YAML with JIRA Integration

"2024-07-26":
  tasks:
    - jira_ticket: "CNTRLPLANE-123"  # Will become a clickable link
      description: "Implemented FBC integration"
      status: "completed"
    - jira_ticket: "https://issues.redhat.com/browse/PROJ-456"  # Also works with full URLs
      description: "Bug investigation"
      status: "in progress"

Usage

Here are some examples of how to run the CLI tool from your terminal.

Calculating Hours

  • Calculate hours for a single day:

    ./bin/taskledger hours --start-date=2024-07-26
  • Calculate total hours over a date range:

    ./bin/taskledger hours --start-date=2024-07-26 --end-date=2024-07-27
  • Calculate total hours for all entries in the log:

    ./bin/taskledger hours

Generating Reports

  • Generate a report for a single day:

    ./bin/taskledger report --start-date=2024-07-27
  • Generate a report for a date range:

    ./bin/taskledger report --start-date=2024-07-26 --end-date=2024-07-27
  • Generate a report for all entries in the log:

    ./bin/taskledger report

HTML Output Options

TaskLedger can generate beautifully formatted HTML reports with clickable JIRA links and styled sections.

  • Save report as HTML file:

    ./bin/taskledger report --html-file report.html
  • Save and automatically open HTML file in browser:

    ./bin/taskledger report --html-file report.html --open-html
  • Copy HTML report to clipboard (when clipboard tools available):

    ./bin/taskledger report --copy-html
  • Display HTML source in terminal:

    ./bin/taskledger report --show-html
  • Combine options:

    # Generate HTML report with JIRA summaries, save to file, and auto-open
    export JIRA_PAT="your_token"
    ./bin/taskledger report --html-file weekly-report.html --open-html --start-date=2024-07-26 --end-date=2024-07-27
    
    # Generate HTML and both save to file and copy to clipboard
    ./bin/taskledger report --html-file report.html --copy-html --open-html

HTML Features:

  • Clean, modern styling with proper typography
  • Clickable JIRA ticket links (with summaries when JIRA_PAT is configured)
  • Clickable GitHub PR links
  • Responsive design that works in browsers and email clients
  • Professional formatting suitable for sharing with stakeholders
  • Cross-platform auto-open support (macOS, Linux, Windows)
  • Slack-compatible nested list structure for easy copy/paste

Sample Report Output

Work Report (2024-07-26 to 2024-07-27)
========================================
=======Autogenerated by TaskLedger=======

🦀 Thing I've been working on
    • PROJ-1234: 
        • Implemented a new OAuth 2.0 authentication flow for user login. This included front-end and back-end changes.
            • PR: https://github.com/example/repo/pull/123

:starfleet: Thing I plan on working on next
    • PROJ-5678
        • Continue debugging the memory leak issue

:facepalm: Thing that is blocking me or that I could use some help / discussion about
• PROJ-5678 
  • Blocker: Waiting for access to the production database logs to replicate the issue.

Using a Different Log File

  • You can target any YAML file using the --file flag.
    ./bin/taskledger report --file=./archive/old_log.yml

Getting Help

  • Get help for the main application:

    ./bin/taskledger --help
  • Get help for a specific subcommand:

    ./bin/taskledger hours --help
    ./bin/taskledger report --help

Important: Task Grouping Behavior

The jira_ticket field serves as a unique identifier for grouping related tasks. TaskLedger tracks the progression of work items by grouping all tasks with the same jira_ticket value together. This is crucial for proper status tracking and report generation.

Key Points:

  1. Every task should have a unique jira_ticket identifier - even for non-Jira work
  2. Tasks are grouped by jira_ticket - multiple entries with the same identifier are treated as updates to the same work item
  3. Status progression is tracked chronologically - the most recent task entry for each jira_ticket determines current status
  4. Completed tasks disappear from "next up" - when the latest entry for a jira_ticket is marked "completed", it won't appear in future planning sections

Examples of Good jira_ticket Values:

# Official Jira tickets
jira_ticket: "PROJ-1234"
jira_ticket: "https://company.atlassian.net/browse/PROJ-1234"

# Custom identifiers for non-Jira work
jira_ticket: "NO-JIRA: Update Documentation"
jira_ticket: "ADMIN-001: Setup New Environment" 
jira_ticket: "BUG-FIX: Login Page CSS Issue"
jira_ticket: "RESEARCH: Evaluate New Framework"

What Happens Without Unique Identifiers:

If you leave jira_ticket empty or use the same value for unrelated tasks, TaskLedger cannot properly track task progression, and you may see completed work still appearing in "next up" sections.

YAML Fields Reference

Task Fields

  • jira_ticket: Required - Unique identifier for grouping related tasks (Jira ticket ID, URL, or custom identifier)
  • description: Single task description (use this OR descriptions, not both)
  • descriptions: Array of multiple descriptions for the same task - useful for tracking multiple updates throughout the day (alternative to description)
  • status: Task status - "completed", "in progress", or "not started"
  • qc_goal: Quarterly connect goal ID for personal tracking (optional, not displayed in reports)
  • github_pr: GitHub pull request URL
  • upnext_description: Specific description for next up tasks
  • blocker: Description of what's blocking the task (if any)

Claude Code Plugin

TaskLedger includes a Claude Code plugin that enables automatic JIRA ticket updates directly from your worklog.

Installation

Install the plugin from the Claude Code marketplace:

claude plugins add taskledger

Or install directly from the repository:

claude plugins add github:bryan-cox/taskledger

Prerequisites

  • Claude Code CLI installed
  • Atlassian JIRA MCP server configured (provides JIRA API access)

Commands

/update-jira

Post work report comments to JIRA tickets from your worklog.yml file.

# Preview what would be posted (dry run)
/update-jira --dry-run

# Update tickets for today
/update-jira

# Update tickets for a specific date range
/update-jira --start-date 2025-01-06 --end-date 2025-01-07

Features:

  • Reads tasks from worklog.yml and groups by JIRA ticket
  • Generates formatted comments in Jira wiki markup
  • Checks for duplicate comments to avoid spam
  • Shows preview and asks for confirmation before posting
  • Includes work completed, PRs, next steps, and blockers

Comment Format:

h2. Status Update: 2025-01-06 to 2025-01-07

*Work Completed:*
* Implemented feature X
* Fixed bug in Y component

*Pull Requests:*
* [PR #123|https://github.com/org/repo/pull/123]

*Next Steps:* Complete unit tests and submit for review

----
_Generated via TaskLedger /update-jira_

Arguments:

  • --start-date YYYY-MM-DD: Start of date range (defaults to today)
  • --end-date YYYY-MM-DD: End of date range (defaults to today)
  • --dry-run: Preview mode - shows what would be posted without actually posting

Contributors

bryan-coxcelebdornrb

Issues