roast-ai 0.3.1 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yaml +2 -2
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +85 -0
  5. data/CLAUDE.md +106 -9
  6. data/Gemfile +4 -1
  7. data/Gemfile.lock +70 -16
  8. data/README.md +159 -8
  9. data/bin/console +1 -0
  10. data/bin/roast +1 -1
  11. data/claude-swarm.yml +210 -0
  12. data/docs/AGENT_STEPS.md +288 -0
  13. data/docs/VALIDATION.md +178 -0
  14. data/examples/agent_continue/add_documentation/prompt.md +5 -0
  15. data/examples/agent_continue/add_error_handling/prompt.md +5 -0
  16. data/examples/agent_continue/analyze_codebase/prompt.md +7 -0
  17. data/examples/agent_continue/combined_workflow.yml +24 -0
  18. data/examples/agent_continue/continue_adding_features/prompt.md +4 -0
  19. data/examples/agent_continue/create_integration_tests/prompt.md +3 -0
  20. data/examples/agent_continue/document_with_context/prompt.md +5 -0
  21. data/examples/agent_continue/explore_api/prompt.md +6 -0
  22. data/examples/agent_continue/implement_client/prompt.md +6 -0
  23. data/examples/agent_continue/inline_workflow.yml +20 -0
  24. data/examples/agent_continue/refactor_code/prompt.md +2 -0
  25. data/examples/agent_continue/verify_changes/prompt.md +6 -0
  26. data/examples/agent_continue/workflow.yml +27 -0
  27. data/examples/agent_workflow/README.md +75 -0
  28. data/examples/agent_workflow/apply_refactorings/prompt.md +22 -0
  29. data/examples/agent_workflow/identify_code_smells/prompt.md +15 -0
  30. data/examples/agent_workflow/summarize_improvements/prompt.md +18 -0
  31. data/examples/agent_workflow/workflow.png +0 -0
  32. data/examples/agent_workflow/workflow.yml +16 -0
  33. data/examples/api_workflow/workflow.png +0 -0
  34. data/examples/apply_diff_demo/README.md +58 -0
  35. data/examples/apply_diff_demo/apply_simple_change/prompt.md +13 -0
  36. data/examples/apply_diff_demo/create_sample_file/prompt.md +11 -0
  37. data/examples/apply_diff_demo/workflow.yml +24 -0
  38. data/examples/available_tools_demo/README.md +42 -0
  39. data/examples/available_tools_demo/analyze_files/prompt.md +6 -0
  40. data/examples/available_tools_demo/explore_directory/prompt.md +6 -0
  41. data/examples/available_tools_demo/workflow.png +0 -0
  42. data/examples/available_tools_demo/workflow.yml +32 -0
  43. data/examples/available_tools_demo/write_summary/prompt.md +6 -0
  44. data/examples/bash_prototyping/api_testing.png +0 -0
  45. data/examples/bash_prototyping/system_analysis.png +0 -0
  46. data/examples/case_when/detect_language/prompt.md +2 -2
  47. data/examples/case_when/workflow.png +0 -0
  48. data/examples/cmd/basic_workflow.png +0 -0
  49. data/examples/cmd/dev_workflow.png +0 -0
  50. data/examples/cmd/explorer_workflow.png +0 -0
  51. data/examples/conditional/simple_workflow.png +0 -0
  52. data/examples/conditional/workflow.png +0 -0
  53. data/examples/context_management_demo/README.md +43 -0
  54. data/examples/context_management_demo/workflow.yml +42 -0
  55. data/examples/direct_coerce_syntax/workflow.png +0 -0
  56. data/examples/dot_notation/workflow.png +0 -0
  57. data/examples/exit_on_error/workflow.png +0 -0
  58. data/examples/grading/run_coverage.rb +0 -2
  59. data/examples/grading/workflow.png +0 -0
  60. data/examples/interpolation/workflow.png +0 -0
  61. data/examples/interpolation/workflow.yml +1 -1
  62. data/examples/iteration/analyze_complexity/prompt.md +2 -2
  63. data/examples/iteration/generate_recommendations/prompt.md +2 -2
  64. data/examples/iteration/implement_fix/prompt.md +2 -2
  65. data/examples/iteration/prioritize_issues/prompt.md +1 -1
  66. data/examples/iteration/prompts/analyze_file.md +2 -2
  67. data/examples/iteration/prompts/generate_summary.md +1 -1
  68. data/examples/iteration/prompts/update_report.md +3 -3
  69. data/examples/iteration/prompts/write_report.md +3 -3
  70. data/examples/iteration/read_file/prompt.md +2 -2
  71. data/examples/iteration/select_next_issue/prompt.md +2 -2
  72. data/examples/iteration/update_fix_count/prompt.md +4 -4
  73. data/examples/iteration/verify_fix/prompt.md +3 -3
  74. data/examples/iteration/workflow.png +0 -0
  75. data/examples/json_handling/workflow.png +0 -0
  76. data/examples/mcp/README.md +3 -3
  77. data/examples/mcp/analyze_changes/prompt.md +1 -1
  78. data/examples/mcp/database_workflow.png +0 -0
  79. data/examples/mcp/database_workflow.yml +1 -1
  80. data/examples/mcp/env_demo/workflow.png +0 -0
  81. data/examples/mcp/fetch_pr_context/prompt.md +1 -1
  82. data/examples/mcp/filesystem_demo/workflow.png +0 -0
  83. data/examples/mcp/github_workflow.png +0 -0
  84. data/examples/mcp/github_workflow.yml +1 -1
  85. data/examples/mcp/multi_mcp_workflow.png +0 -0
  86. data/examples/mcp/post_review/prompt.md +1 -1
  87. data/examples/mcp/workflow.png +0 -0
  88. data/examples/no_model_fallback/README.md +17 -0
  89. data/examples/no_model_fallback/analyze_file/prompt.md +1 -0
  90. data/examples/no_model_fallback/analyze_patterns/prompt.md +27 -0
  91. data/examples/no_model_fallback/generate_report_for_md/prompt.md +10 -0
  92. data/examples/no_model_fallback/generate_report_for_rb/prompt.md +3 -0
  93. data/examples/no_model_fallback/sample.rb +42 -0
  94. data/examples/no_model_fallback/workflow.yml +19 -0
  95. data/examples/openrouter_example/workflow.png +0 -0
  96. data/examples/pre_post_processing/analyze_test_file/prompt.md +1 -1
  97. data/examples/pre_post_processing/improve_test_coverage/prompt.md +1 -1
  98. data/examples/pre_post_processing/optimize_test_performance/prompt.md +1 -1
  99. data/examples/pre_post_processing/post_processing/aggregate_metrics/prompt.md +2 -2
  100. data/examples/pre_post_processing/post_processing/generate_summary_report/prompt.md +1 -1
  101. data/examples/pre_post_processing/pre_processing/setup_test_environment/prompt.md +1 -1
  102. data/examples/pre_post_processing/validate_changes/prompt.md +2 -2
  103. data/examples/pre_post_processing/workflow.png +0 -0
  104. data/examples/rspec_to_minitest/workflow.png +0 -0
  105. data/examples/shared_config/example_with_shared_config/workflow.png +0 -0
  106. data/examples/shared_config/shared.png +0 -0
  107. data/examples/single_target_prepost/workflow.png +0 -0
  108. data/examples/smart_coercion_defaults/workflow.png +0 -0
  109. data/examples/step_configuration/workflow.png +0 -0
  110. data/examples/swarm_example.yml +25 -0
  111. data/examples/tool_config_example/workflow.png +0 -0
  112. data/examples/user_input/README.md +90 -0
  113. data/examples/user_input/funny_name/create_backstory/prompt.md +10 -0
  114. data/examples/user_input/funny_name/workflow.png +0 -0
  115. data/examples/user_input/funny_name/workflow.yml +26 -0
  116. data/examples/user_input/generate_summary/prompt.md +11 -0
  117. data/examples/user_input/simple_input_demo/workflow.png +0 -0
  118. data/examples/user_input/simple_input_demo/workflow.yml +35 -0
  119. data/examples/user_input/survey_workflow.png +0 -0
  120. data/examples/user_input/survey_workflow.yml +71 -0
  121. data/examples/user_input/welcome_message/prompt.md +3 -0
  122. data/examples/user_input/workflow.png +0 -0
  123. data/examples/user_input/workflow.yml +73 -0
  124. data/examples/workflow_generator/create_workflow_files/prompt.md +1 -1
  125. data/examples/workflow_generator/workflow.png +0 -0
  126. data/lib/roast/errors.rb +6 -4
  127. data/lib/roast/helpers/function_caching_interceptor.rb +0 -2
  128. data/lib/roast/helpers/logger.rb +12 -35
  129. data/lib/roast/helpers/minitest_coverage_runner.rb +0 -1
  130. data/lib/roast/helpers/prompt_loader.rb +0 -2
  131. data/lib/roast/helpers/timeout_handler.rb +91 -0
  132. data/lib/roast/resources/api_resource.rb +0 -4
  133. data/lib/roast/resources/url_resource.rb +0 -3
  134. data/lib/roast/resources.rb +0 -8
  135. data/lib/roast/services/context_threshold_checker.rb +42 -0
  136. data/lib/roast/services/token_counting_service.rb +44 -0
  137. data/lib/roast/tools/apply_diff.rb +128 -0
  138. data/lib/roast/tools/ask_user.rb +0 -2
  139. data/lib/roast/tools/bash.rb +12 -9
  140. data/lib/roast/tools/cmd.rb +29 -12
  141. data/lib/roast/tools/coding_agent.rb +65 -17
  142. data/lib/roast/tools/context_summarizer.rb +108 -0
  143. data/lib/roast/tools/grep.rb +0 -3
  144. data/lib/roast/tools/helpers/coding_agent_message_formatter.rb +1 -4
  145. data/lib/roast/tools/read_file.rb +0 -2
  146. data/lib/roast/tools/search_file.rb +0 -2
  147. data/lib/roast/tools/swarm.rb +124 -0
  148. data/lib/roast/tools/update_files.rb +0 -4
  149. data/lib/roast/tools/write_file.rb +0 -3
  150. data/lib/roast/tools.rb +0 -13
  151. data/lib/roast/value_objects/step_name.rb +14 -3
  152. data/lib/roast/value_objects/workflow_path.rb +0 -2
  153. data/lib/roast/value_objects.rb +4 -4
  154. data/lib/roast/version.rb +1 -1
  155. data/lib/roast/workflow/agent_step.rb +33 -0
  156. data/lib/roast/workflow/api_configuration.rb +0 -4
  157. data/lib/roast/workflow/base_iteration_step.rb +3 -6
  158. data/lib/roast/workflow/base_step.rb +54 -28
  159. data/lib/roast/workflow/base_workflow.rb +43 -23
  160. data/lib/roast/workflow/case_executor.rb +0 -1
  161. data/lib/roast/workflow/case_step.rb +0 -4
  162. data/lib/roast/workflow/command_executor.rb +0 -2
  163. data/lib/roast/workflow/conditional_executor.rb +0 -1
  164. data/lib/roast/workflow/conditional_step.rb +0 -4
  165. data/lib/roast/workflow/configuration.rb +5 -67
  166. data/lib/roast/workflow/configuration_loader.rb +63 -3
  167. data/lib/roast/workflow/configuration_parser.rb +1 -7
  168. data/lib/roast/workflow/context_manager.rb +89 -0
  169. data/lib/roast/workflow/dot_access_hash.rb +16 -1
  170. data/lib/roast/workflow/each_step.rb +1 -1
  171. data/lib/roast/workflow/error_handler.rb +0 -3
  172. data/lib/roast/workflow/expression_evaluator.rb +0 -3
  173. data/lib/roast/workflow/file_state_repository.rb +0 -5
  174. data/lib/roast/workflow/input_executor.rb +41 -0
  175. data/lib/roast/workflow/input_step.rb +163 -0
  176. data/lib/roast/workflow/iteration_executor.rb +0 -2
  177. data/lib/roast/workflow/output_handler.rb +1 -3
  178. data/lib/roast/workflow/output_manager.rb +0 -2
  179. data/lib/roast/workflow/repeat_step.rb +1 -1
  180. data/lib/roast/workflow/replay_handler.rb +1 -4
  181. data/lib/roast/workflow/resource_resolver.rb +0 -3
  182. data/lib/roast/workflow/session_manager.rb +0 -3
  183. data/lib/roast/workflow/sqlite_state_repository.rb +342 -0
  184. data/lib/roast/workflow/state_manager.rb +2 -4
  185. data/lib/roast/workflow/state_repository_factory.rb +36 -0
  186. data/lib/roast/workflow/step_completion_reporter.rb +27 -0
  187. data/lib/roast/workflow/step_executor_coordinator.rb +48 -24
  188. data/lib/roast/workflow/step_executor_factory.rb +0 -5
  189. data/lib/roast/workflow/step_executor_registry.rb +1 -4
  190. data/lib/roast/workflow/step_executor_with_reporting.rb +68 -0
  191. data/lib/roast/workflow/step_executors/hash_step_executor.rb +0 -3
  192. data/lib/roast/workflow/step_executors/parallel_step_executor.rb +0 -3
  193. data/lib/roast/workflow/step_executors/string_step_executor.rb +0 -2
  194. data/lib/roast/workflow/step_factory.rb +56 -0
  195. data/lib/roast/workflow/step_loader.rb +31 -17
  196. data/lib/roast/workflow/step_name_extractor.rb +84 -0
  197. data/lib/roast/workflow/step_orchestrator.rb +3 -2
  198. data/lib/roast/workflow/step_type_resolver.rb +28 -1
  199. data/lib/roast/workflow/validation_command.rb +197 -0
  200. data/lib/roast/workflow/validator.rb +0 -4
  201. data/lib/roast/workflow/validators/base_validator.rb +44 -0
  202. data/lib/roast/workflow/validators/dependency_validator.rb +223 -0
  203. data/lib/roast/workflow/validators/linting_validator.rb +113 -0
  204. data/lib/roast/workflow/validators/schema_validator.rb +90 -0
  205. data/lib/roast/workflow/validators/step_collector.rb +57 -0
  206. data/lib/roast/workflow/validators/validation_orchestrator.rb +52 -0
  207. data/lib/roast/workflow/workflow_executor.rb +11 -20
  208. data/lib/roast/workflow/workflow_initializer.rb +1 -8
  209. data/lib/roast/workflow/workflow_runner.rb +6 -7
  210. data/lib/roast/workflow.rb +0 -15
  211. data/lib/roast/workflow_diagram_generator.rb +298 -0
  212. data/lib/roast.rb +212 -10
  213. data/roast.gemspec +4 -2
  214. data/schema/workflow.json +123 -1
  215. metadata +143 -6
  216. data/lib/roast/helpers.rb +0 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4f94565fdc94547f9ab2fa57b401930d189c2e63f5f31897165a07cf6828b10d
4
- data.tar.gz: '068450417abc06ed7fb98af7c36ec972d6671b23e0e85cfdadde8a934c327fdc'
3
+ metadata.gz: b31e95a8d65d0b1fa798c0baed8bcbf9249cc67fca752154865d914d01ffbd8d
4
+ data.tar.gz: 21205a0a50e2301dda0936e67b02d05af94085b0e383f859aec282827649ebb3
5
5
  SHA512:
6
- metadata.gz: 07e5a581c469a37d3f0371627c92ef0b465cfeb5e977a90221a3cdb7783193de7a1c6600df3b1235705ef65e0e76f566bf88730621172314d3bc0ba70adc5dc4
7
- data.tar.gz: 12e7ae70eee847f11eac8c4e593e11b5a94c0574634254a559d41d006e8fac01dc7b7c26fa2ba1a80fc13de0172ac810ff390e8bda2555e96489c0385f815537
6
+ metadata.gz: 80b5ceada69faff53f5893e9378e628474b103c3d6b60a8701be80b1bfe11cb6e4bde252670d890a2ae7e460d90d956daed7813d251cf6d84399ab70d321b0d8
7
+ data.tar.gz: 620e7d46fc6f7e9b10a71807f213ba101cb2bbd9a3bad073a153057bd67bc842cf74e4ffaa179596a2ed3655dc7a864c366034a37f4a720d2fd6faafa86f5541
@@ -23,8 +23,8 @@ jobs:
23
23
  BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
24
24
  steps:
25
25
  - uses: actions/checkout@v4
26
- - name: Install ripgrep
27
- run: sudo apt-get update && sudo apt-get install -y ripgrep
26
+ - name: Install dependencies
27
+ run: sudo apt-get update && sudo apt-get install -y ripgrep graphviz
28
28
  - uses: ruby/setup-ruby@v1
29
29
  with:
30
30
  ruby-version: ${{ matrix.ruby }}
data/.gitignore CHANGED
@@ -40,3 +40,4 @@ bin/ruby-rewrite
40
40
  bin/thor
41
41
 
42
42
  gemfiles/*.lock
43
+ bin/claude-swarm
data/CHANGELOG.md CHANGED
@@ -5,6 +5,91 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.4.1] - 2025-06-18
9
+
10
+ ### Added
11
+ - **SQLite session storage** as the default storage backend (#252)
12
+ - Provides better performance and advanced querying capabilities
13
+ - Sessions are stored in `~/.roast/sessions.db` by default (configurable via `ROAST_SESSIONS_DB`)
14
+ - New `roast sessions` command to list and filter stored sessions
15
+ - New `roast session <id>` command to view detailed session information
16
+ - Session cleanup with `roast sessions --cleanup --older-than <duration>`
17
+ - Filter sessions by status, workflow name, or age
18
+ - Maintains full backward compatibility with filesystem storage
19
+ - **`--file-storage` CLI option** to use legacy filesystem storage instead of SQLite
20
+ - Use `-f` or `--file-storage` flag to opt into filesystem storage
21
+ - Environment variable `ROAST_STATE_STORAGE=file` still supported for compatibility
22
+ - **Foundation for wait_for_event feature** (#251)
23
+ - New `roast resume` command infrastructure for resuming paused workflows
24
+ - Event storage and tracking in SQLite sessions table
25
+ - **Configurable agent step options** for CodingAgent (#266)
26
+ - New `continue` option for agent steps to maintain session context across multiple agent invocations
27
+ - New `include_context_summary` option to provide AI-generated workflow context summaries to agents
28
+ - Context summaries are intelligently tailored to the agent's specific task using LLM analysis
29
+ - Helps reduce token usage by including only relevant context information
30
+ - **Token consumption reporting** for step execution (#264)
31
+ - Displays token usage (prompt and completion) after each step execution
32
+ - Helps users monitor and optimize their LLM token consumption
33
+ - Automatically enabled for all workflow runs
34
+ - **Timeout functionality for bash and cmd steps** (#261)
35
+ - New `timeout` option for bash and cmd steps to prevent hanging commands
36
+ - Configurable timeout duration in seconds
37
+ - Commands are automatically terminated if they exceed the specified timeout
38
+ - Prevents workflows from getting stuck on unresponsive commands
39
+ - **Claude Swarm tool integration** (#254)
40
+ - New `Roast::Tools::Swarm` for integrating with Claude Swarm framework
41
+ - Enables using Swarm's multi-agent orchestration capabilities within Roast workflows
42
+ - Provides seamless handoffs between specialized AI agents
43
+ - **Workflow visualization with diagram command** (#256)
44
+ - New `roast diagram` command to generate visual representations of workflows
45
+ - Creates GraphViz-based diagrams showing workflow structure and flow
46
+ - Supports both DOT format output and PNG/SVG image generation
47
+ - Helps understand complex workflow logic at a glance
48
+ - **Comprehensive workflow validation** (#244)
49
+ - New `roast validate` command to check workflow syntax and structure
50
+ - Validates YAML syntax, step references, and configuration options
51
+ - Provides detailed error messages for invalid workflows
52
+ - Helps catch errors before running workflows
53
+ - **apply_diff tool** (#246)
54
+ - New built-in tool for applying unified diff patches to files
55
+ - Supports standard diff format for making precise file modifications
56
+ - Enables AI models to suggest changes in diff format
57
+ - More reliable than search-and-replace for complex edits
58
+ - **Model fallback mechanism** (#257)
59
+ - Workflows without explicit model configuration now use a sensible default
60
+ - Prevents errors when model is not specified at workflow or step level
61
+ - Improves user experience for simple workflows
62
+ - **Context management foundation for auto-compaction** (#264)
63
+ - Infrastructure for future automatic context size management
64
+ - Enables intelligent token usage optimization in long-running workflows
65
+
66
+ ### Changed
67
+ - Session storage now defaults to SQLite instead of filesystem
68
+ - Existing filesystem sessions remain accessible when using `--file-storage` flag
69
+ - No migration required - both storage backends can coexist
70
+
71
+ [0.4.1]: https://github.com/Shopify/roast/compare/v0.4.0...v0.4.1
72
+
73
+ ## [0.4.0] - 2025-06-12
74
+
75
+ ### Added
76
+ - **Input step type** for collecting user input during workflow execution (#154)
77
+ - Interactive prompts pause workflow execution to collect user input
78
+ - Supports multiple input types: `text` (default), `confirm`, `select`, and `password`
79
+ - `confirm` type provides yes/no prompts with boolean results
80
+ - `select` type allows choosing from a list of options
81
+ - `password` type masks input for sensitive data using io/console
82
+ - Input values are stored in workflow output and accessible via dot notation (e.g., `{{output.step_name}}`)
83
+ - Integrates with CLI::UI for consistent formatting and user experience
84
+ - **Agent step type** for direct pass-through to coding agents (#151)
85
+ - Steps prefixed with `^` send prompts directly to the CodingAgent tool
86
+ - Supports both file-based and inline agent prompts
87
+ - Bypasses LLM interpretation for precise agent instructions
88
+
89
+ ### Fixed
90
+ - DotAccessHash array wrapping and template response handling
91
+ - CLI::UI formatting and color handling for better terminal output
92
+
8
93
  ## [0.3.1] - 2025-06-05
9
94
 
10
95
  ### Added
data/CLAUDE.md CHANGED
@@ -4,17 +4,15 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
4
4
 
5
5
  ## About the codebase
6
6
  - This is a Ruby gem called Roast. Its purpose is to run AI workflows defined in a YAML file.
7
+ - Note that this project now uses Zeitwerk, which means you don't have to manually require project files anymore
7
8
 
8
9
  ## Commands
9
-
10
- - Default (tests + lint): `bundle exec rake`
11
- - Test all: `bundle exec test`
10
+ - Default THE SUITE RUNS FAST SO USE THIS IN MOST CASES (tests + lint w/autocorrect): `bundle exec rake`
12
11
  - Run single test: `bundle exec ruby -Itest test/path/to/test_file.rb`
13
12
  - Lint: `bundle exec rubocop`
14
13
  - Lint (with autocorrect, preferred): `bundle exec rubocop -A`
15
14
  - Whenever you want to run the whole test suite just run `bundle exec rake` to also run linting, and note the linting errors too (most will auto correct but not all)
16
15
  - **Run roast locally**: Use `bin/roast` (not `bundle exec roast` which may use the installed gem)
17
- - Alternative: `bundle exec exe/roast`
18
16
 
19
17
  ## Tech stack
20
18
  - `thor` and `cli-ui` for the CLI tool
@@ -22,7 +20,6 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
22
20
  - Prefer using the more literate `test "this is a test description" do` type of testing that we get from extending ActiveSupport::TestCase over the primitive XUnit-style def test_description headings for tests
23
21
 
24
22
  ## Code Style Guidelines
25
-
26
23
  - Naming: snake_case for variables/methods, CamelCase for classes/modules, ALL_CAPS for constants
27
24
  - Module structure: Use nested modules under the `Roast` namespace
28
25
  - Command pattern: Commands implement a `call` method and class-level `help` method
@@ -40,7 +37,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
40
37
  - Always leave a blank line after module includes and before the rest of the class
41
38
 
42
39
  ## Architecture Guidelines
43
-
40
+ - **SOLID principles are important** - don't violate them
44
41
  - **Maintain proper separation of concerns**: Don't mix unrelated concepts in the same class or module
45
42
  - Example: Conditional execution (if/unless) should NOT be mixed with iteration execution (each/repeat)
46
43
  - Each concept should have its own executor class and be handled separately
@@ -51,14 +48,67 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
51
48
  - ConditionalExecutor handles conditionals (if, unless)
52
49
  - Don't combine different responsibilities in one class
53
50
  - **Do not implement prompts "inline" using a prompt: attribute nested under step names, that violates the primary design architecture of Roast**
51
+ - When faced with the choice between working around an architectural issue or code smell versus actually diving into fixing the design issue or code smell, choose the latter more principled approach
52
+ - When fixing code smells, you don't have to worry about internal backwards compatibility
53
+
54
+ ## Workflow Configuration Syntax
55
+ - The `steps` key in the workflow configuration is an array of step names
56
+ - Only step names, inline prompts, and control flow keywords are allowed in the steps array
57
+ - Additional per-step configuration is provided in a top-level hash with the step name as the key, not within steps!!! (Very important)
58
+ - The reason that steps are not configured "inline" within the steps array is so that the shape of the workflow is as obvious as possible
59
+ - Step labels are inferred for most steps and optional for inline prompts, but required for steps that need custom configuration
60
+ - The result of running a step is stored in the `workflow.output` hash with the step label as the key
61
+
62
+ ## How Roast Tools Work (CRITICAL - READ THIS!)
63
+ **Tools in Roast are NOT explicitly invoked in workflow steps!** This is a fundamental concept that differs from many other workflow systems.
64
+
65
+ ### Key Concepts:
66
+ 1. **Tools are capabilities available to the LLM** - They are functions the LLM can choose to call while executing a step
67
+ 2. **Steps contain prompts** - Steps describe what needs to be done, not how to do it
68
+ 3. **The LLM decides when to use tools** - While executing a step's prompt, the LLM analyzes the task and calls tools as needed
69
+ 4. **Tools are registered, not declared in steps** - Use the `tools:` section to make tools available, but never use a `tool:` key in step configuration
70
+
71
+ ### Correct inline prompt syntax:
72
+ ```yaml
73
+ steps:
74
+ - analyze_code: |
75
+ Analyze the codebase and identify performance bottlenecks.
76
+ Use any available tools to read files and search for patterns.
77
+ ```
78
+
79
+ ### INCORRECT syntax (DO NOT USE):
80
+ ```yaml
81
+ # WRONG - no 'prompt:' key
82
+ steps:
83
+ - analyze_code:
84
+ prompt: "Analyze the codebase"
85
+
86
+ # WRONG - no 'tool:' key
87
+ steps:
88
+ - run_analysis:
89
+ tool: coding_agent
90
+ prompt: "Analyze code"
91
+ ```
54
92
 
55
- ## Guidance and Expectations
93
+ ### How tools are actually used:
94
+ When the LLM executes the `analyze_code` step above, it might:
95
+ 1. Decide it needs to read files and call `read_file(path)`
96
+ 2. Decide it needs to search and call `grep(pattern, path)`
97
+ 3. Decide it needs Claude Swarm and call `swarm(prompt, config_path)`
56
98
 
99
+ The LLM makes these decisions based on the prompt and available tools, similar to how Claude (you) decides when to use Bash, Read, or other tools when responding to user requests.
100
+
101
+ ## Step Configuration
102
+ - The `path` key in a step configuration is the path to a Ruby file that defines a custom step.
103
+ - The `model` key in a step configuration is the model to use for the step.
104
+ - The `print_response` key in a step configuration is a boolean that determines whether the step's response should be printed to the console.
105
+
106
+ ## Coding Guidance and Expectations
57
107
  - Do not decide unilaterally to leave code for the sake of "backwards compatibility"... always run those decisions by me first.
58
108
  - Don't ever commit and push changes unless directly told to do so
109
+ - You can't test input steps yourself since they block, so ask me to do it manually
59
110
 
60
111
  ## Git Workflow Practices
61
-
62
112
  1. **Amending Commits**:
63
113
  - Use `git commit --amend --no-edit` to add staged changes to the last commit without changing the commit message
64
114
  - This is useful for incorporating small fixes or changes that belong with the previous commit
@@ -130,6 +180,48 @@ gh pr view {pr_number}
130
180
  gh pr diff {pr_number}
131
181
  ```
132
182
 
183
+ ### Issue Labeling and Project Management
184
+
185
+ When creating GitHub issues, always check available labels, projects, and milestones first:
186
+
187
+ ```bash
188
+ # List all available labels
189
+ gh api repos/Shopify/roast/labels | jq '.[].name'
190
+
191
+ # List all milestones
192
+ gh api repos/Shopify/roast/milestones | jq '.[] | {title: .title, number: .number, state: .state}'
193
+
194
+ # List projects linked to the roast repository
195
+ gh api graphql -f query='
196
+ {
197
+ repository(owner: "Shopify", name: "roast") {
198
+ projectsV2(first: 10) {
199
+ nodes {
200
+ title
201
+ number
202
+ url
203
+ }
204
+ }
205
+ }
206
+ }' --jq '.data.repository.projectsV2.nodes[] | {title: .title, number: .number, url: .url}'
207
+ ```
208
+
209
+ **Issue Creation Workflow**:
210
+ 1. First check what labels exist and apply appropriate ones when creating the issue
211
+ 2. After creating the issue, ask the user if they want it added to an existing milestone
212
+ 3. Ask the user if they want it added to a particular project board
213
+
214
+ ```bash
215
+ # Create issue with labels
216
+ gh api repos/Shopify/roast/issues -X POST -F title="Issue Title" -F body="Issue description" -F 'labels=["bug", "enhancement"]'
217
+
218
+ # Add issue to a milestone (after creation)
219
+ gh api repos/Shopify/roast/issues/{issue_number} -X PATCH -F milestone={milestone_number}
220
+
221
+ # Add issue to a GitHub Project
222
+ gh project item-add {project_number} --url https://github.com/Shopify/roast/issues/{issue_number}
223
+ ```
224
+
133
225
  #### Formatting Tips for GitHub API
134
226
  1. Use literal newlines in the body text instead of `\n` escape sequences
135
227
  2. When formatting is stripped (like backticks), use alternatives:
@@ -167,4 +259,9 @@ gh pr diff {pr_number}
167
259
  - Avoid premature optimization outside of hot paths
168
260
  - Consider the tradeoff between readability and performance
169
261
  - Suggest optimizations that improve both clarity and performance
170
- ```
262
+
263
+ ## CLI::UI Formatting Tips
264
+ - To apply color to terminal output using CLI::UI, use the following syntax:
265
+ ```ruby
266
+ puts ::CLI::UI.fmt("{{red:This field is required. Please provide a value.}}")
267
+ ```
data/Gemfile CHANGED
@@ -8,7 +8,7 @@ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
8
8
  gemspec
9
9
 
10
10
  gem "cgi"
11
- gem "cli-ui"
11
+ gem "cli-ui", "2.3.0"
12
12
  gem "dotenv"
13
13
  gem "guard"
14
14
  gem "guard-minitest"
@@ -18,3 +18,6 @@ gem "rubocop-shopify", require: false
18
18
  gem "vcr", require: false
19
19
  gem "webmock", require: false
20
20
  gem "minitest-rg"
21
+ gem "sqlite3", "~> 1.7"
22
+
23
+ gem "claude_swarm"
data/Gemfile.lock CHANGED
@@ -1,15 +1,17 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- roast-ai (0.3.1)
4
+ roast-ai (0.4.1)
5
5
  activesupport (>= 7.0)
6
- cli-ui
6
+ cli-ui (= 2.3.0)
7
7
  diff-lcs (~> 1.5)
8
8
  faraday-retry
9
9
  json-schema
10
10
  open_router (~> 0.3)
11
11
  raix (~> 1.0)
12
+ ruby-graphviz (~> 1.2)
12
13
  thor (~> 1.3)
14
+ zeitwerk (~> 2.6)
13
15
 
14
16
  GEM
15
17
  remote: https://rubygems.org/
@@ -33,17 +35,49 @@ GEM
33
35
  base64 (0.3.0)
34
36
  benchmark (0.4.1)
35
37
  bigdecimal (3.2.2)
36
- cgi (0.4.2)
37
- cli-ui (2.3.1)
38
+ cgi (0.5.0)
39
+ claude_swarm (0.1.15)
40
+ fast-mcp-annotations
41
+ thor (~> 1.3)
42
+ cli-ui (2.3.0)
38
43
  coderay (1.1.3)
39
44
  concurrent-ruby (1.3.5)
40
45
  connection_pool (2.5.3)
41
46
  crack (1.0.0)
42
47
  bigdecimal
43
48
  rexml
44
- diff-lcs (1.6.1)
49
+ diff-lcs (1.6.2)
45
50
  dotenv (3.1.8)
46
51
  drb (2.2.3)
52
+ dry-configurable (1.3.0)
53
+ dry-core (~> 1.1)
54
+ zeitwerk (~> 2.6)
55
+ dry-core (1.1.0)
56
+ concurrent-ruby (~> 1.0)
57
+ logger
58
+ zeitwerk (~> 2.6)
59
+ dry-inflector (1.2.0)
60
+ dry-initializer (3.2.0)
61
+ dry-logic (1.6.0)
62
+ bigdecimal
63
+ concurrent-ruby (~> 1.0)
64
+ dry-core (~> 1.1)
65
+ zeitwerk (~> 2.6)
66
+ dry-schema (1.14.1)
67
+ concurrent-ruby (~> 1.0)
68
+ dry-configurable (~> 1.0, >= 1.0.1)
69
+ dry-core (~> 1.1)
70
+ dry-initializer (~> 3.2)
71
+ dry-logic (~> 1.5)
72
+ dry-types (~> 1.8)
73
+ zeitwerk (~> 2.6)
74
+ dry-types (1.8.3)
75
+ bigdecimal (~> 3.0)
76
+ concurrent-ruby (~> 1.0)
77
+ dry-core (~> 1.0)
78
+ dry-inflector (~> 1.0)
79
+ dry-logic (~> 1.4)
80
+ zeitwerk (~> 2.6)
47
81
  event_stream_parser (1.0.0)
48
82
  faraday (2.13.1)
49
83
  faraday-net_http (>= 2.0, < 3.5)
@@ -55,6 +89,13 @@ GEM
55
89
  net-http (>= 0.5.0)
56
90
  faraday-retry (2.3.1)
57
91
  faraday (~> 2.0)
92
+ fast-mcp-annotations (1.5.2)
93
+ addressable (~> 2.8)
94
+ base64
95
+ dry-schema (~> 1.14)
96
+ json (~> 2.0)
97
+ mime-types (~> 3.4)
98
+ rack (~> 3.1)
58
99
  ffi (1.17.2-arm64-darwin)
59
100
  ffi (1.17.2-x86_64-linux-gnu)
60
101
  formatador (1.1.0)
@@ -73,14 +114,14 @@ GEM
73
114
  guard-minitest (2.4.6)
74
115
  guard-compat (~> 1.2)
75
116
  minitest (>= 3.0)
76
- hashdiff (1.1.2)
117
+ hashdiff (1.2.0)
77
118
  i18n (1.14.7)
78
119
  concurrent-ruby (~> 1.0)
79
120
  json (2.12.2)
80
121
  json-schema (5.1.1)
81
122
  addressable (~> 2.8)
82
123
  bigdecimal (~> 3.1)
83
- language_server-protocol (3.17.0.4)
124
+ language_server-protocol (3.17.0.5)
84
125
  lint_roller (1.1.0)
85
126
  listen (3.9.0)
86
127
  rb-fsevent (~> 0.10, >= 0.10.3)
@@ -88,6 +129,11 @@ GEM
88
129
  logger (1.7.0)
89
130
  lumberjack (1.2.10)
90
131
  method_source (1.1.0)
132
+ mime-types (3.7.0)
133
+ logger
134
+ mime-types-data (~> 3.2025, >= 3.2025.0507)
135
+ mime-types-data (3.2025.0603)
136
+ mini_portile2 (2.8.9)
91
137
  minitest (5.25.5)
92
138
  minitest-rg (5.3.0)
93
139
  minitest (~> 5.0)
@@ -114,22 +160,23 @@ GEM
114
160
  pry (0.15.2)
115
161
  coderay (~> 1.1)
116
162
  method_source (~> 1.0)
117
- public_suffix (6.0.1)
163
+ public_suffix (6.0.2)
118
164
  racc (1.8.1)
165
+ rack (3.1.16)
119
166
  rainbow (3.1.1)
120
- raix (1.0.0)
167
+ raix (1.0.1)
121
168
  activesupport (>= 6.0)
122
169
  faraday-retry (~> 2.0)
123
170
  open_router (~> 0.2)
124
171
  ostruct
125
172
  ruby-openai (~> 7)
126
- rake (13.2.1)
173
+ rake (13.3.0)
127
174
  rb-fsevent (0.11.2)
128
175
  rb-inotify (0.11.1)
129
176
  ffi (~> 1.0)
130
177
  regexp_parser (2.10.0)
131
178
  rexml (3.4.1)
132
- rubocop (1.75.3)
179
+ rubocop (1.76.0)
133
180
  json (~> 2.3)
134
181
  language_server-protocol (~> 3.17.0.2)
135
182
  lint_roller (~> 1.1.0)
@@ -137,14 +184,16 @@ GEM
137
184
  parser (>= 3.3.0.2)
138
185
  rainbow (>= 2.2.2, < 4.0)
139
186
  regexp_parser (>= 2.9.3, < 3.0)
140
- rubocop-ast (>= 1.44.0, < 2.0)
187
+ rubocop-ast (>= 1.45.0, < 2.0)
141
188
  ruby-progressbar (~> 1.7)
142
189
  unicode-display_width (>= 2.4.0, < 4.0)
143
- rubocop-ast (1.44.1)
190
+ rubocop-ast (1.45.0)
144
191
  parser (>= 3.3.7.2)
145
192
  prism (~> 1.4)
146
- rubocop-shopify (2.17.0)
193
+ rubocop-shopify (2.17.1)
147
194
  rubocop (~> 1.62)
195
+ ruby-graphviz (1.2.5)
196
+ rexml
148
197
  ruby-openai (7.4.0)
149
198
  event_stream_parser (>= 0.3.0, < 2.0.0)
150
199
  faraday (>= 1)
@@ -153,6 +202,8 @@ GEM
153
202
  ruby2_keywords (0.0.5)
154
203
  securerandom (0.4.1)
155
204
  shellany (0.0.1)
205
+ sqlite3 (1.7.3)
206
+ mini_portile2 (~> 2.8.0)
156
207
  thor (1.3.2)
157
208
  tzinfo (2.0.6)
158
209
  concurrent-ruby (~> 1.0)
@@ -166,14 +217,16 @@ GEM
166
217
  addressable (>= 2.8.0)
167
218
  crack (>= 0.3.2)
168
219
  hashdiff (>= 0.4.0, < 2.0.0)
220
+ zeitwerk (2.7.3)
169
221
 
170
222
  PLATFORMS
171
- arm64-darwin-23
223
+ arm64-darwin
172
224
  x86_64-linux
173
225
 
174
226
  DEPENDENCIES
175
227
  cgi
176
- cli-ui
228
+ claude_swarm
229
+ cli-ui (= 2.3.0)
177
230
  dotenv
178
231
  guard
179
232
  guard-minitest
@@ -182,6 +235,7 @@ DEPENDENCIES
182
235
  rake
183
236
  roast-ai!
184
237
  rubocop-shopify
238
+ sqlite3 (~> 1.7)
185
239
  vcr
186
240
  webmock
187
241