Created
November 27, 2025 01:36
-
-
Save itsthatguy/309d065d95ce1b3588f2151912928a74 to your computer and use it in GitHub Desktop.
LangChain Patch Notes Generator - Jupyter Notebook
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "cells": [ | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "# Patch Notes Generator\n", | |
| "\n", | |
| "This notebook demonstrates how to build a LangChain agent/tool chain that generates customer-facing patch notes from GitHub PR descriptions and commit messages.\n", | |
| "\n", | |
| "## Features\n", | |
| "- Fetch GitHub PR descriptions and commit messages\n", | |
| "- Transform technical changes into customer-friendly updates\n", | |
| "- Generate structured patch notes\n", | |
| "- Track what's been done since last update" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## Setup and Imports" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "✓ Imports loaded successfully\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "import os\n", | |
| "from datetime import datetime, timedelta\n", | |
| "\n", | |
| "from dotenv import load_dotenv\n", | |
| "from langchain.agents import create_agent\n", | |
| "from langchain.tools import tool\n", | |
| "from langchain_ollama import ChatOllama\n", | |
| "\n", | |
| "# Load environment variables\n", | |
| "load_dotenv()\n", | |
| "\n", | |
| "print(\"✓ Imports loaded successfully\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## Configuration" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 2, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "GitHub Repo: armiger-gameworks/gm-dashboard-prototype\n", | |
| "Model: gpt-oss:latest\n", | |
| "GitHub Token: ✓ Set\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# GitHub configuration\n", | |
| "GITHUB_TOKEN = os.getenv(\"GITHUB_TOKEN\", \"your-github-token-here\")\n", | |
| "GITHUB_REPO = os.getenv(\"GITHUB_REPO\", \"owner/repo\") # e.g., \"armiger-gameworks/my-product\"\n", | |
| "\n", | |
| "# LLM configuration\n", | |
| "MODEL_NAME = os.getenv(\"OLLAMA_MODEL\", \"gpt-oss:latest\")\n", | |
| "\n", | |
| "print(f\"GitHub Repo: {GITHUB_REPO}\")\n", | |
| "print(f\"Model: {MODEL_NAME}\")\n", | |
| "print(f\"GitHub Token: {'✓ Set' if GITHUB_TOKEN != 'your-github-token-here' else '✗ Not set'}\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## Tool 1: Fetch GitHub PRs" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 3, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "✓ fetch_github_prs tool defined\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "@tool\n", | |
| "def fetch_github_prs(since_days: int = 7) -> str:\n", | |
| " \"\"\"\n", | |
| " Fetch merged GitHub pull requests from the last N days.\n", | |
| " \n", | |
| " Args:\n", | |
| " since_days: Number of days to look back for PRs (default: 7)\n", | |
| " \n", | |
| " Returns:\n", | |
| " Formatted string with PR titles, descriptions, and merge dates\n", | |
| " \"\"\"\n", | |
| " try:\n", | |
| " from github import Github, Auth\n", | |
| " \n", | |
| " auth = Auth.Token(GITHUB_TOKEN)\n", | |
| " g = Github(auth=auth)\n", | |
| " repo = g.get_repo(GITHUB_REPO)\n", | |
| " \n", | |
| " since_date = datetime.now() - timedelta(days=since_days)\n", | |
| " \n", | |
| " pulls = repo.get_pulls(state='closed', sort='updated', direction='desc')\n", | |
| " \n", | |
| " merged_prs = []\n", | |
| " for pr in pulls:\n", | |
| " if pr.merged and pr.merged_at >= since_date:\n", | |
| " merged_prs.append({\n", | |
| " 'number': pr.number,\n", | |
| " 'title': pr.title,\n", | |
| " 'body': pr.body or 'No description provided',\n", | |
| " 'merged_at': pr.merged_at.strftime('%Y-%m-%d'),\n", | |
| " 'author': pr.user.login,\n", | |
| " 'labels': [label.name for label in pr.labels]\n", | |
| " })\n", | |
| " \n", | |
| " if not merged_prs:\n", | |
| " return f\"No merged PRs found in the last {since_days} days.\"\n", | |
| " \n", | |
| " result = f\"Found {len(merged_prs)} merged PRs in the last {since_days} days:\\n\\n\"\n", | |
| " for pr in merged_prs:\n", | |
| " result += f\"PR #{pr['number']}: {pr['title']}\\n\"\n", | |
| " result += f\"Merged: {pr['merged_at']} | Author: {pr['author']}\\n\"\n", | |
| " result += f\"Labels: {', '.join(pr['labels']) if pr['labels'] else 'None'}\\n\"\n", | |
| " result += f\"Description: {pr['body'][:200]}...\\n\\n\"\n", | |
| " \n", | |
| " return result\n", | |
| " \n", | |
| " except Exception as e:\n", | |
| " return f\"Error fetching PRs: {str(e)}\"\n", | |
| "\n", | |
| "print(\"✓ fetch_github_prs tool defined\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## Tool 2: Fetch Commit Messages" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 4, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "✓ fetch_commit_messages tool defined\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "@tool\n", | |
| "def fetch_commit_messages(since_days: int = 7, branch: str = \"main\") -> str:\n", | |
| " \"\"\"\n", | |
| " Fetch commit messages from a GitHub repository.\n", | |
| " \n", | |
| " Args:\n", | |
| " since_days: Number of days to look back for commits (default: 7)\n", | |
| " branch: Branch name to fetch commits from (default: \"main\")\n", | |
| " \n", | |
| " Returns:\n", | |
| " Formatted string with commit messages and metadata\n", | |
| " \"\"\"\n", | |
| " try:\n", | |
| " from github import Github, Auth\n", | |
| " \n", | |
| " auth = Auth.Token(GITHUB_TOKEN)\n", | |
| " g = Github(auth=auth)\n", | |
| " repo = g.get_repo(GITHUB_REPO)\n", | |
| " \n", | |
| " since_date = datetime.now() - timedelta(days=since_days)\n", | |
| " \n", | |
| " commits = repo.get_commits(sha=branch, since=since_date)\n", | |
| " \n", | |
| " commit_list = []\n", | |
| " for commit in commits:\n", | |
| " commit_list.append({\n", | |
| " 'sha': commit.sha[:7],\n", | |
| " 'message': commit.commit.message,\n", | |
| " 'author': commit.commit.author.name,\n", | |
| " 'date': commit.commit.author.date.strftime('%Y-%m-%d %H:%M')\n", | |
| " })\n", | |
| " \n", | |
| " if not commit_list:\n", | |
| " return f\"No commits found in the last {since_days} days on {branch} branch.\"\n", | |
| " \n", | |
| " result = f\"Found {len(commit_list)} commits in the last {since_days} days on {branch}:\\n\\n\"\n", | |
| " for c in commit_list:\n", | |
| " result += f\"[{c['sha']}] {c['date']} - {c['author']}\\n\"\n", | |
| " result += f\"{c['message']}\\n\\n\"\n", | |
| " \n", | |
| " return result\n", | |
| " \n", | |
| " except Exception as e:\n", | |
| " return f\"Error fetching commits: {str(e)}\"\n", | |
| "\n", | |
| "print(\"✓ fetch_commit_messages tool defined\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## Tool 3: Format Patch Notes" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 5, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "✓ format_patch_notes tool defined\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "@tool\n", | |
| "def format_patch_notes(changes_summary: str, version: str = \"TBD\") -> str:\n", | |
| " \"\"\"\n", | |
| " Format a summary of changes into customer-facing patch notes.\n", | |
| "\n", | |
| " Args:\n", | |
| " changes_summary: Summary of changes to format\n", | |
| " version: Version number for the patch notes (default: \"TBD\")\n", | |
| "\n", | |
| " Returns:\n", | |
| " Formatted patch notes in markdown\n", | |
| " \"\"\"\n", | |
| " date = datetime.now().strftime('%Y-%m-%d')\n", | |
| "\n", | |
| " template = f\"\"\"# Patch Notes - Version {version}\n", | |
| "\n", | |
| "**Release Date:** {date}\n", | |
| "\n", | |
| "## What's New\n", | |
| "\n", | |
| "{changes_summary}\n", | |
| "\n", | |
| "---\n", | |
| "*Thank you for your continued support!*\n", | |
| "\"\"\"\n", | |
| "\n", | |
| " return template\n", | |
| "\n", | |
| "\n", | |
| "print(\"✓ format_patch_notes tool defined\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## Initialize LLM and Agent" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 6, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "✓ Agent initialized successfully\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# Initialize the LLM\n", | |
| "llm = ChatOllama(model=MODEL_NAME, temperature=0.3)\n", | |
| "\n", | |
| "# Define available tools\n", | |
| "tools = [fetch_github_prs, fetch_commit_messages, format_patch_notes]\n", | |
| "\n", | |
| "# System prompt for the agent\n", | |
| "system_prompt = f\"\"\"You are a helpful assistant that generates customer-facing patch notes.\n", | |
| "\n", | |
| "The GitHub repository is configured as: {GITHUB_REPO}\n", | |
| "You have access to tools that can fetch data from this repository.\n", | |
| "\n", | |
| "Your job is to:\n", | |
| "1. AUTOMATICALLY use fetch_github_prs and fetch_commit_messages tools to get recent changes\n", | |
| "2. Analyze the technical changes\n", | |
| "3. Transform them into clear, customer-friendly language\n", | |
| "4. Focus on user benefits and new features\n", | |
| "5. Group related changes together\n", | |
| "6. Use the format_patch_notes tool to create the final output\n", | |
| "\n", | |
| "Guidelines:\n", | |
| "- Use simple, non-technical language\n", | |
| "- Emphasize user benefits, not implementation details\n", | |
| "- Group changes into categories: New Features, Improvements, Bug Fixes\n", | |
| "- Be concise but informative\n", | |
| "- Avoid jargon unless necessary\n", | |
| "\n", | |
| "IMPORTANT: When asked to generate patch notes, immediately use the tools to fetch data.\n", | |
| "Do NOT ask the user for the repository name - it's already configured as {GITHUB_REPO}.\"\"\"\n", | |
| "\n", | |
| "# Create the agent\n", | |
| "agent = create_agent(llm, tools, system_prompt=system_prompt)\n", | |
| "\n", | |
| "print(\"✓ Agent initialized successfully\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": null, | |
| "metadata": {}, | |
| "outputs": [], | |
| "source": [] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 7, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "\n", | |
| "================================================================================\n", | |
| "GENERATED PATCH NOTES\n", | |
| "================================================================================\n", | |
| "\n", | |
| "# Patch Notes – Version 1.0.0 \n", | |
| "**Release Date:** 2025‑11‑26 \n", | |
| "\n", | |
| "## What’s New\n", | |
| "\n", | |
| "### New Features \n", | |
| "- **Shop Widget** – Browse, search, and filter D&D item catalogs directly from your dashboard. Add items to your inventory or use them in your game. \n", | |
| "- **Multi‑Dashboard Support** – Organize dashboards into rooms and screens. Create, edit, and delete rooms, and navigate screens with breadcrumb navigation. All data is saved locally. \n", | |
| "- **Unified Toolbar** – A single bottom toolbar replaces three separate panels. Pick widgets, view data trays for characters, creatures, and locations, and access debug controls. \n", | |
| "- **GM Screen Dashboard** – A drag‑and‑drop dashboard inspired by Stream Deck. Includes initiative tracker, dice roller, entity cards, loot generator, and configurable button widgets. \n", | |
| "\n", | |
| "### Improvements \n", | |
| "- **Button Widget Settings** – Cleaner settings panel with auto‑generated labels, sound preview, and a new “Create New Screen” option. \n", | |
| "- **Widget Size & Placement** – Widgets now use their default and minimum sizes from the registry, preventing awkward resizing and overlap. New widgets are positioned automatically. \n", | |
| "- **Debug Overlay Control** – Move debug overlay state to the dashboard container for instant toolbar control. \n", | |
| "- **Drag‑and‑Drop Ref Hook** – A new hook fixes type mismatches, making drag‑and‑drop smoother. \n", | |
| "\n", | |
| "### Bug Fixes \n", | |
| "- Fixed duplicate screen creation when clicking navigation buttons. \n", | |
| "- Fixed widget sizing and placement bugs. \n", | |
| "- Fixed drag‑and‑drop reference errors. \n", | |
| "- Fixed page reload after seeding to ensure fresh data. \n", | |
| "- Minor UI and test fixes for a more stable experience. \n", | |
| "\n", | |
| "--- \n", | |
| "\n", | |
| "*Thank you for your continued support!*\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# Example: Generate patch notes for the last 7 days\n", | |
| "response = agent.invoke({\n", | |
| " \"messages\": [{\n", | |
| " \"role\": \"user\", \n", | |
| " \"content\": \"Call the fetch_github_prs tool with since_days=7, then call fetch_commit_messages with since_days=7 and branch='main', analyze the results, and create formatted patch notes using the format_patch_notes tool.\"\n", | |
| " }]\n", | |
| "})\n", | |
| "\n", | |
| "print(\"\\n\" + \"=\"*80)\n", | |
| "print(\"GENERATED PATCH NOTES\")\n", | |
| "print(\"=\"*80 + \"\\n\")\n", | |
| "print(response[\"messages\"][-1].content)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## Custom Query Examples" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 8, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "# Patch Notes – 2025‑11‑26 (Last 14 Days)\n", | |
| "\n", | |
| "## New Features\n", | |
| "- **Shop Widget** – Browse and filter D&D item catalogs right from your dashboard. \n", | |
| "- **Rooms & Screens** – Organize multiple dashboards into rooms and screens for easier campaign management. \n", | |
| "- **Unified Toolbar** – A single bottom‑bar replaces separate add‑widget, data‑tray, and debug panels, giving you quick access to all controls. \n", | |
| "- **Enhanced Button Widget Settings** – Auto‑generated labels, a “Create New Screen” option, and sound‑preview functionality.\n", | |
| "\n", | |
| "## Improvements\n", | |
| "- **Button Settings UI** – Redesigned for a clearer layout and auto‑label generation. \n", | |
| "- **Widget Sizing** – Widgets now use their default and minimum sizes from the registry, improving layout consistency. \n", | |
| "- **Debug Controls** – Moved to the toolbar for easier access. \n", | |
| "- **Drag‑and‑Drop Hook** – `useDragRef` resolves type mismatches, making interactions smoother. \n", | |
| "- **Seeding Refresh** – A full page reload after seeding ensures data is always up‑to‑date.\n", | |
| "\n", | |
| "## Bug Fixes\n", | |
| "- Prevented duplicate screen creation when navigation buttons are clicked. \n", | |
| "- Fixed widget sizing and positioning logic. \n", | |
| "- Resolved drag‑and‑drop ref type mismatch. \n", | |
| "- Corrected shop widget local state handling. \n", | |
| "- Ensured dashboard reload works reliably after seeding.\n", | |
| "\n", | |
| "*Thank you for using the GM Dashboard Prototype! Happy gaming!*\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# Example 1: Different time range\n", | |
| "response = agent.invoke({\n", | |
| " \"messages\": [{\"role\": \"user\", \"content\": \"What changes were made in the last 14 days?\"}]\n", | |
| "})\n", | |
| "print(response[\"messages\"][-1].content)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 9, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "# Patch Notes – Version TBD \n", | |
| "**Release Date:** 2025‑11‑26 \n", | |
| "\n", | |
| "## New Features\n", | |
| "\n", | |
| "- **Unified Toolbar** – A single bottom‑toolbar replaces the separate add‑widget button, data tray, and debug panel. It gives you a categorized widget picker, quick access to character/creature/location data, and debug controls (overlay toggle, opacity slider, seed data) for a faster, more intuitive dashboard experience. \n", | |
| "\n", | |
| "- **Shop Widget** – Browse a catalog of D&D items directly from the dashboard. Filter by category and rarity, preview items, and add them to your session with ease. \n", | |
| "\n", | |
| "- **Multi‑Dashboard Support** – Organize your campaigns with rooms and screens. Create, edit, and delete rooms, navigate a breadcrumb hierarchy, and enjoy local‑storage persistence for a seamless multi‑screen workflow. \n", | |
| "\n", | |
| "- **GM Screen Dashboard** – The core Stream‑Deck‑style interface now includes drag‑and‑drop widgets (initiative tracker, dice roller, entity cards, loot generator, button widgets), a dark theme, and full local persistence—all built for tabletop RPGs. \n", | |
| "\n", | |
| "--- \n", | |
| "\n", | |
| "*Thank you for your continued support!*\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# Example 2: Focus on specific type of changes\n", | |
| "response = agent.invoke({\n", | |
| " \"messages\": [{\"role\": \"user\", \"content\": \"Generate patch notes focusing only on new features added in the last 7 days.\"}]\n", | |
| "})\n", | |
| "print(response[\"messages\"][-1].content)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 10, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "**What the team has been working on in the last 7 days**\n", | |
| "\n", | |
| "| Category | Highlights |\n", | |
| "|----------|------------|\n", | |
| "| **New Features** | • Added a **Shop widget** that lets you browse, search, and filter D&D item catalogs directly on the dashboard.<br>• Introduced **Rooms & Screens** – you can now create multiple dashboards, organize them into rooms, and navigate with breadcrumbs.<br>• Built a **Unified Toolbar** at the bottom of the dashboard that replaces three separate panels. It gives quick access to a widget picker, a data tray (characters, creatures, locations), and debug controls. |\n", | |
| "| **Improvements** | • The **Button widget** now auto‑generates labels, offers a “Create New Screen” option, and previews sounds. <br>• Widgets now spawn with the correct default and minimum sizes from the registry, and the layout algorithm places them without overlap. <br>• The toolbar’s debug overlay state is lifted to the dashboard level, making it easier to control from anywhere. <br>• Updated the test infrastructure: new helper functions for setting up rooms and dashboards, and more reliable element selectors. |\n", | |
| "| **Bug Fixes** | • Fixed a duplicate screen creation bug when clicking navigation buttons. <br>• Resolved a ref‑type mismatch in the drag‑and‑drop system. <br>• Ensured the dashboard reloads properly after seeding data, so all new data appears immediately. <br>• Corrected the shop widget’s local state handling by replacing the deprecated Apollo LocalState API. |\n", | |
| "| **Other Updates** | • Switched the CI environment to use Bun and the official Playwright Docker image for faster builds.<br>• Added a custom ApolloLink for local GraphQL resolvers, improving compatibility.<br>• Minor refactors and cleanup across the codebase (e.g., removing unused components, improving test IDs). |\n", | |
| "\n", | |
| "**Bottom line:** The dashboard is now more powerful and easier to use. You can browse an item shop, organize your dashboards into rooms, and manage widgets from a single toolbar—all while enjoying a smoother, bug‑free experience.\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# Example 3: Summary of recent work\n", | |
| "response = agent.invoke({\n", | |
| " \"messages\": [{\"role\": \"user\", \"content\": \"Summarize what the team has been working on in the last 7 days.\"}]\n", | |
| "})\n", | |
| "print(response[\"messages\"][-1].content)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## Test Individual Tools\n", | |
| "\n", | |
| "You can test each tool independently:" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 11, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "Error fetching PRs: can't compare offset-naive and offset-aware datetimes\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# Test fetching PRs\n", | |
| "pr_data = fetch_github_prs.invoke({\"since_days\": 7})\n", | |
| "print(pr_data)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 12, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "Found 15 commits in the last 7 days on main:\n", | |
| "\n", | |
| "[dfcbf68] 2025-11-26 22:57 - Kevin Altman\n", | |
| "fix(button-widget): prevent duplicate screen creation on navigation button clicks\n", | |
| "\n", | |
| "Update button configuration after creating a new screen to reference the\n", | |
| "created screen ID instead of continuing to create new screens on each click.\n", | |
| "\n", | |
| "[470391b] 2025-11-26 21:36 - Kevin Altman\n", | |
| "feat(toolbar): consolidate add widget, data tray, and debug panel into unified toolbar\n", | |
| "\n", | |
| "Replace three separate UI components (AddComponentButton, DebugPanel, and\n", | |
| "bottom panel data tray) with a single persistent toolbar at the bottom of\n", | |
| "the dashboard. The toolbar provides:\n", | |
| "\n", | |
| "- Widget picker popup with categorized components\n", | |
| "- Data tray popup with tabs for characters, creatures, and locations\n", | |
| "- Debug controls popup with overlay toggle, opacity slider, and seed data\n", | |
| "\n", | |
| "Lift debug overlay state from DroppableGridLayout to DashboardContainer\n", | |
| "to enable toolbar control. Add comprehensive test suite covering all\n", | |
| "toolbar functionality, data integration, and debug controls.\n", | |
| "\n", | |
| "[038d64c] 2025-11-26 21:06 - Kevin Altman\n", | |
| "refactor(button-widget): improve settings UI with auto-label generation\n", | |
| "\n", | |
| "Redesign the button widget settings panel with a more intuitive layout.\n", | |
| "Add automatic label generation based on the selected action type\n", | |
| "(back, navigate, or sound), with manual override support.\n", | |
| "\n", | |
| "Includes new \"Create New Screen\" option for navigation actions and\n", | |
| "sound preview functionality with selectable sound effects.\n", | |
| "\n", | |
| "[29875d5] 2025-11-26 20:40 - Kevin Altman\n", | |
| "fix(widget): use registry default and min sizes when adding widgets\n", | |
| "\n", | |
| "Widgets now spawn with their configured defaultSize and minSize from the\n", | |
| "component registry instead of falling back to hardcoded 2x2. New widgets\n", | |
| "are positioned horizontally then vertically to fill available space.\n", | |
| "\n", | |
| "- Use registry defaultSize for widget initial dimensions\n", | |
| "- Apply registry minSize constraints to grid layout\n", | |
| "- Add position-finding algorithm to avoid widget overlap\n", | |
| "- Delete unused GridLayout.tsx component\n", | |
| "- Expose componentRegistry globally for testing\n", | |
| "- Add e2e tests verifying size and positioning behavior\n", | |
| "\n", | |
| "[16e985e] 2025-11-26 20:11 - Kevin Altman\n", | |
| "ci(playwright): install unzip dependency and upgrade setup-bun action\n", | |
| "\n", | |
| "The Playwright container image requires unzip for Bun installation.\n", | |
| "Upgrade setup-bun action from v1 to v2 for latest features.\n", | |
| "\n", | |
| "[6d73982] 2025-11-26 20:03 - Kevin Altman\n", | |
| "ci(playwright): switch to bun and playwright container image\n", | |
| "\n", | |
| "Use official Playwright Docker container to avoid browser installation\n", | |
| "overhead. Replace npm with bun for faster dependency installation and\n", | |
| "test execution.\n", | |
| "\n", | |
| "[a039669] 2025-11-26 20:03 - Kevin Altman\n", | |
| "fix(dnd): add useDragRef hook to resolve react-dnd ref type mismatch\n", | |
| "\n", | |
| "Create a custom hook that wraps react-dnd's drag connector function,\n", | |
| "resolving TypeScript errors when passing the drag ref directly to\n", | |
| "DOM elements.\n", | |
| "\n", | |
| "[0052910] 2025-11-26 19:44 - Kevin Altman\n", | |
| "test(shop-widget): fix tests with test-ids and improved element selection\n", | |
| "\n", | |
| "Add data-testid attributes to key shop widget elements (inventory count,\n", | |
| "catalog items count, category filters, rarity filters) for reliable test\n", | |
| "targeting. Update all Playwright tests to use common room/dashboard setup\n", | |
| "helper and more robust element selectors.\n", | |
| "\n", | |
| "[7ef428e] 2025-11-26 19:22 - Kevin Altman\n", | |
| "test(playwright): refactor tests to use room/dashboard architecture\n", | |
| "\n", | |
| "Add setupRoomAndDashboard helper to handle multi-room workflow.\n", | |
| "Update all test specs to create rooms before adding widgets, matching\n", | |
| "the new rooms-based navigation introduced in the dashboard feature.\n", | |
| "\n", | |
| "[f7c3e28] 2025-11-26 19:00 - Kevin Altman\n", | |
| "fix(shop-widget): replace LocalState with custom ApolloLink for local resolvers\n", | |
| "\n", | |
| "Apollo Client's LocalState API has compatibility issues. Replace it with a\n", | |
| "custom ApolloLink that intercepts queries with @local directives and routes\n", | |
| "them to merged resolvers directly.\n", | |
| "\n", | |
| "Update all Playwright tests to create a room before testing shop widget\n", | |
| "functionality, matching the new multi-dashboard flow.\n", | |
| "\n", | |
| "[d98a51d] 2025-11-26 18:06 - Kevin Altman\n", | |
| "feat(shop-widget): add shop widget with item catalog and playwright test infrastructure\n", | |
| "\n", | |
| "Implement a shop widget feature for the GM Screen dashboard that displays\n", | |
| "D&D item catalogs with search and filtering capabilities. Add comprehensive\n", | |
| "Playwright test coverage for dashboard management, dice roller, initiative\n", | |
| "tracker, and the new shop widget functionality.\n", | |
| "\n", | |
| "Key additions:\n", | |
| "- Shop widget with GraphQL-based item catalog service\n", | |
| "- Category and rarity filtering for items\\\n", | |
| "\n", | |
| "Extra addditions:\n", | |
| "- Claude Code agent configurations for Playwright test automation\n", | |
| "- GitHub Actions workflow for CI test execution\n", | |
| "- Test suites covering all major widget features\n", | |
| "\n", | |
| "[074d1d5] 2025-11-26 17:40 - Kevin Altman\n", | |
| "fix(dashboard): force page reload after seeding to ensure data refresh\n", | |
| "\n", | |
| "Replace navigation-based refresh with window.location.reload() after\n", | |
| "seeding dashboard data. This ensures all application state is properly\n", | |
| "reset with the seeded data.\n", | |
| "\n", | |
| "Also uses TanStack Router's navigate function for consistent routing\n", | |
| "when staying on the same dashboard after seed.\n", | |
| "\n", | |
| "[7942ca9] 2025-11-26 17:29 - Kevin Altman\n", | |
| "feat(dashboard): add rooms, screens, for multi-dashboard support\n", | |
| "\n", | |
| "Implement hierarchical room/screen organization allowing dungeon masters to\n", | |
| "group related dashboards.\n", | |
| "\n", | |
| "Key changes:\n", | |
| "- Add rooms feature with CRUD operations and local storage persistence\n", | |
| "- Create breadcrumb navigation for room/screen hierarchy\n", | |
| "- Upgrade dependencies including React 19, Apollo Client 4, and TailwindCSS 4\n", | |
| "- Restructure dashboard state management to support multi-screen workflows\n", | |
| "\n", | |
| "[5091746] 2025-11-26 06:35 - Kevin Altman\n", | |
| "feat: add gm screen dashboard for tabletop rpg dungeon masters\n", | |
| "\n", | |
| "Implement a customizable Stream Deck-style dashboard system with:\n", | |
| "\n", | |
| "- Grid-based drag-and-drop layout using react-grid-layout\n", | |
| "- Widget system with initiative tracker, dice roller, entity cards,\n", | |
| " loot generator, and configurable button widgets\n", | |
| "- Multi-dashboard support with localStorage/IndexedDB persistence\n", | |
| "- Bottom panel for dragging entities onto the dashboard\n", | |
| "- Dark theme with Pathfinder-inspired styling\n", | |
| "\n", | |
| "Built with Vite, React, TypeScript, TailwindCSS, TanStack Router,\n", | |
| "and Apollo Client reactive variables for state management.\n", | |
| "\n", | |
| "[76bac30] 2025-11-25 21:48 - Kevin Altman\n", | |
| "initial commit\n", | |
| "\n", | |
| "\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# Test fetching commits\n", | |
| "commit_data = fetch_commit_messages.invoke({\"since_days\": 7, \"branch\": \"main\"})\n", | |
| "print(commit_data)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 13, | |
| "metadata": {}, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "# Patch Notes - Version 1.2.0\n", | |
| "\n", | |
| "**Release Date:** 2025-11-26\n", | |
| "\n", | |
| "## What's New\n", | |
| "\n", | |
| "### New Features\n", | |
| "- Added user authentication\n", | |
| "- Implemented dark mode\n", | |
| "\n", | |
| "### Improvements\n", | |
| "- Improved page load speed by 50%\n", | |
| "- Enhanced mobile responsiveness\n", | |
| "\n", | |
| "### Bug Fixes\n", | |
| "- Fixed login redirect issue\n", | |
| "- Resolved payment processing errors\n", | |
| "\n", | |
| "\n", | |
| "---\n", | |
| "*Thank you for your continued support!*\n", | |
| "\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# Test formatting\n", | |
| "sample_summary = \"\"\"### New Features\n", | |
| "- Added user authentication\n", | |
| "- Implemented dark mode\n", | |
| "\n", | |
| "### Improvements\n", | |
| "- Improved page load speed by 50%\n", | |
| "- Enhanced mobile responsiveness\n", | |
| "\n", | |
| "### Bug Fixes\n", | |
| "- Fixed login redirect issue\n", | |
| "- Resolved payment processing errors\n", | |
| "\"\"\"\n", | |
| "\n", | |
| "formatted = format_patch_notes.invoke({\"changes_summary\": sample_summary, \"version\": \"1.2.0\"})\n", | |
| "print(formatted)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## Next Steps\n", | |
| "\n", | |
| "To use this notebook:\n", | |
| "\n", | |
| "1. **Set up environment variables** in a `.env` file:\n", | |
| " ```\n", | |
| " GITHUB_TOKEN=your_github_personal_access_token\n", | |
| " GITHUB_REPO=owner/repository-name\n", | |
| " OLLAMA_MODEL=llama3.2:latest\n", | |
| " ```\n", | |
| "\n", | |
| "2. **Install required dependencies**:\n", | |
| " ```bash\n", | |
| " uv pip install PyGithub jupyter ipykernel python-dotenv\n", | |
| " ```\n", | |
| "\n", | |
| "3. **Run the notebook**:\n", | |
| " ```bash\n", | |
| " uv run jupyter notebook patch_notes_generator.ipynb\n", | |
| " ```\n", | |
| "\n", | |
| "4. **Customize the tools** to match your workflow and repository structure\n", | |
| "\n", | |
| "5. **Extend with additional tools** such as:\n", | |
| " - Slack/Discord integration for posting patch notes\n", | |
| " - Database storage for tracking releases\n", | |
| " - Automated version number generation\n", | |
| " - Integration with issue trackers" | |
| ] | |
| } | |
| ], | |
| "metadata": { | |
| "kernelspec": { | |
| "display_name": "Python (ollama-agents devenv)", | |
| "language": "python", | |
| "name": "ollama-agents" | |
| }, | |
| "language_info": { | |
| "codemirror_mode": { | |
| "name": "ipython", | |
| "version": 3 | |
| }, | |
| "file_extension": ".py", | |
| "mimetype": "text/x-python", | |
| "name": "python", | |
| "nbconvert_exporter": "python", | |
| "pygments_lexer": "ipython3", | |
| "version": "3.12.12" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 4 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment