roast-ai 0.4.6 → 0.4.8

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 (286) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yaml +3 -1
  3. data/.gitignore +7 -0
  4. data/.rubocop.yml +14 -0
  5. data/Gemfile +2 -1
  6. data/Gemfile.lock +9 -1
  7. data/Rakefile +16 -4
  8. data/examples/README.md +9 -0
  9. data/examples/available_tools_demo/workflow.yml +2 -2
  10. data/examples/basic_prompt_workflow/workflow.md +1 -0
  11. data/examples/basic_prompt_workflow/workflow.yml +14 -0
  12. data/lib/roast/dsl/executor.rb +2 -1
  13. data/lib/roast/helpers/cmd_runner.rb +199 -0
  14. data/lib/roast/initializers.rb +1 -1
  15. data/lib/roast/tools/apply_diff.rb +1 -1
  16. data/lib/roast/tools/bash.rb +4 -4
  17. data/lib/roast/tools/cmd.rb +3 -5
  18. data/lib/roast/tools/coding_agent.rb +1 -1
  19. data/lib/roast/tools/grep.rb +6 -2
  20. data/lib/roast/tools/read_file.rb +2 -1
  21. data/lib/roast/tools/swarm.rb +2 -7
  22. data/lib/roast/tools.rb +10 -1
  23. data/lib/roast/version.rb +1 -1
  24. data/lib/roast/workflow/base_step.rb +2 -3
  25. data/lib/roast/workflow/command_executor.rb +3 -3
  26. data/lib/roast/workflow/resource_resolver.rb +1 -1
  27. data/lib/roast/workflow/shell_script_step.rb +1 -1
  28. data/lib/roast/workflow/step_loader.rb +2 -7
  29. data/lib/roast.rb +7 -1
  30. data/rubocop/cop/roast/use_cmd_runner.rb +93 -0
  31. data/rubocop/cop/roast.rb +4 -0
  32. data/sorbet/rbi/gems/docile@1.4.1.rbi +377 -0
  33. data/sorbet/rbi/gems/lint_roller@1.1.0.rbi +233 -2
  34. data/sorbet/rbi/gems/racc@1.8.1.rbi +6 -4
  35. data/sorbet/rbi/gems/rainbow@3.1.1.rbi +396 -2
  36. data/sorbet/rbi/gems/regexp_parser@2.10.0.rbi +3788 -2
  37. data/sorbet/rbi/gems/rubocop-ast@1.45.1.rbi +7747 -2
  38. data/sorbet/rbi/gems/rubocop-sorbet@0.10.5.rbi +2386 -0
  39. data/sorbet/rbi/gems/rubocop@1.77.0.rbi +62813 -2
  40. data/sorbet/rbi/gems/ruby-progressbar@1.13.0.rbi +1311 -2
  41. data/sorbet/rbi/gems/simplecov-html@0.13.2.rbi +225 -0
  42. data/sorbet/rbi/gems/simplecov@0.22.0.rbi +2259 -0
  43. data/sorbet/rbi/gems/simplecov_json_formatter@0.1.4.rbi +9 -0
  44. data/sorbet/rbi/gems/unicode-display_width@3.1.4.rbi +125 -2
  45. data/sorbet/rbi/gems/unicode-emoji@4.0.4.rbi +244 -2
  46. data/sorbet/tapioca/require.rb +2 -1
  47. metadata +12 -240
  48. data/CHANGELOG.md +0 -364
  49. data/examples/agent_continue/add_documentation/prompt.md +0 -5
  50. data/examples/agent_continue/add_error_handling/prompt.md +0 -5
  51. data/examples/agent_continue/analyze_codebase/prompt.md +0 -7
  52. data/examples/agent_continue/combined_workflow.yml +0 -24
  53. data/examples/agent_continue/continue_adding_features/prompt.md +0 -4
  54. data/examples/agent_continue/create_integration_tests/prompt.md +0 -3
  55. data/examples/agent_continue/document_with_context/prompt.md +0 -5
  56. data/examples/agent_continue/explore_api/prompt.md +0 -6
  57. data/examples/agent_continue/implement_client/prompt.md +0 -6
  58. data/examples/agent_continue/inline_workflow.yml +0 -20
  59. data/examples/agent_continue/refactor_code/prompt.md +0 -2
  60. data/examples/agent_continue/verify_changes/prompt.md +0 -6
  61. data/examples/agent_continue/workflow.yml +0 -27
  62. data/examples/agent_workflow/README.md +0 -75
  63. data/examples/agent_workflow/apply_refactorings/prompt.md +0 -22
  64. data/examples/agent_workflow/identify_code_smells/prompt.md +0 -15
  65. data/examples/agent_workflow/summarize_improvements/prompt.md +0 -18
  66. data/examples/agent_workflow/workflow.png +0 -0
  67. data/examples/agent_workflow/workflow.yml +0 -16
  68. data/examples/api_workflow/README.md +0 -85
  69. data/examples/api_workflow/fetch_api_data/prompt.md +0 -10
  70. data/examples/api_workflow/generate_report/prompt.md +0 -10
  71. data/examples/api_workflow/prompt.md +0 -10
  72. data/examples/api_workflow/transform_data/prompt.md +0 -10
  73. data/examples/api_workflow/workflow.png +0 -0
  74. data/examples/api_workflow/workflow.yml +0 -30
  75. data/examples/apply_diff_demo/README.md +0 -58
  76. data/examples/apply_diff_demo/apply_simple_change/prompt.md +0 -13
  77. data/examples/apply_diff_demo/create_sample_file/prompt.md +0 -11
  78. data/examples/apply_diff_demo/workflow.yml +0 -24
  79. data/examples/available_tools_demo/workflow.png +0 -0
  80. data/examples/bash_prototyping/README.md +0 -53
  81. data/examples/bash_prototyping/analyze_network/prompt.md +0 -13
  82. data/examples/bash_prototyping/analyze_system/prompt.md +0 -11
  83. data/examples/bash_prototyping/api_testing.png +0 -0
  84. data/examples/bash_prototyping/api_testing.yml +0 -14
  85. data/examples/bash_prototyping/check_processes/prompt.md +0 -11
  86. data/examples/bash_prototyping/generate_report/prompt.md +0 -16
  87. data/examples/bash_prototyping/process_json_response/prompt.md +0 -24
  88. data/examples/bash_prototyping/system_analysis.png +0 -0
  89. data/examples/bash_prototyping/system_analysis.yml +0 -14
  90. data/examples/bash_prototyping/test_public_api/prompt.md +0 -22
  91. data/examples/case_when/README.md +0 -58
  92. data/examples/case_when/detect_language/prompt.md +0 -16
  93. data/examples/case_when/workflow.png +0 -0
  94. data/examples/case_when/workflow.yml +0 -58
  95. data/examples/cmd/README.md +0 -99
  96. data/examples/cmd/analyze_project/prompt.md +0 -57
  97. data/examples/cmd/basic_demo/prompt.md +0 -48
  98. data/examples/cmd/basic_workflow.png +0 -0
  99. data/examples/cmd/basic_workflow.yml +0 -17
  100. data/examples/cmd/check_repository/prompt.md +0 -57
  101. data/examples/cmd/create_and_verify/prompt.md +0 -56
  102. data/examples/cmd/dev_workflow.png +0 -0
  103. data/examples/cmd/dev_workflow.yml +0 -26
  104. data/examples/cmd/explore_project/prompt.md +0 -67
  105. data/examples/cmd/explorer_workflow.png +0 -0
  106. data/examples/cmd/explorer_workflow.yml +0 -21
  107. data/examples/cmd/smart_tool_selection/prompt.md +0 -99
  108. data/examples/coding_agent_with_model.yml +0 -20
  109. data/examples/coding_agent_with_retries.yml +0 -30
  110. data/examples/conditional/README.md +0 -161
  111. data/examples/conditional/check_condition/prompt.md +0 -1
  112. data/examples/conditional/simple_workflow.png +0 -0
  113. data/examples/conditional/simple_workflow.yml +0 -15
  114. data/examples/conditional/workflow.png +0 -0
  115. data/examples/conditional/workflow.yml +0 -23
  116. data/examples/context_management_demo/README.md +0 -43
  117. data/examples/context_management_demo/workflow.yml +0 -42
  118. data/examples/direct_coerce_syntax/README.md +0 -32
  119. data/examples/direct_coerce_syntax/workflow.png +0 -0
  120. data/examples/direct_coerce_syntax/workflow.yml +0 -36
  121. data/examples/dot_notation/README.md +0 -37
  122. data/examples/dot_notation/workflow.png +0 -0
  123. data/examples/dot_notation/workflow.yml +0 -44
  124. data/examples/exit_on_error/README.md +0 -50
  125. data/examples/exit_on_error/analyze_lint_output/prompt.md +0 -9
  126. data/examples/exit_on_error/apply_fixes/prompt.md +0 -2
  127. data/examples/exit_on_error/workflow.png +0 -0
  128. data/examples/exit_on_error/workflow.yml +0 -19
  129. data/examples/grading/README.md +0 -71
  130. data/examples/grading/analyze_coverage/prompt.md +0 -52
  131. data/examples/grading/calculate_final_grade.rb +0 -67
  132. data/examples/grading/format_result.rb +0 -64
  133. data/examples/grading/generate_grades/prompt.md +0 -105
  134. data/examples/grading/generate_recommendations/output.txt +0 -17
  135. data/examples/grading/generate_recommendations/prompt.md +0 -60
  136. data/examples/grading/js_test_runner +0 -31
  137. data/examples/grading/rb_test_runner +0 -19
  138. data/examples/grading/read_dependencies/prompt.md +0 -16
  139. data/examples/grading/run_coverage.rb +0 -54
  140. data/examples/grading/verify_mocks_and_stubs/prompt.md +0 -12
  141. data/examples/grading/verify_test_helpers/prompt.md +0 -53
  142. data/examples/grading/workflow.md +0 -8
  143. data/examples/grading/workflow.png +0 -0
  144. data/examples/grading/workflow.rb.md +0 -6
  145. data/examples/grading/workflow.ts+tsx.md +0 -6
  146. data/examples/grading/workflow.yml +0 -41
  147. data/examples/instrumentation.rb +0 -76
  148. data/examples/interpolation/README.md +0 -50
  149. data/examples/interpolation/analyze_file/prompt.md +0 -1
  150. data/examples/interpolation/analyze_patterns/prompt.md +0 -27
  151. data/examples/interpolation/generate_report_for_js/prompt.md +0 -3
  152. data/examples/interpolation/generate_report_for_rb/prompt.md +0 -3
  153. data/examples/interpolation/sample.js +0 -48
  154. data/examples/interpolation/sample.rb +0 -42
  155. data/examples/interpolation/workflow.md +0 -1
  156. data/examples/interpolation/workflow.png +0 -0
  157. data/examples/interpolation/workflow.yml +0 -21
  158. data/examples/iteration/IMPLEMENTATION.md +0 -88
  159. data/examples/iteration/README.md +0 -68
  160. data/examples/iteration/analyze_complexity/prompt.md +0 -22
  161. data/examples/iteration/generate_recommendations/prompt.md +0 -21
  162. data/examples/iteration/generate_report/prompt.md +0 -129
  163. data/examples/iteration/implement_fix/prompt.md +0 -25
  164. data/examples/iteration/prioritize_issues/prompt.md +0 -24
  165. data/examples/iteration/prompts/analyze_file.md +0 -28
  166. data/examples/iteration/prompts/generate_summary.md +0 -24
  167. data/examples/iteration/prompts/update_report.md +0 -29
  168. data/examples/iteration/prompts/write_report.md +0 -22
  169. data/examples/iteration/read_file/prompt.md +0 -9
  170. data/examples/iteration/select_next_issue/prompt.md +0 -25
  171. data/examples/iteration/simple_workflow.md +0 -39
  172. data/examples/iteration/simple_workflow.yml +0 -58
  173. data/examples/iteration/update_fix_count/prompt.md +0 -26
  174. data/examples/iteration/verify_fix/prompt.md +0 -29
  175. data/examples/iteration/workflow.png +0 -0
  176. data/examples/iteration/workflow.yml +0 -42
  177. data/examples/json_handling/README.md +0 -32
  178. data/examples/json_handling/workflow.png +0 -0
  179. data/examples/json_handling/workflow.yml +0 -52
  180. data/examples/mcp/README.md +0 -223
  181. data/examples/mcp/analyze_changes/prompt.md +0 -8
  182. data/examples/mcp/analyze_issues/prompt.md +0 -4
  183. data/examples/mcp/analyze_schema/prompt.md +0 -4
  184. data/examples/mcp/check_data_quality/prompt.md +0 -5
  185. data/examples/mcp/check_documentation/prompt.md +0 -4
  186. data/examples/mcp/create_recommendations/prompt.md +0 -5
  187. data/examples/mcp/database_workflow.png +0 -0
  188. data/examples/mcp/database_workflow.yml +0 -29
  189. data/examples/mcp/env_demo/workflow.png +0 -0
  190. data/examples/mcp/env_demo/workflow.yml +0 -34
  191. data/examples/mcp/fetch_pr_context/prompt.md +0 -4
  192. data/examples/mcp/filesystem_demo/create_test_file/prompt.md +0 -2
  193. data/examples/mcp/filesystem_demo/list_files/prompt.md +0 -6
  194. data/examples/mcp/filesystem_demo/read_with_mcp/prompt.md +0 -7
  195. data/examples/mcp/filesystem_demo/workflow.png +0 -0
  196. data/examples/mcp/filesystem_demo/workflow.yml +0 -38
  197. data/examples/mcp/generate_insights/prompt.md +0 -4
  198. data/examples/mcp/generate_report/prompt.md +0 -6
  199. data/examples/mcp/generate_review/prompt.md +0 -16
  200. data/examples/mcp/github_workflow.png +0 -0
  201. data/examples/mcp/github_workflow.yml +0 -32
  202. data/examples/mcp/multi_mcp_workflow.png +0 -0
  203. data/examples/mcp/multi_mcp_workflow.yml +0 -58
  204. data/examples/mcp/post_review/prompt.md +0 -3
  205. data/examples/mcp/save_report/prompt.md +0 -6
  206. data/examples/mcp/search_issues/prompt.md +0 -2
  207. data/examples/mcp/summarize/prompt.md +0 -1
  208. data/examples/mcp/test_filesystem/prompt.md +0 -6
  209. data/examples/mcp/test_github/prompt.md +0 -8
  210. data/examples/mcp/test_read/prompt.md +0 -1
  211. data/examples/mcp/workflow.png +0 -0
  212. data/examples/mcp/workflow.yml +0 -35
  213. data/examples/no_model_fallback/README.md +0 -17
  214. data/examples/no_model_fallback/analyze_file/prompt.md +0 -1
  215. data/examples/no_model_fallback/analyze_patterns/prompt.md +0 -27
  216. data/examples/no_model_fallback/generate_report_for_md/prompt.md +0 -10
  217. data/examples/no_model_fallback/generate_report_for_rb/prompt.md +0 -3
  218. data/examples/no_model_fallback/sample.rb +0 -42
  219. data/examples/no_model_fallback/workflow.yml +0 -19
  220. data/examples/openrouter_example/README.md +0 -48
  221. data/examples/openrouter_example/analyze_input/prompt.md +0 -16
  222. data/examples/openrouter_example/generate_response/prompt.md +0 -9
  223. data/examples/openrouter_example/workflow.png +0 -0
  224. data/examples/openrouter_example/workflow.yml +0 -12
  225. data/examples/pre_post_processing/README.md +0 -111
  226. data/examples/pre_post_processing/analyze_test_file/prompt.md +0 -23
  227. data/examples/pre_post_processing/improve_test_coverage/prompt.md +0 -17
  228. data/examples/pre_post_processing/optimize_test_performance/prompt.md +0 -25
  229. data/examples/pre_post_processing/post_processing/aggregate_metrics/prompt.md +0 -31
  230. data/examples/pre_post_processing/post_processing/cleanup_environment/prompt.md +0 -28
  231. data/examples/pre_post_processing/post_processing/generate_summary_report/prompt.md +0 -32
  232. data/examples/pre_post_processing/post_processing/output.txt +0 -24
  233. data/examples/pre_post_processing/pre_processing/gather_baseline_metrics/prompt.md +0 -26
  234. data/examples/pre_post_processing/pre_processing/setup_test_environment/prompt.md +0 -11
  235. data/examples/pre_post_processing/validate_changes/prompt.md +0 -24
  236. data/examples/pre_post_processing/workflow.png +0 -0
  237. data/examples/pre_post_processing/workflow.yml +0 -21
  238. data/examples/retry/workflow.yml +0 -23
  239. data/examples/rspec_to_minitest/README.md +0 -68
  240. data/examples/rspec_to_minitest/analyze_spec/prompt.md +0 -30
  241. data/examples/rspec_to_minitest/create_minitest/prompt.md +0 -33
  242. data/examples/rspec_to_minitest/run_and_improve/prompt.md +0 -35
  243. data/examples/rspec_to_minitest/workflow.md +0 -10
  244. data/examples/rspec_to_minitest/workflow.png +0 -0
  245. data/examples/rspec_to_minitest/workflow.yml +0 -40
  246. data/examples/shared_config/README.md +0 -52
  247. data/examples/shared_config/example_with_shared_config/workflow.png +0 -0
  248. data/examples/shared_config/example_with_shared_config/workflow.yml +0 -6
  249. data/examples/shared_config/shared.png +0 -0
  250. data/examples/shared_config/shared.yml +0 -7
  251. data/examples/single_target_prepost/README.md +0 -36
  252. data/examples/single_target_prepost/post_processing/output.txt +0 -27
  253. data/examples/single_target_prepost/pre_processing/gather_dependencies/prompt.md +0 -11
  254. data/examples/single_target_prepost/workflow.png +0 -0
  255. data/examples/single_target_prepost/workflow.yml +0 -20
  256. data/examples/smart_coercion_defaults/README.md +0 -65
  257. data/examples/smart_coercion_defaults/workflow.png +0 -0
  258. data/examples/smart_coercion_defaults/workflow.yml +0 -44
  259. data/examples/step_configuration/README.md +0 -84
  260. data/examples/step_configuration/workflow.png +0 -0
  261. data/examples/step_configuration/workflow.yml +0 -57
  262. data/examples/swarm_example.yml +0 -25
  263. data/examples/tool_config_example/README.md +0 -109
  264. data/examples/tool_config_example/example_step/prompt.md +0 -42
  265. data/examples/tool_config_example/workflow.png +0 -0
  266. data/examples/tool_config_example/workflow.yml +0 -17
  267. data/examples/user_input/README.md +0 -90
  268. data/examples/user_input/funny_name/create_backstory/prompt.md +0 -10
  269. data/examples/user_input/funny_name/workflow.png +0 -0
  270. data/examples/user_input/funny_name/workflow.yml +0 -26
  271. data/examples/user_input/generate_summary/prompt.md +0 -11
  272. data/examples/user_input/simple_input_demo/workflow.png +0 -0
  273. data/examples/user_input/simple_input_demo/workflow.yml +0 -35
  274. data/examples/user_input/survey_workflow.png +0 -0
  275. data/examples/user_input/survey_workflow.yml +0 -71
  276. data/examples/user_input/welcome_message/prompt.md +0 -3
  277. data/examples/user_input/workflow.png +0 -0
  278. data/examples/user_input/workflow.yml +0 -73
  279. data/examples/workflow_generator/README.md +0 -27
  280. data/examples/workflow_generator/analyze_user_request/prompt.md +0 -34
  281. data/examples/workflow_generator/create_workflow_files/prompt.md +0 -32
  282. data/examples/workflow_generator/get_user_input/prompt.md +0 -14
  283. data/examples/workflow_generator/info_from_roast.rb +0 -22
  284. data/examples/workflow_generator/workflow.png +0 -0
  285. data/examples/workflow_generator/workflow.yml +0 -34
  286. data/lib/roast/helpers/timeout_handler.rb +0 -89
@@ -1,54 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class RunCoverage < Roast::Workflow::BaseStep
4
- def call
5
- # Run the test with coverage analysis
6
- run_test_with_coverage
7
- end
8
-
9
- private
10
-
11
- def run_test_with_coverage
12
- subject_file = workflow.output["read_dependencies"]
13
- subject_file = subject_file.match(%r{<sut>(.*?)</sut>})&.[](1) || subject_file
14
- test_file = workflow.file
15
- extension = File.extname(test_file).gsub(".", "")
16
-
17
- # Handle JS/TS test files
18
- extension = "js" if ["js", "jsx", "ts", "tsx"].include?(extension)
19
-
20
- # Get the absolute path to the test_runner executable
21
- test_runner_path = File.expand_path("#{extension}_test_runner", __dir__)
22
-
23
- # Make sure the test_runner executable exists
24
- unless File.exist?(test_runner_path)
25
- Roast::Helpers::Logger.error("Test runner executable not found: #{test_runner_path}")
26
- exit(1)
27
- end
28
-
29
- # Resolve paths to prevent issues when pwd differs from project root
30
- resolved_subject_file = Roast::Helpers::PathResolver.resolve(subject_file)
31
- unless File.exist?(resolved_subject_file)
32
- Roast::Helpers::Logger.error("Subject file not found: #{resolved_subject_file}")
33
- exit(1)
34
- end
35
-
36
- resolved_test_file = Roast::Helpers::PathResolver.resolve(test_file)
37
- unless File.exist?(resolved_test_file)
38
- Roast::Helpers::Logger.error("Test file not found: #{resolved_test_file}")
39
- exit(1)
40
- end
41
-
42
- # Run the test_runner using shadowenv for environment consistency
43
- command = "shadowenv exec --dir . -- #{test_runner_path} #{resolved_test_file} #{resolved_subject_file}"
44
- output, status = Open3.capture2(command)
45
-
46
- unless status.success?
47
- Roast::Helpers::Logger.error("Test runner exited with non-zero status: #{status.exitstatus}")
48
- Roast::Helpers::Logger.error(output)
49
- exit(status.exitstatus)
50
- end
51
-
52
- output
53
- end
54
- end
@@ -1,12 +0,0 @@
1
- Find places in the provided test code where stubbing and mocking are used. Search for the corresponding implementation source code of those dependencies elsewhere in the codebase to validate that the stub or mock matches the implementation that it is doubling. Use the tool functions provided to find and read the dependencies.
2
-
3
- Once you've found the dependencies, verify that any mocks and stubs accurately reflect the real implementation. If there are discrepancies, list them out alphabetically with:
4
-
5
- 1. The name of the mocked/stubbed method
6
- 2. What the mock/stub expects in terms of arguments and/or return values
7
- 3. What the actual implementation actually takes as arguments and returns
8
- 4. Suggestions for fixing the discrepancy
9
-
10
- Note: If there are no discrepancies, do not summarize those that accurately reflect their real implementations in the codebase, just respond "All mocks and stubs verified."
11
-
12
- IMPORTANT: There's absolutely no need for you to waste time grepping for methods/functions that you know belong to testing libraries such as Mocha's `expects` and `stubs`. Only search for the implementation of things that are stubbed and/or mocked in the test to verify whether the test code matches the implementation code.
@@ -1,53 +0,0 @@
1
- Now identify custom test helpers used in this test for the following purpose:
2
-
3
- 1. Analyzing if they are used correctly
4
- 2. Understanding test code that has had significant chunks of implementation abstracted away into helpers
5
- 3. Fully understanding custom assertions that are not included by default in Ruby on Rails or part of your base knowledge
6
-
7
- Your grep tool function is vital for this work. It provides 4 lines of context before and after the matching line.
8
-
9
- For example, if you call `grep(string: "def assert_sql")`, the output will include:
10
-
11
- ```
12
- .test/support/helpers/sql_assertions.rb-101- end
13
- .test/support/helpers/sql_assertions.rb-102- result
14
- .test/support/helpers/sql_assertions.rb-103- end
15
- .test/support/helpers/sql_assertions.rb-104-
16
- .test/support/helpers/sql_assertions.rb:105: def assert_sql(*patterns_to_match, **kwargs, &block)
17
- .test/support/helpers/sql_assertions.rb-106- mysql_only_test!
18
- .test/support/helpers/sql_assertions.rb-107-
19
- .test/support/helpers/sql_assertions.rb-108- result = T.let(nil, T.nilable(T::Boolean))
20
- .test/support/helpers/sql_assertions.rb-109- counter = ActiveRecord::SQLCounter.new(**kwargs)
21
- ```
22
-
23
- Unfortunately, many test helper methods are undocumented. In those cases (like the example above) the pre-context will be junk. However, there are a number of helper methods that do have very specific and narrow use cases, and those do tend to be well-documented. In those cases, you should use `read_file` to be able to read the full documentation.
24
-
25
- For example, here is the result of calling `grep(string: "def assert_sql_events")`
26
-
27
- ```
28
- .test/support/helpers/externals_helper.rb-93- # @example Logs events in the list that did not occur
29
- .test/support/helpers/externals_helper.rb-94- # expected_queries = { "Shop Load" => 1, "User Load" => 1 }
30
- .test/support/helpers/externals_helper.rb-95- # # Fails and reports that User Load occured 0 times instead of expected 1
31
- .test/support/helpers/externals_helper.rb-96- # assert_sql_events(expected_queries) { Shop.current_or_find(shop.id) }
32
- .test/support/helpers/externals_helper.rb:97: def assert_sql_events(expected_events, &block)
33
- .test/support/helpers/externals_helper.rb-98- mysql_only_test!
34
- .test/support/helpers/externals_helper.rb-99-
35
- .test/support/helpers/externals_helper.rb-100- mysql_events = ExternalsCollector.new(&block).events
36
- .test/support/helpers/externals_helper.rb-101- .select { |e| e.first == :mysql }
37
- ```
38
-
39
- Notice that the documentation for the `assert_sql_events` method is cutoff. Use your `read_file` tool function to get the whole test helper source code and gain better understanding of how it is intended to be used, with the side benefit of also being able to see how it is implemented.
40
-
41
- Note: You will undoubtedly already be familiar with some of Minitest and RSpec's built-in helpers. There is no need to search for those, since they are packaged as gems you won't find them anyway.
42
-
43
- DO NOT FORGET TO PREPEND `def` TO YOUR QUERY TO FIND A METHOD DEFINITION INSTEAD OF USAGES, otherwise you may bring back a very large and useless result set!!!
44
-
45
- Once you are done understanding the custom test helpers used in the test file, analyze and report on whether it seems like any of the helpers are:
46
-
47
- 1. Used incorrectly
48
- 2. Used unnecessarily
49
- 3. Any other problem related to the use of helper methods
50
-
51
- Where possible, use your best judgment to make recommendations for how to fix problems that you find, but ONLY related to test helpers.
52
-
53
- Note: You are only being used to help find problems so it is not necessary to report on correct usage of helpers or to make positive comments.
@@ -1,8 +0,0 @@
1
- As a senior software engineer and testing expert, evaluate the quality of this test file based on guidelines that will be subsequently provided.
2
-
3
- Next I will now provide the source code of the test that we will be analyzing, and then step you through a series of analysis activities, before finally asking you to provided a final report.
4
-
5
- <test>
6
- # <%= file %>
7
- <%= File.read(file) %>
8
- </test>
Binary file
@@ -1,6 +0,0 @@
1
- As a senior Ruby engineer and testing expert, evaluate the quality of this Ruby test file. Next I will now provide the source code of the test that we will be analyzing, and then step you through a series of analysis activities, before finally asking you to provided a final report.
2
-
3
- <test>
4
- # <%= file %>
5
- <%= File.read(file) %>
6
- </test>
@@ -1,6 +0,0 @@
1
- As a senior front-end engineer and testing expert, evaluate the quality of this test file. Next I will now provide the source code of the test that we will be analyzing, and then step you through a series of analysis activities, before finally asking you to provided a final report.
2
-
3
- <test>
4
- # <%= file %>
5
- <%= File.read(file) %>
6
- </test>
@@ -1,41 +0,0 @@
1
- name: Test Grading
2
- api_token: $(echo $OPENAI_API_KEY)
3
- # model: anthropic:claude-opus-4
4
- model: gpt-4.1-mini
5
-
6
- tools:
7
- - Roast::Tools::Grep
8
- - Roast::Tools::ReadFile
9
- - Roast::Tools::SearchFile
10
-
11
- # Uncomment this to run the workflow on modified tests automatically
12
- # each: '% cd $(git rev-parse --show-toplevel) && git status --porcelain | grep "_test\.rb" | cut -c4- | xargs realpath'
13
-
14
- steps:
15
- - read_dependencies
16
- - run_coverage
17
- -
18
- - analyze_coverage
19
- - verify_test_helpers
20
- - verify_mocks_and_stubs
21
- - generate_grades
22
- - calculate_final_grade
23
- - format_result
24
- - generate_recommendations
25
-
26
- # set non-default attributes for steps below
27
- analyze_coverage:
28
- # model: gpt-4.1-mini
29
- json: true
30
-
31
- generate_grades:
32
- # model: o3
33
- json: true
34
-
35
- generate_recommendations:
36
- # model: o3
37
- json: true
38
- params:
39
- max_completion_tokens: 5_000
40
-
41
-
@@ -1,76 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Demonstration of how to use the Roast instrumentation hooks
4
- # This file would typically be placed in PROJECT_ROOT/.roast/initializers/
5
- # for automatic loading during workflow execution
6
-
7
- # Example: Log all workflow and step events
8
- ActiveSupport::Notifications.subscribe(/roast\.workflow\./) do |name, start, finish, _id, payload|
9
- duration = finish - start
10
-
11
- case name
12
- when "roast.workflow.start"
13
- puts "\n🚀 Workflow starting: #{payload[:name]}"
14
- puts " Path: #{payload[:workflow_path]}"
15
- puts " Options: #{payload[:options]}"
16
- when "roast.workflow.complete"
17
- status = payload[:success] ? "✅ Successfully" : "❌ With errors"
18
- puts "\n#{status} completed workflow in #{duration.round(2)} seconds"
19
- end
20
- end
21
-
22
- # Example: Track step execution times
23
- ActiveSupport::Notifications.subscribe(/roast\.step\./) do |name, start, finish, _id, payload|
24
- duration = finish - start
25
-
26
- case name
27
- when "roast.step.start"
28
- puts "\n ▶️ Step starting: #{payload[:step_name]}"
29
- when "roast.step.complete"
30
- puts " ✅ Step completed: #{payload[:step_name]} (#{duration.round(3)}s)"
31
- when "roast.step.error"
32
- puts " ❌ Step failed: #{payload[:step_name]}"
33
- puts " Error: #{payload[:error]} - #{payload[:message]}"
34
- end
35
- end
36
-
37
- # Example: Monitor AI interactions
38
- ActiveSupport::Notifications.subscribe(/roast\.chat_completion\./) do |name, start, finish, _id, payload|
39
- case name
40
- when "roast.chat_completion.start"
41
- puts "\n 🤖 AI request starting (model: #{payload[:model]})"
42
- puts " Parameters: #{payload[:parameters].inspect}" if payload[:parameters].any?
43
- when "roast.chat_completion.complete"
44
- duration = finish - start
45
- puts " 🤖 AI request completed in #{duration.round(2)}s (execution time: #{payload[:execution_time].round(2)}s)"
46
- puts " Response size: #{payload[:response_size]} characters"
47
- when "roast.chat_completion.error"
48
- puts " 🤖 AI request failed: #{payload[:error]} - #{payload[:message]}"
49
- puts " Execution time: #{payload[:execution_time].round(2)}s"
50
- end
51
- end
52
-
53
- # Example: Track tool executions
54
- ActiveSupport::Notifications.subscribe(/roast\.tool\./) do |name, _start, _finish, _id, payload|
55
- case name
56
- when "roast.tool.execute"
57
- puts "\n 🔧 Executing tool: #{payload[:function_name]}"
58
- when "roast.tool.complete"
59
- puts " 🔧 Tool completed: #{payload[:function_name]} (#{payload[:execution_time].round(3)}s)"
60
- puts " Cache enabled: #{payload[:cache_enabled]}"
61
- when "roast.tool.error"
62
- puts " 🔧 Tool failed: #{payload[:function_name]}"
63
- puts " Error: #{payload[:error]} - #{payload[:message]}"
64
- puts " Execution time: #{payload[:execution_time].round(3)}s"
65
- end
66
- end
67
-
68
- # In a Shopify-specific initializer (e.g., .roast/initializers/monorail.rb),
69
- # you could replace these logging examples with actual Monorail tracking:
70
- #
71
- # ActiveSupport::Notifications.subscribe("roast.workflow.start") do |name, start, finish, id, payload|
72
- # Roast::Support::Monorail.track_command("run", {
73
- # "workflow_path" => payload[:workflow_path],
74
- # "name" => payload[:name]
75
- # })
76
- # end
@@ -1,50 +0,0 @@
1
- # Interpolation Example
2
-
3
- This example demonstrates how to use Roast's interpolation feature to create dynamic workflows.
4
-
5
- ## Overview
6
-
7
- The workflow in this example:
8
- 1. Analyzes a file and extracts its metadata
9
- 2. Extracts patterns based on the file type
10
- 3. Dynamically selects a report generation step based on the file extension
11
- 4. Outputs a completion message using the file's basename
12
-
13
- ## Interpolation Examples
14
-
15
- The workflow demonstrates several types of interpolation:
16
-
17
- - `{{ }}` syntax for embedding dynamic values
18
- - Access to file metadata via expressions like `{{file_basename}}` and `{{file_ext}}`
19
- - Dynamic step selection with `generate_report_for_{{file_ext}}`
20
- - Shell command interpolation with `$(echo "Processing completed for file: {{file_basename}}")`
21
-
22
- ## Running the Example
23
-
24
- To run this example with a Ruby file:
25
-
26
- ```bash
27
- roast execute workflow.yml /path/to/some_file.rb
28
- ```
29
-
30
- Or with a JavaScript file:
31
-
32
- ```bash
33
- roast execute workflow.yml /path/to/some_file.js
34
- ```
35
-
36
- The workflow will:
37
- 1. Extract the file's basename and extension
38
- 2. Store these in the workflow context
39
- 3. Dynamically choose a report generator based on file extension
40
- 4. Create a markdown report file
41
- 5. Output a completion message with the filename
42
-
43
- ## How Interpolation Works
44
-
45
- 1. When Roast processes a step name or shell command, it looks for `{{ }}` patterns
46
- 2. Expressions inside `{{ }}` are evaluated in the workflow's context using Ruby's `instance_eval`
47
- 3. This allows access to the workflow's variables, methods, and output hash
48
- 4. The evaluated expressions replace the `{{ }}` patterns in the step name or command
49
-
50
- This makes workflows dynamic and able to respond to different inputs without code changes.
@@ -1 +0,0 @@
1
- Analyze the file at: <%= workflow.file %>
@@ -1,27 +0,0 @@
1
- Extract some patterns about this file and return in json format like this:
2
-
3
- <json>
4
- {
5
- "code_patterns": {
6
- "class_structure": {
7
- "name": "Calculator",
8
- "instance_variables": ["@memory"],
9
- "method_count": 7,
10
- "method_types": {
11
- "constructor": ["initialize"],
12
- "operations": ["add", "subtract", "multiply", "divide"],
13
- "accessors": ["memory"],
14
- "utility": ["clear"]
15
- }
16
- },
17
- "error_handling": {
18
- "techniques": ["conditional raise", "zero check"],
19
- "examples": ["raise \"Division by zero!\" if number.zero?"]
20
- },
21
- "design_patterns": {
22
- "state": "Uses instance variable to maintain calculator state",
23
- "command": "Each operation method modifies the internal state"
24
- }
25
- }
26
- }
27
- </json>
@@ -1,3 +0,0 @@
1
- Generate a nicely formatted report based on the following metadata:
2
-
3
- <%= workflow.output[:analyze_patterns] %>
@@ -1,3 +0,0 @@
1
- Generate a nicely formatted report based on the following metadata:
2
-
3
- <%= workflow.output[:analyze_patterns] %>
@@ -1,48 +0,0 @@
1
- // Sample JavaScript file for testing interpolation in workflows
2
-
3
- class Calculator {
4
- constructor() {
5
- this.memory = 0;
6
- }
7
-
8
- add(number) {
9
- this.memory += number;
10
- return this.memory;
11
- }
12
-
13
- subtract(number) {
14
- this.memory -= number;
15
- return this.memory;
16
- }
17
-
18
- multiply(number) {
19
- this.memory *= number;
20
- return this.memory;
21
- }
22
-
23
- divide(number) {
24
- if (number === 0) {
25
- throw new Error("Division by zero!");
26
- }
27
- this.memory /= number;
28
- return this.memory;
29
- }
30
-
31
- getMemory() {
32
- return this.memory;
33
- }
34
-
35
- clear() {
36
- this.memory = 0;
37
- return this.memory;
38
- }
39
- }
40
-
41
- // Example usage
42
- if (require.main === module) {
43
- const calc = new Calculator();
44
- calc.add(10);
45
- calc.multiply(2);
46
- calc.subtract(5);
47
- console.log(`Result: ${calc.getMemory()}`);
48
- }
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Sample Ruby file for testing interpolation in workflows
4
-
5
- class Calculator
6
- def initialize
7
- @memory = 0
8
- end
9
-
10
- def add(number)
11
- @memory += number
12
- end
13
-
14
- def subtract(number)
15
- @memory -= number
16
- end
17
-
18
- def multiply(number)
19
- @memory *= number
20
- end
21
-
22
- def divide(number)
23
- raise "Division by zero!" if number.zero?
24
-
25
- @memory /= number
26
- end
27
-
28
- attr_reader :memory
29
-
30
- def clear
31
- @memory = 0
32
- end
33
- end
34
-
35
- # Example usage
36
- if __FILE__ == $PROGRAM_NAME
37
- calc = Calculator.new
38
- calc.add(10)
39
- calc.multiply(2)
40
- calc.subtract(5)
41
- puts "Result: #{calc.memory}"
42
- end
@@ -1 +0,0 @@
1
- You are a good robot.
Binary file
@@ -1,21 +0,0 @@
1
- name: interpolation_example
2
- model: gpt-4o-mini
3
-
4
- tools:
5
- - Roast::Tools::ReadFile
6
-
7
- steps:
8
- - analyze_file
9
- - analyze_patterns
10
- - generate_report_for_{{File.extname(workflow.file).sub('.', '')}}
11
- - '$(echo "Processing completed for file: {{File.basename(workflow.file)}}")'
12
-
13
- analyze_patterns:
14
- json: true
15
-
16
- generate_report_for_rb:
17
- print_response: true
18
-
19
- generate_report_for_md:
20
- print_response: true
21
-
@@ -1,88 +0,0 @@
1
- # Iteration Mechanisms Implementation
2
-
3
- This document provides an overview of how the iteration mechanisms are implemented in Roast.
4
-
5
- ## Core Components
6
-
7
- ### 1. Schema Extensions
8
-
9
- The workflow schema has been extended to support two new iteration constructs:
10
-
11
- - **Repeat** - For conditional repetition until a condition is met
12
- - **Each** - For iterating over collections with a variable binding
13
-
14
- These schema extensions define the structure and validation rules for the iteration YAML syntax.
15
-
16
- ### 2. Step Classes
17
-
18
- Two new step classes handle the actual iteration logic:
19
-
20
- - **RepeatStep** - Executes steps repeatedly until a condition is met or a maximum iteration count is reached
21
- - **EachStep** - Iterates over a collection, binding each item to a variable, and executes steps for each item
22
-
23
- Both inherit from a common `BaseIterationStep` class that provides shared functionality.
24
-
25
- ### 3. Pattern Matching
26
-
27
- The `WorkflowExecutor` has been enhanced with pattern matching to recognize the `repeat` and `each` keywords and dispatch to the appropriate step classes:
28
-
29
- ```ruby
30
- case name
31
- when "repeat"
32
- execute_repeat_step(command)
33
- when "each"
34
- # Handle 'each' step with its special format
35
- execute_each_step(step)
36
- else
37
- # Handle regular steps
38
- end
39
- ```
40
-
41
- ### 4. State Management
42
-
43
- Both iteration types include state management to:
44
-
45
- - Track current iteration number
46
- - Save state after each iteration
47
- - Support resumption after failures
48
- - Provide safety limits against infinite loops
49
-
50
- ## Iteration Flow
51
-
52
- ### RepeatStep Flow
53
-
54
- 1. Start with iteration count = 0
55
- 2. Execute the nested steps in sequence
56
- 3. Evaluate the until condition
57
- 4. If condition is true or max_iterations is reached, stop
58
- 5. Otherwise, increment iteration count and go back to step 2
59
- 6. Return the results of all iterations
60
-
61
- ### EachStep Flow
62
-
63
- 1. Resolve the collection expression
64
- 2. For each item in the collection:
65
- a. Set the named variable (accessible in steps through a getter method)
66
- b. Execute the nested steps
67
- c. Save state
68
- 3. Return the results from all iterations
69
-
70
- ## Safety Mechanisms
71
-
72
- - **max_iterations** parameter prevents infinite loops
73
- - State is saved after each iteration for resumption capability
74
- - Robust error handling during condition evaluation and step execution
75
- - Collection type checking ensures iterable objects
76
-
77
- ## Usage Examples
78
-
79
- The workflow.yml and step files in this directory demonstrate practical applications of these iteration mechanisms for code quality analysis.
80
-
81
- ## Integration with Existing Workflow Engine
82
-
83
- The iteration mechanism integrates seamlessly with the existing workflow engine:
84
-
85
- - Uses the same state persistence mechanisms
86
- - Follows the same execution models
87
- - Maintains compatibility with all existing steps
88
- - Supports interpolation within iteration constructs
@@ -1,68 +0,0 @@
1
- # Code Quality Analysis Workflow
2
-
3
- This example demonstrates the use of Roast's iteration features to analyze and improve code quality across a codebase.
4
-
5
- ## What it does
6
-
7
- 1. Collects Ruby files from the codebase for analysis
8
- 2. Analyzes each file for complexity, code smells, and potential improvements
9
- 3. Generates recommendations for each file
10
- 4. Prioritizes the identified issues by impact and difficulty
11
- 5. Automatically implements fixes for the highest-priority issues
12
- 6. Verifies each fix before moving to the next one
13
- 7. Continues until either 5 fixes have been applied or all issues are addressed
14
- 8. Generates a summary report of changes made
15
-
16
- ## Iteration Features Demonstrated
17
-
18
- ### Collection Iteration with `each`
19
-
20
- The workflow uses the `each` construct to iterate through Ruby files:
21
-
22
- ```yaml
23
- - each: "output['get_files_to_analyze'].split('\n')"
24
- as: "current_file"
25
- steps:
26
- - read_file
27
- - analyze_complexity
28
- - generate_recommendations
29
- ```
30
-
31
- This makes the current file available as `current_file` in each step, allowing the analysis steps to process each file individually.
32
-
33
- ### Conditional Repetition with `repeat`
34
-
35
- The workflow uses the `repeat` construct to iteratively fix issues until a condition is met:
36
-
37
- ```yaml
38
- - repeat:
39
- steps:
40
- - select_next_issue
41
- - implement_fix
42
- - verify_fix
43
- - update_fix_count
44
- until: "output['update_fix_count']['fixes_applied'] >= 5 || output['select_next_issue']['no_issues_left'] == true"
45
- max_iterations: 10
46
- ```
47
-
48
- This continues applying fixes until either:
49
- - 5 fixes have been successfully applied
50
- - No more issues remain to be fixed
51
- - The maximum of 10 iterations is reached (safety limit)
52
-
53
- ## Running the Example
54
-
55
- To run this workflow:
56
-
57
- ```bash
58
- roast run examples/iteration/workflow.yml --target=/path/to/your/project
59
- ```
60
-
61
- The workflow will analyze the Ruby files in your project, suggest improvements, and apply the highest-priority fixes.
62
-
63
- ## Customizing
64
-
65
- - Adjust the file selection criteria in `get_files_to_analyze`
66
- - Modify the analysis criteria in `analyze_complexity`
67
- - Change the fix limit in the `until` condition
68
- - Set a different `max_iterations` value to control the maximum number of fixes
@@ -1,22 +0,0 @@
1
- I'll analyze the code complexity of the file <%= current_file %>, which I've read in the previous step.
2
-
3
- I'll examine the following aspects:
4
- 1. Cyclomatic complexity (number of decision paths)
5
- 2. Method length and complexity
6
- 3. Class size and responsibilities
7
- 4. Code smells (long parameter lists, deeply nested blocks, etc.)
8
- 5. Potential performance bottlenecks
9
- 6. Opportunities for refactoring
10
-
11
- ```ruby
12
- <%= output.read_file %>
13
- ```
14
-
15
- Based on this analysis, I'll provide a structured assessment of the code quality issues found.
16
-
17
- For each issue identified, I'll assign:
18
- - Severity (high, medium, low)
19
- - Type (complexity, maintainability, performance, style)
20
- - Location (line numbers, method/class names)
21
- - Brief description of the issue
22
- - Suggested improvement