Created
August 4, 2025 14:08
-
-
Save cortfritz/1454cbaff6d040758acd4aa2d2877414 to your computer and use it in GitHub Desktop.
elixir mix task version of harper reed's feb 2025 llm workflow
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
# Harper's post: https://harper.blog/2025/02/16/my-llm-codegen-workflow-atm/ | |
# | |
# I mostly copied his file based workflow here | |
# | |
defmodule Mix.Tasks.Ai do | |
use Mix.Task | |
@shortdoc "AI-assisted development workflow tasks" | |
@moduledoc """ | |
AI-assisted development workflow tasks for code analysis and automation. | |
## Usage | |
mix ai <subcommand> [options] | |
## Available Subcommands | |
### Bundle Management | |
mix ai clean # Clean old bundles and generate fresh repomix output | |
mix ai copy # Copy bundle to clipboard for external LLM use | |
### Code Analysis | |
mix ai review # Generate code review prompt + bundle (clipboard) | |
mix ai tests # Generate missing tests prompt + bundle (clipboard) | |
mix ai readme # Generate README prompt + bundle (clipboard) | |
### Issue Management | |
mix ai issues # Generate GitHub issues prompt + bundle (clipboard) | |
mix ai issues.gen # Interactive GitHub issues generation workflow | |
mix ai issues.post # Post issues from issues.txt via gh CLI | |
mix ai prompts # Generate issue prompts + bundle (clipboard) | |
## Examples | |
mix ai clean # Clean and regenerate bundle | |
mix ai copy # Copy bundle to clipboard | |
mix ai review # Get code review prompt ready for LLM | |
mix ai issues.gen # Full workflow: prompt → LLM → save → post | |
## Files Used | |
- `repomix-output.txt` - Generated bundle file | |
- `issues.txt` - LLM-generated issues for posting | |
## Requirements | |
- `repomix` installed for bundle generation | |
- `gh` CLI for GitHub issue posting | |
- Clipboard access (pbcopy/pbpaste) | |
""" | |
@valid_subcommands ~w[clean copy review tests readme issues issues.gen issues.post prompts help] | |
def run([]), do: run(["help"]) | |
def run(["help"]) do | |
Mix.shell().info(@moduledoc) | |
end | |
def run([subcommand | args]) when subcommand in @valid_subcommands do | |
case subcommand do | |
"clean" -> clean_bundles(args) | |
"copy" -> copy_bundle(args) | |
"review" -> generate_review_prompt(args) | |
"tests" -> generate_tests_prompt(args) | |
"readme" -> generate_readme_prompt(args) | |
"issues" -> generate_issues_prompt(args) | |
"issues.gen" -> generate_issues_workflow(args) | |
"issues.post" -> post_issues(args) | |
"prompts" -> generate_issue_prompts(args) | |
end | |
end | |
def run([invalid_subcommand | _]) do | |
Mix.shell().error("Unknown subcommand: #{invalid_subcommand}") | |
Mix.shell().info("Valid subcommands: #{Enum.join(@valid_subcommands, ", ")}") | |
Mix.shell().info("Run `mix ai help` for detailed usage information.") | |
end | |
# Clean old bundles and regenerate | |
defp clean_bundles(_args) do | |
Mix.shell().info("Cleaning old bundles...") | |
# Clean up old files | |
File.rm("repomix-output.txt") | |
File.rm("code-bundle.txt") | |
# Generate new bundle | |
case System.cmd("repomix", ["--output", "repomix-output.txt"]) do | |
{_output, 0} -> | |
Mix.shell().info("✓ Fresh bundle generated: repomix-output.txt") | |
{error, _} -> | |
Mix.shell().error("Failed to generate bundle: #{error}") | |
end | |
end | |
# Copy bundle to clipboard | |
defp copy_bundle(_args) do | |
if File.exists?("repomix-output.txt") do | |
case System.cmd("bash", ["-c", "cat repomix-output.txt | pbcopy"]) do | |
{_, 0} -> | |
Mix.shell().info("✓ Bundle copied to clipboard") | |
{error, _} -> | |
Mix.shell().error("Failed to copy to clipboard: #{error}") | |
end | |
else | |
Mix.shell().error("Bundle not found. Run `mix ai clean` first.") | |
end | |
end | |
# Generate code review prompt | |
defp generate_review_prompt(_args) do | |
prompt = """ | |
Please review this codebase for: | |
- Code quality and best practices | |
- Potential bugs and security issues | |
- Performance improvements | |
- Architecture suggestions | |
- Testing coverage gaps | |
Focus on actionable feedback with specific examples. | |
""" | |
copy_prompt_with_bundle(prompt, "Code review prompt + bundle copied to clipboard") | |
end | |
# Generate missing tests prompt | |
defp generate_tests_prompt(_args) do | |
prompt = """ | |
Analyze this Elixir/Phoenix codebase and identify missing test coverage. | |
Please generate test cases for: | |
- Untested functions and modules | |
- Edge cases and error conditions | |
- Integration scenarios | |
- LiveView interactions | |
- API endpoints | |
Follow ExUnit best practices and existing test patterns. | |
""" | |
copy_prompt_with_bundle(prompt, "Missing tests prompt + bundle copied to clipboard") | |
end | |
# Generate README prompt | |
defp generate_readme_prompt(_args) do | |
prompt = """ | |
Generate a comprehensive README.md for this Elixir/Phoenix project. | |
Include: | |
- Project overview and purpose | |
- Key features and architecture | |
- Installation and setup instructions | |
- Usage examples and API documentation | |
- Development workflow | |
- Contributing guidelines | |
- Deployment information | |
Base the content on the actual codebase structure and functionality. | |
""" | |
copy_prompt_with_bundle(prompt, "README generation prompt + bundle copied to clipboard") | |
end | |
# Generate GitHub issues prompt | |
defp generate_issues_prompt(_args) do | |
prompt = """ | |
Based on this codebase, generate 3-5 GitHub issues for bugs, features, and improvements. | |
Format each issue as: | |
TITLE: [Clear, concise title] | |
BODY: [Detailed description with acceptance criteria] | |
LABELS: [Comma-separated labels like 'bug', 'enhancement', 'documentation'] | |
--- | |
Focus on: | |
- Actual bugs or potential issues you can identify | |
- Meaningful feature enhancements | |
- Documentation improvements | |
- Performance optimizations | |
- Code quality improvements | |
""" | |
copy_prompt_with_bundle(prompt, "GitHub issues prompt + bundle copied to clipboard") | |
end | |
# Generate issue prompts | |
defp generate_issue_prompts(_args) do | |
prompt = """ | |
Generate detailed issue prompts for this codebase covering: | |
1. Bug reports for potential issues | |
2. Feature requests for enhancements | |
3. Documentation improvements needed | |
4. Testing requirements and gaps | |
5. Performance optimization opportunities | |
6. Security considerations | |
7. Code quality improvements | |
Make each prompt specific and actionable. | |
""" | |
copy_prompt_with_bundle(prompt, "Issue prompts + bundle copied to clipboard") | |
end | |
# Interactive GitHub issues workflow | |
defp generate_issues_workflow(_args) do | |
prompt = """ | |
Based on this codebase, generate 3-5 GitHub issues for bugs, features, and improvements. | |
Format each issue as: | |
TITLE: [Clear, concise title] | |
BODY: [Detailed description with acceptance criteria] | |
LABELS: [Comma-separated labels like 'bug', 'enhancement', 'documentation'] | |
--- | |
""" | |
if File.exists?("repomix-output.txt") do | |
bundle = File.read!("repomix-output.txt") | |
full_prompt = prompt <> "\n" <> bundle | |
temp_file = "/tmp/ai_prompt_#{:rand.uniform(99999)}.txt" | |
File.write!(temp_file, full_prompt) | |
case System.cmd("bash", ["-c", "cat #{temp_file} | pbcopy"]) do | |
{_, 0} -> | |
File.rm(temp_file) | |
Mix.shell().info("✓ Issues generation prompt + bundle copied to clipboard") | |
Mix.shell().info("") | |
Mix.shell().info("Next steps:") | |
Mix.shell().info("1. Paste into your LLM") | |
Mix.shell().info("2. Save the LLM response as 'issues.txt'") | |
Mix.shell().info("3. Run: mix ai issues.post") | |
{error, _} -> | |
File.rm(temp_file) | |
Mix.shell().error("Failed to copy to clipboard: #{error}") | |
end | |
else | |
Mix.shell().error("Bundle not found. Run `mix ai clean` first.") | |
end | |
end | |
# Post issues from issues.txt via gh CLI | |
defp post_issues(_args) do | |
if File.exists?("issues.txt") do | |
Mix.shell().info("Posting GitHub issues...") | |
case System.cmd("bash", ["priv/scripts/post_issues.sh"]) do | |
{output, 0} -> | |
Mix.shell().info("✓ Issues posted successfully!") | |
Mix.shell().info(output) | |
{error, _} -> | |
Mix.shell().error("Failed to post issues: #{error}") | |
end | |
else | |
Mix.shell().error("issues.txt not found. Run `mix ai issues.gen` first.") | |
end | |
end | |
# Helper to copy prompt + bundle to clipboard | |
defp copy_prompt_with_bundle(prompt, success_message) do | |
if File.exists?("repomix-output.txt") do | |
bundle = File.read!("repomix-output.txt") | |
full_content = prompt <> "\n" <> bundle | |
temp_file = "/tmp/ai_content_#{:rand.uniform(99999)}.txt" | |
File.write!(temp_file, full_content) | |
case System.cmd("bash", ["-c", "cat #{temp_file} | pbcopy"]) do | |
{_, 0} -> | |
File.rm(temp_file) | |
Mix.shell().info("✓ #{success_message}") | |
{error, _} -> | |
File.rm(temp_file) | |
Mix.shell().error("Failed to copy to clipboard: #{error}") | |
end | |
else | |
Mix.shell().error("Bundle not found. Run `mix ai clean` first.") | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment