Automating my work diary with AI

Picture by Gemini Nano Banana Pro - Prompt: Generate a 1920x1080 wallpaper in 8-bit pixel art style.Subject: A cute AI robot sitting in the center, writing in a diary with a feather quill.Composition: The robot is perfectly centered with a padding of approximately 20% (1/5th) of empty space around it.Background: A vertical gradient background emulating a simple horizon line. Use exactly two solid colors for the gradient, choosing randomly from this list: [Green, Blue, Purple, Light Green, Cyan].Style: Retro, clean pixel art, minimalist.

As someone who is always looking for the next challenge, I don’t usually bother keeping track of completed tasks. Still, it’s very useful to be able to look back and see what I have achieved in the past.

Because of this, it was always hard for me to remember what I did in the previous quarter when preparing my performance review. I started wondering how I could automate this task and took the opportunity to experiment with AI tools.

My first idea was to focus on a specific solution, get some daily stats (commits, PRs, comments, etc.) from GitHub, as for a developer it is something very representative of the work done in a day.

The next step was to use an AI model to generate a summary of the day based on these stats, so I can have a concise and clear description of what I did in a human-readable format.

And the last step was to store these summaries in a structured way, I decided to use https://obsidian.md/ as it is a great tool for note taking and knowledge management, and it allows me to easily organize and search my work diary.

This this simple idea in mind, I write a definition document with the requirements and the steps to follow, and used GitHub Copilot to create a plan, and execute it.

The result, in 2-3 iterations with the agent, was a simple CLI tool that runs daily, fetches the GitHub stats, generates the summary using an AI model, and stores the summary in a repo which contains my Obsidian vault.

I could validate the results and they were amazing, as example this real output for a day:

# Work Diary - 2026-01-15

## Summary

Today I primarily focused on improving the developer experience around dialog management within the `factorialco/f0` repository. I created a new `useDialog` hook designed to simplify the process of opening and managing dialogs, reducing the amount of boilerplate code required.

Pull request #3242 introduces this new hook, showcasing a more streamlined approach compared to the previous method. The goal is to provide a smoother and more intuitive way for developers to integrate dialogs into the application. This work aims to improve code maintainability and reduce the potential for errors related to dialog state management.

Going further

I understood the potential of these tools, so I rethought the architecture to make it more flexible and extensible. I found that:

  • not only GitHub stats are useful; other sources like Slack, email, and Jira can also be valuable
  • the output format doesn’t always need to be Markdown
  • sometimes I might want to send the summary to different places like email or Slack instead of (or in addition to) a file

With this in mind I redesigned the architecture around a plugin‑based system that follows a 3 + 1 step process:

  • Input (plugins): collect data from different sources (GitHub, Slack, email, Jira, etc.) and provide a prompt to the AI model to summarize that data.

  • AI summarizer (core): takes the data from the input plugins and generates a summary using an AI model.

  • Formatter (plugin): combines all the plugin summaries and formats them into different representations (Markdown, HTML, plain text, etc.).

  • Output (plugins): take the formatter output and store, print, or send the summary to different destinations.

This way I can easily add new input sources, change the AI model, add new formatters or output destinations without changing the core logic of the application.

Example workflow

A workflow similar to the one in the first iteration looks like this:

ai:
  provider: google
  model: gemini-2.5-flash
  apiKey: env:GOOGLE_API_KEY

inputs:
  - plugin: github
    config:
      token: env:GH_READ_TOKEN
      username: env:GH_USERNAME
  - plugin: email
    config:
      provider: gmail
      host: imap.gmail.com
      port: 993
      secure: true
      user: env:IMAP_USER
      password: env:IMAP_PASSWORD
      mailbox: "[Gmail]/Todos"   # pulls everything
      sentMailbox: "[Gmail]/Enviados"  # typical Gmail sent folder
      maxMessages: 200
      
formatter:
  plugin: markdown

outputs:
  - plugin: console
  - plugin: file
    config:
      path: '~/workdiary-{date}.md'
      mode: merge # Don't be worried if the file exists, just append the new summary or update the previous one as it wraps the content with markers  

Note the use of env: to get the API keys and other sensitive data from environment variables, so they are not stored in plain text in the workflow file. When the tool runs, it replaces these placeholders with the actual values from the environment.

Then run the tool to generate the work diary:

$ work-diary --workflow ./workflow.yaml

Show me the code!

I thought this tool could be useful for other people, so I released it as open source: https://github.com/sergiocarracedo/work-diary. If you want to run it on your machine you can follow the instructions in SETUP.md.

The project is still in early stages, but if you want to contribute with new plugins, features, etc. you are welcome!

Running it as a scheduled task

To be truly valuable, this tool needs to run every day. There are many ways to achieve that, but I decided to use GitHub Actions because it is easy to set up and maintain. The repository includes a reusable GitHub Action (sergiocarracedo/work-diary@v1.1.0) that you can use in your own repo to run the tool daily.

This is the workflow I use in my repo to run the tool at the end of each day and commit the changes to the Obsidian repo:

# .github/workflows/work-diary.yml
name: Work Diary

on:
  schedule:
    - cron: "30 23 * * *"
  workflow_dispatch:
    inputs:
      date:
        description: "Target date (YYYY-MM-DD, UTC). Defaults to today."
        required: false
        type: string

jobs:
  diary:
    permissions:
      contents: write
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Run Work Diary
        uses: sergiocarracedo/work-diary@v1.1.0
        env:
          AI_PROVIDER: 'google'
          AI_MODEL: 'gemini-2.5-flash'
          AI_APIKEY: ${{ secrets.GEMINI_API_KEY }}
          GH_READ_TOKEN: ${{ secrets.GH_READ_TOKEN }}
          GH_USERNAME: ${{ secrets.GH_USERNAME }}
        with:
          config: |
            ai:
              provider: env:AI_PROVIDER
              model: env:AI_MODEL
              apiKey: env:AI_APIKEY

            inputs:
              - plugin: github
                config:
                  token: env:GH_READ_TOKEN
                  username: env:GH_USERNAME

            formatter:
              plugin: markdown

            outputs:
              - plugin: console
              - plugin: file
                config:
                  path: "Daily Notes/{date}.md"
                  mode: merge

      - name: Commit and push diary changes
        env:
          GIT_AUTHOR_NAME: github-actions[bot]
          GIT_AUTHOR_EMAIL: github-actions[bot]@users.noreply.github.com
          GIT_COMMITTER_NAME: github-actions[bot]
          GIT_COMMITTER_EMAIL: github-actions[bot]@users.noreply.github.com
        run: |
          git status --porcelain
          if git status --porcelain | grep .; then
            git config user.name "$GIT_AUTHOR_NAME"
            git config user.email "$GIT_AUTHOR_EMAIL"
            git add .
            git commit -m "chore: update work diary"
            git push
          else
            echo "No changes to commit."
          fi

This workflow runs every day at 23

UTC, and you can adjust the cron expression to fit your needs. It checks out the repository, runs the work-diary tool with the specified configuration, and then commits and pushes any changes to the repository.

Conclusion

Automating my work diary with AI has been a great experience. It has saved me time and effort and allowed me to focus on more important tasks. It also gives me a better overview of my work, and I’m pretty sure it will help me a lot in the future when I need to prepare my performance reviews. 😉😉

If you are interested in other input sources, formatters or output plugins, feel free to open an issue or a PR in the work-diary. Providing feedback and suggestions is always welcome!

Disclaimer

No AI models were harmed during the making of this tool, well I stressed them a little bit 😂