This document outlines the steps to implement the GitHub PR Reporter application.
- 1. Initialize a new Dart console application.
- 2. Add dependencies to
pubspec.yaml:-
argsfor command-line argument parsing. -
githubfor interacting with the GitHub API. -
google_cloud_ai_generativelanguage_v1betafor the Gemini API. -
testandmocktailfor unit testing (as dev dependencies).
-
- 3. Create the initial directory and file structure:
-
bin/github_reporter.dart(main entry point) -
lib/github_reporter.dart(forReportGeneratorclass) -
lib/src/services/github_service.dart -
lib/src/services/gemini_service.dart -
test/directory for unit tests.
-
- 1. Implement
GitHubService:- Create the class structure in
github_service.dart. - Implement a method to fetch merged pull requests for a given repository and date range.
- Create the class structure in
- 2. Implement
GeminiService:- Create the class structure in
gemini_service.dart. - Implement a method to generate a text summary from a given input string (the PR details).
- Create the class structure in
- 1. Implement
ReportGenerator:- Create the class structure in
github_reporter.dart. - Implement the
generateReportmethod to orchestrate calls to the service classes. - Implement the logic to format the collected data into the final Markdown report string.
- Create the class structure in
- 1. Implement the entry point in
bin/github_reporter.dart:- Set up command-line argument parsing using the
argspackage. - Implement logic to handle API keys from both arguments and environment variables.
- Implement the default date range logic.
- Instantiate and run the
ReportGenerator. - Print the final report to
stdout. - Implement error handling to print messages to
stderrand exit.
- Set up command-line argument parsing using the
- 1. Write unit tests for
ReportGeneratorusing mocked services. - 2. Write unit tests for the service classes (
GitHubService) usingmocktail.
- 1. Add
dartdoccomments to all public APIs. - 2. Run
dart formaton the entire codebase. - 3. Review and update all documentation (
USAGE.md,DESIGN.md,IMPLEMENTATION.md).
- 1. Implement a system instruction for Gemini to guide summary creation.
- 2. Include the pull request diff in the data sent to Gemini for summarization.
- 1. Add a
--verboseflag to the CLI inbin/github_reporter.dart. - 2. Pass the verbose flag to the
ReportGenerator. - 3. In
ReportGenerator, if verbose mode is enabled:- Log a message when the
GitHubServiceis called to fetch pull requests. - Log the number of pull requests returned by the
GitHubService. - For each pull request, log a message before calling the
GeminiServiceto generate the summary. - Log a message after the summary is generated.
- Log a message when the
- 4. Update
USAGE.mdto document the new--verboseflag.
- 1. Add an
--output-fileoption to the CLI inbin/github_reporter.dart. - 2. In
bin/github_reporter.dart, if the--output-fileoption is provided, write the report to the specified file. - 3. If the
--output-fileoption is not provided, print the report to the console. - 4. Update
USAGE.mdto document the new--output-fileoption. - 5. Update
DESIGN.mdto reflect the new file output functionality.
- 1. Implement a retry loop in
GeminiService.getSummaryto handle transient errors from the Gemini API. - 2. The loop should attempt to generate a summary up to three times.
- 3. Implement exponential backoff for the delay between retries.
- 4. If all retries fail, throw an exception.
- 5. Update
DESIGN.mdto reflect the new retry logic.
- 1. Add a
--exclude-authoroption to the CLI inbin/github_reporter.dart. - 2. Modify
ReportGenerator.generateReportto accept a list of authors to exclude. - 3. Modify
GitHubService.getMergedPullRequeststo filter out pull requests from the specified authors using the GitHub search query. - 4. Update
USAGE.mdto document the new--exclude-authoroption. - 5. Update
DESIGN.mdto reflect the new filtering functionality.
- 1. Make the pull request ID in the Markdown report a clickable link to the pull request on GitHub.
- 2. Format the
Merged Attime in the report to Pacific Time, 12-hour clock, with only hours and minutes listed. - 3. Update
USAGE.mdto reflect these formatting changes. - 4. Update
DESIGN.mdto reflect these formatting changes.
- 1. Create a custom exception class
RateLimitExceptioningithub_service.dart. - 2. In
GitHubService, catch theRateLimitHitexception from thegithubpackage and re-throw it as aRateLimitException. - 3. In
bin/github_reporter.dart, add atry-catchblock to handle theRateLimitException. - 4. When a
RateLimitExceptionis caught, log a user-friendly error message tostderrand exit with a non-zero status code. - 5. Ensure that no report is written to a file if a
RateLimitExceptionoccurs. - 6. Update
DESIGN.mdto document the new rate limit handling mechanism. - 7. Write a unit test to verify that
RateLimitHitis correctly caught and re-thrown asRateLimitException.
- 1. Create a new
Issuemodel inlib/src/models/issue.dart. - 2. Add a
getClosedIssuesmethod toGitHubServiceto fetch closed issues within the specified date range. - 3. In
ReportGenerator, callgetClosedIssuesand add a new "Closed Issues" section to the report. - 4. Write unit tests for the new
getClosedIssuesmethod inGitHubService.
- 1. Update the
Issuemodel inlib/src/models/issue.dartto include reaction data. - 2. Update the
getClosedIssuesmethod inGitHubServiceto fetch reaction data for each issue. - 3. In
ReportGenerator, format and display the reaction data in the "Closed Issues" section of the report. - 4. Update the unit tests for
getClosedIssuesto include reaction data.
- 1. Create a new prompt for the Gemini service to generate an overall summary.
- 2. Create a new method in
GeminiServiceto generate the overall summary. - 3. In
ReportGenerator, call the new method and add the overall summary to the top of the report. - 4. Update
DESIGN.mdandUSAGE.mdto reflect the new overall summary feature. - 5. Update the unit tests to include the overall summary.
- 1. Create new data models for Hacker News stories and comments in
lib/src/models/. - 2. Create a new
HackerNewsServiceclass inlib/src/services/hacker_news_service.dart. - 3. Implement a method in
HackerNewsServiceto get the top stories from the Hacker News API. - 4. Implement a method in
HackerNewsServiceto get the details of a story, including its comments. - 5. Add unit tests for the
HackerNewsService. - 6. Integrate the
HackerNewsServiceinto theReportGeneratorto include a new "Hacker News" section in the report. - 7. Update
DESIGN.mdandUSAGE.mdto reflect the new Hacker News integration.
- 1. Create a new prompt for the Gemini service to generate a summary of summaries from multiple reports.
- 2. Create a new method in
GeminiServiceto generate the multi-report summary. - 3. In
ReportGenerator, call the new method and add the multi-report summary to the top of the combined report. - 4. Update
DESIGN.mdandUSAGE.mdto reflect the new multi-report summary feature. - 5. Update the unit tests to include the multi-report summary.
- 2025-11-03: Initialized a new Dart console application using
dart create. Addedargs,github, andgoogle_generative_aias dependencies, andtestandmocktailas dev dependencies. Created the initial directory and file structure for the services. - 2025-11-03: Implemented the initial
GitHubServiceandGeminiServiceclasses.GitHubServiceincludes a method to fetch merged pull requests within a date range, andGeminiServiceincludes a method to generate a summary from text. - 2025-11-03: Implemented the
ReportGeneratorclass. This class orchestrates calls to theGitHubServiceandGeminiServiceand formats the collected data into a Markdown report. - 2025-11-03: Implemented the command-line interface in
bin/github_reporter.dart. This includes argument parsing, API key handling from both arguments and environment variables, default date logic, and error handling. - 2025-11-03: Wrote unit tests for the
ReportGeneratorusing mockedGitHubServiceandGeminiServiceinstances. This ensures the report generation logic is working correctly. Despite verification that the mock is being called, a persistenttype 'Null' is not a subtype of type 'Future<String>'error is occurring, which is currently unresolved. - 2025-11-03: Wrote unit tests for the
GitHubService. TheGeminiServicecould not be tested as theGenerativeModelclass is final and cannot be mocked. This will be revisited. - 2025-11-03: The CLI tests were removed as they were not a reliable way to test the CLI. Manual testing will be performed.
- 2025-11-03: Added
dartdoccomments to all public APIs, formatted the entire codebase usingdart format, and reviewed all documentation. - 2025-11-03: Added a system instruction to the
GeminiServiceto guide the model in creating better summaries. - 2025-11-04: Modified the
--helpflag output inbin/github_reporter.dartto include a brief description and a sample invocation before the options list. - 2025-11-04: Updated
USAGE.mdto reflect the new--helpmessage format and the default date behavior. - 2025-11-04: Fixed the
stderrnot defined error inlib/github_reporter.dartby importingdart:io. - 2025-11-04: Added logging for the start and end dates in
ReportGenerator.generateReportwhen verbose mode is enabled. - 2025-11-04: Added logging for GitHub API requests in
GitHubServicewhen verbose mode is enabled. - 2025-11-04: Switched from using
PullRequestsServicetoSearchServiceinGitHubServiceto fetch merged pull requests more efficiently. Updated tests to reflect this change. - 2025-11-04: Switched from using a text file to a Dart file with a
conststring for the Gemini system instruction. This provides compile-time validation and better performance. - 2025-11-04: Added an
--output-fileoption to the CLI to allow writing the report to a file instead of printing it to the console. - 2025-11-04: Clarified in
USAGE.mdthat the--output-fileoption will overwrite existing files. - 2025-11-04: Implemented a retry mechanism with exponential backoff in
GeminiServiceto handle transient API errors.
- 2025-11-04: Refactored
maxRetriesinGeminiServiceto be a top-level constant for better maintainability. - 2025-11-06: Modified the default end date to be yesterday's date instead of the current date.
- 2025-11-06: Implemented filtering of pull requests by author using the
--exclude-authorCLI option. - 2025-11-06: Implemented clickable pull request IDs and Pacific Time formatting for
Merged Attimes in the report. - 2025-11-06: Made the author's name in the report a clickable link to their GitHub profile.
- 2025-11-11: Added the
summarizeMultiReportmethod toGeminiServiceand thecreateMultiReportSummaryPrompttoprompts.dartto support summarizing summaries from multiple reports.
- 2026-01-22: Fixed an issue where the application would hang after execution by properly disposing of
http.Clientinstances inGitHubServiceandHackerNewsService.