roast-ai 0.3.0 → 0.4.0

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 (127) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +32 -0
  4. data/CLAUDE.md +52 -1
  5. data/Gemfile +3 -1
  6. data/Gemfile.lock +63 -16
  7. data/README.md +115 -5
  8. data/bin/roast +1 -1
  9. data/claude-swarm.yml +210 -0
  10. data/docs/AGENT_STEPS.md +264 -0
  11. data/examples/agent_workflow/README.md +75 -0
  12. data/examples/agent_workflow/apply_refactorings/prompt.md +22 -0
  13. data/examples/agent_workflow/identify_code_smells/prompt.md +15 -0
  14. data/examples/agent_workflow/summarize_improvements/prompt.md +18 -0
  15. data/examples/agent_workflow/workflow.yml +16 -0
  16. data/examples/available_tools_demo/README.md +42 -0
  17. data/examples/available_tools_demo/analyze_files/prompt.md +6 -0
  18. data/examples/available_tools_demo/explore_directory/prompt.md +6 -0
  19. data/examples/available_tools_demo/workflow.yml +32 -0
  20. data/examples/available_tools_demo/write_summary/prompt.md +6 -0
  21. data/examples/case_when/detect_language/prompt.md +2 -2
  22. data/examples/grading/README.md +71 -0
  23. data/examples/grading/run_coverage.rb +0 -2
  24. data/examples/iteration/analyze_complexity/prompt.md +2 -2
  25. data/examples/iteration/generate_recommendations/prompt.md +2 -2
  26. data/examples/iteration/implement_fix/prompt.md +2 -2
  27. data/examples/iteration/prioritize_issues/prompt.md +1 -1
  28. data/examples/iteration/prompts/analyze_file.md +2 -2
  29. data/examples/iteration/prompts/generate_summary.md +1 -1
  30. data/examples/iteration/prompts/update_report.md +3 -3
  31. data/examples/iteration/prompts/write_report.md +3 -3
  32. data/examples/iteration/read_file/prompt.md +2 -2
  33. data/examples/iteration/select_next_issue/prompt.md +2 -2
  34. data/examples/iteration/update_fix_count/prompt.md +4 -4
  35. data/examples/iteration/verify_fix/prompt.md +3 -3
  36. data/examples/mcp/README.md +3 -3
  37. data/examples/mcp/analyze_changes/prompt.md +1 -1
  38. data/examples/mcp/database_workflow.yml +1 -1
  39. data/examples/mcp/fetch_pr_context/prompt.md +1 -1
  40. data/examples/mcp/github_workflow.yml +1 -1
  41. data/examples/mcp/post_review/prompt.md +1 -1
  42. data/examples/pre_post_processing/analyze_test_file/prompt.md +1 -1
  43. data/examples/pre_post_processing/improve_test_coverage/prompt.md +1 -1
  44. data/examples/pre_post_processing/optimize_test_performance/prompt.md +1 -1
  45. data/examples/pre_post_processing/post_processing/aggregate_metrics/prompt.md +2 -2
  46. data/examples/pre_post_processing/post_processing/generate_summary_report/prompt.md +1 -1
  47. data/examples/pre_post_processing/pre_processing/setup_test_environment/prompt.md +1 -1
  48. data/examples/pre_post_processing/validate_changes/prompt.md +2 -2
  49. data/examples/user_input/README.md +90 -0
  50. data/examples/user_input/funny_name/create_backstory/prompt.md +10 -0
  51. data/examples/user_input/funny_name/workflow.yml +26 -0
  52. data/examples/user_input/generate_summary/prompt.md +11 -0
  53. data/examples/user_input/simple_input_demo/workflow.yml +35 -0
  54. data/examples/user_input/survey_workflow.yml +71 -0
  55. data/examples/user_input/welcome_message/prompt.md +3 -0
  56. data/examples/user_input/workflow.yml +73 -0
  57. data/examples/workflow_generator/create_workflow_files/prompt.md +1 -1
  58. data/lib/roast/errors.rb +6 -4
  59. data/lib/roast/helpers/function_caching_interceptor.rb +0 -2
  60. data/lib/roast/helpers/logger.rb +12 -35
  61. data/lib/roast/helpers/minitest_coverage_runner.rb +0 -1
  62. data/lib/roast/helpers/prompt_loader.rb +0 -2
  63. data/lib/roast/resources/api_resource.rb +0 -4
  64. data/lib/roast/resources/url_resource.rb +0 -3
  65. data/lib/roast/resources.rb +0 -8
  66. data/lib/roast/tools/ask_user.rb +0 -2
  67. data/lib/roast/tools/bash.rb +0 -3
  68. data/lib/roast/tools/cmd.rb +0 -3
  69. data/lib/roast/tools/coding_agent.rb +1 -8
  70. data/lib/roast/tools/grep.rb +0 -3
  71. data/lib/roast/tools/helpers/coding_agent_message_formatter.rb +1 -4
  72. data/lib/roast/tools/read_file.rb +0 -2
  73. data/lib/roast/tools/search_file.rb +0 -2
  74. data/lib/roast/tools/update_files.rb +0 -4
  75. data/lib/roast/tools/write_file.rb +0 -3
  76. data/lib/roast/tools.rb +0 -13
  77. data/lib/roast/value_objects/step_name.rb +14 -3
  78. data/lib/roast/value_objects/workflow_path.rb +0 -2
  79. data/lib/roast/value_objects.rb +4 -4
  80. data/lib/roast/version.rb +1 -1
  81. data/lib/roast/workflow/agent_step.rb +26 -0
  82. data/lib/roast/workflow/api_configuration.rb +0 -4
  83. data/lib/roast/workflow/base_iteration_step.rb +0 -4
  84. data/lib/roast/workflow/base_step.rb +54 -28
  85. data/lib/roast/workflow/base_workflow.rb +2 -21
  86. data/lib/roast/workflow/case_executor.rb +0 -1
  87. data/lib/roast/workflow/case_step.rb +0 -4
  88. data/lib/roast/workflow/command_executor.rb +0 -2
  89. data/lib/roast/workflow/conditional_executor.rb +0 -1
  90. data/lib/roast/workflow/conditional_step.rb +0 -4
  91. data/lib/roast/workflow/configuration.rb +3 -10
  92. data/lib/roast/workflow/configuration_loader.rb +0 -2
  93. data/lib/roast/workflow/configuration_parser.rb +1 -7
  94. data/lib/roast/workflow/dot_access_hash.rb +16 -1
  95. data/lib/roast/workflow/error_handler.rb +0 -3
  96. data/lib/roast/workflow/expression_evaluator.rb +0 -3
  97. data/lib/roast/workflow/file_state_repository.rb +0 -5
  98. data/lib/roast/workflow/input_executor.rb +41 -0
  99. data/lib/roast/workflow/input_step.rb +163 -0
  100. data/lib/roast/workflow/iteration_executor.rb +0 -2
  101. data/lib/roast/workflow/output_handler.rb +0 -2
  102. data/lib/roast/workflow/output_manager.rb +0 -2
  103. data/lib/roast/workflow/prompt_step.rb +1 -1
  104. data/lib/roast/workflow/replay_handler.rb +0 -3
  105. data/lib/roast/workflow/resource_resolver.rb +0 -3
  106. data/lib/roast/workflow/session_manager.rb +0 -3
  107. data/lib/roast/workflow/state_manager.rb +0 -2
  108. data/lib/roast/workflow/step_executor_coordinator.rb +34 -11
  109. data/lib/roast/workflow/step_executor_factory.rb +0 -5
  110. data/lib/roast/workflow/step_executor_registry.rb +1 -4
  111. data/lib/roast/workflow/step_executors/hash_step_executor.rb +0 -3
  112. data/lib/roast/workflow/step_executors/parallel_step_executor.rb +0 -3
  113. data/lib/roast/workflow/step_executors/string_step_executor.rb +0 -2
  114. data/lib/roast/workflow/step_factory.rb +56 -0
  115. data/lib/roast/workflow/step_loader.rb +30 -16
  116. data/lib/roast/workflow/step_orchestrator.rb +3 -2
  117. data/lib/roast/workflow/step_type_resolver.rb +28 -1
  118. data/lib/roast/workflow/validator.rb +0 -4
  119. data/lib/roast/workflow/workflow_executor.rb +0 -16
  120. data/lib/roast/workflow/workflow_initializer.rb +1 -8
  121. data/lib/roast/workflow/workflow_runner.rb +0 -7
  122. data/lib/roast/workflow.rb +0 -15
  123. data/lib/roast.rb +55 -10
  124. data/roast.gemspec +2 -1
  125. data/schema/workflow.json +46 -0
  126. metadata +44 -6
  127. data/lib/roast/helpers.rb +0 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 28055339ac18d63a1abd7151943558a114df2e48930c63aa63c65536d193061b
4
- data.tar.gz: c5be17b70caa32f73dca316ab4816d0b92c0c7121747b3e5492f58124e815f87
3
+ metadata.gz: 0c0f1a837c5dafcaecb8443e93a4076c11566f1c3bea1d6835121628fbdf79a7
4
+ data.tar.gz: ab3679b374486831cbf90ab3a259178d48d4e53d5d5dbdc2a2d43537399e4ca9
5
5
  SHA512:
6
- metadata.gz: d5b300fd001d8cc55ecdb5751bc891840732f63be8e951e2c4333a178fde6c2197a2b0063f3add45b48e85251e9b2ee28119d237322bb8f89af86c2208345c1f
7
- data.tar.gz: c579010aedef591cd1a72fb6cd34c15db38fc225550aa17a841397e5f8849c09c5f87cf81da3f04f2300c5dcac704ab2d8a0f78fe8fd443fabfe62e67780a015
6
+ metadata.gz: 3061d9f04b7f886e3a6d588eb729e10062f6310d5973c7ed5181975f27a385c20d8ff8880ecb7e61abd54dfbd87795211313e1c9a6d2a630269d7c4559ae7cae
7
+ data.tar.gz: 7962e4991590700003f3f8a827435214ef9aa90fa4324d34d3b421f11d5f647e43663e17189a0b43f81d6fa124bbf68a269f9674a493994832b9ab5c03f192a6
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,38 @@ 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.0] - 2025-06-12
9
+
10
+ ### Added
11
+ - **Input step type** for collecting user input during workflow execution (#154)
12
+ - Interactive prompts pause workflow execution to collect user input
13
+ - Supports multiple input types: `text` (default), `confirm`, `select`, and `password`
14
+ - `confirm` type provides yes/no prompts with boolean results
15
+ - `select` type allows choosing from a list of options
16
+ - `password` type masks input for sensitive data using io/console
17
+ - Input values are stored in workflow output and accessible via dot notation (e.g., `{{output.step_name}}`)
18
+ - Integrates with CLI::UI for consistent formatting and user experience
19
+ - **Agent step type** for direct pass-through to coding agents (#151)
20
+ - Steps prefixed with `^` send prompts directly to the CodingAgent tool
21
+ - Supports both file-based and inline agent prompts
22
+ - Bypasses LLM interpretation for precise agent instructions
23
+
24
+ ### Fixed
25
+ - DotAccessHash array wrapping and template response handling
26
+ - CLI::UI formatting and color handling for better terminal output
27
+
28
+ ## [0.3.1] - 2025-06-05
29
+
30
+ ### Added
31
+ - Default `print_response: true` for the last step in a workflow (#100)
32
+ - The last step now automatically prints its response unless explicitly configured otherwise
33
+ - Helps newcomers who would otherwise see no output from their workflows
34
+ - Works with all step types: string steps, hash steps with variable assignment, and conditional steps
35
+ - Parallel steps and iteration steps are intelligently handled (no automatic output since there's no single "last" step)
36
+
37
+ ### Fixed
38
+ - PromptStep now properly passes `print_response`, `json`, and `params` parameters to chat_completion
39
+
8
40
  ## [0.3.0] - 2025-06-04
9
41
 
10
42
  ### Changed
data/CLAUDE.md CHANGED
@@ -4,6 +4,7 @@ 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
 
@@ -51,11 +52,14 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
51
52
  - ConditionalExecutor handles conditionals (if, unless)
52
53
  - Don't combine different responsibilities in one class
53
54
  - **Do not implement prompts "inline" using a prompt: attribute nested under step names, that violates the primary design architecture of Roast**
55
+ - 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
56
+ - When fixing code smells, you don't have to worry about internal backwards compatibility
54
57
 
55
58
  ## Guidance and Expectations
56
59
 
57
60
  - Do not decide unilaterally to leave code for the sake of "backwards compatibility"... always run those decisions by me first.
58
61
  - Don't ever commit and push changes unless directly told to do so
62
+ - You can't test input steps yourself, ask me to do it
59
63
 
60
64
  ## Git Workflow Practices
61
65
 
@@ -130,6 +134,48 @@ gh pr view {pr_number}
130
134
  gh pr diff {pr_number}
131
135
  ```
132
136
 
137
+ ### Issue Labeling and Project Management
138
+
139
+ When creating GitHub issues, always check available labels, projects, and milestones first:
140
+
141
+ ```bash
142
+ # List all available labels
143
+ gh api repos/Shopify/roast/labels | jq '.[].name'
144
+
145
+ # List all milestones
146
+ gh api repos/Shopify/roast/milestones | jq '.[] | {title: .title, number: .number, state: .state}'
147
+
148
+ # List projects linked to the roast repository
149
+ gh api graphql -f query='
150
+ {
151
+ repository(owner: "Shopify", name: "roast") {
152
+ projectsV2(first: 10) {
153
+ nodes {
154
+ title
155
+ number
156
+ url
157
+ }
158
+ }
159
+ }
160
+ }' --jq '.data.repository.projectsV2.nodes[] | {title: .title, number: .number, url: .url}'
161
+ ```
162
+
163
+ **Issue Creation Workflow**:
164
+ 1. First check what labels exist and apply appropriate ones when creating the issue
165
+ 2. After creating the issue, ask the user if they want it added to an existing milestone
166
+ 3. Ask the user if they want it added to a particular project board
167
+
168
+ ```bash
169
+ # Create issue with labels
170
+ gh api repos/Shopify/roast/issues -X POST -F title="Issue Title" -F body="Issue description" -F 'labels=["bug", "enhancement"]'
171
+
172
+ # Add issue to a milestone (after creation)
173
+ gh api repos/Shopify/roast/issues/{issue_number} -X PATCH -F milestone={milestone_number}
174
+
175
+ # Add issue to a GitHub Project
176
+ gh project item-add {project_number} --url https://github.com/Shopify/roast/issues/{issue_number}
177
+ ```
178
+
133
179
  #### Formatting Tips for GitHub API
134
180
  1. Use literal newlines in the body text instead of `\n` escape sequences
135
181
  2. When formatting is stripped (like backticks), use alternatives:
@@ -167,4 +213,9 @@ gh pr diff {pr_number}
167
213
  - Avoid premature optimization outside of hot paths
168
214
  - Consider the tradeoff between readability and performance
169
215
  - Suggest optimizations that improve both clarity and performance
170
- ```
216
+
217
+ ## CLI::UI Formatting Tips
218
+ - To apply color to terminal output using CLI::UI, use the following syntax:
219
+ ```ruby
220
+ puts ::CLI::UI.fmt("{{red:This field is required. Please provide a value.}}")
221
+ ```
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,5 @@ gem "rubocop-shopify", require: false
18
18
  gem "vcr", require: false
19
19
  gem "webmock", require: false
20
20
  gem "minitest-rg"
21
+
22
+ gem "claude_swarm"
data/Gemfile.lock CHANGED
@@ -1,15 +1,16 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- roast-ai (0.3.0)
4
+ roast-ai (0.4.0)
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
12
  thor (~> 1.3)
13
+ zeitwerk (~> 2.6)
13
14
 
14
15
  GEM
15
16
  remote: https://rubygems.org/
@@ -33,17 +34,49 @@ GEM
33
34
  base64 (0.3.0)
34
35
  benchmark (0.4.1)
35
36
  bigdecimal (3.2.2)
36
- cgi (0.4.2)
37
- cli-ui (2.3.1)
37
+ cgi (0.5.0)
38
+ claude_swarm (0.1.15)
39
+ fast-mcp-annotations
40
+ thor (~> 1.3)
41
+ cli-ui (2.3.0)
38
42
  coderay (1.1.3)
39
43
  concurrent-ruby (1.3.5)
40
44
  connection_pool (2.5.3)
41
45
  crack (1.0.0)
42
46
  bigdecimal
43
47
  rexml
44
- diff-lcs (1.6.1)
48
+ diff-lcs (1.6.2)
45
49
  dotenv (3.1.8)
46
50
  drb (2.2.3)
51
+ dry-configurable (1.3.0)
52
+ dry-core (~> 1.1)
53
+ zeitwerk (~> 2.6)
54
+ dry-core (1.1.0)
55
+ concurrent-ruby (~> 1.0)
56
+ logger
57
+ zeitwerk (~> 2.6)
58
+ dry-inflector (1.2.0)
59
+ dry-initializer (3.2.0)
60
+ dry-logic (1.6.0)
61
+ bigdecimal
62
+ concurrent-ruby (~> 1.0)
63
+ dry-core (~> 1.1)
64
+ zeitwerk (~> 2.6)
65
+ dry-schema (1.14.1)
66
+ concurrent-ruby (~> 1.0)
67
+ dry-configurable (~> 1.0, >= 1.0.1)
68
+ dry-core (~> 1.1)
69
+ dry-initializer (~> 3.2)
70
+ dry-logic (~> 1.5)
71
+ dry-types (~> 1.8)
72
+ zeitwerk (~> 2.6)
73
+ dry-types (1.8.3)
74
+ bigdecimal (~> 3.0)
75
+ concurrent-ruby (~> 1.0)
76
+ dry-core (~> 1.0)
77
+ dry-inflector (~> 1.0)
78
+ dry-logic (~> 1.4)
79
+ zeitwerk (~> 2.6)
47
80
  event_stream_parser (1.0.0)
48
81
  faraday (2.13.1)
49
82
  faraday-net_http (>= 2.0, < 3.5)
@@ -55,6 +88,13 @@ GEM
55
88
  net-http (>= 0.5.0)
56
89
  faraday-retry (2.3.1)
57
90
  faraday (~> 2.0)
91
+ fast-mcp-annotations (1.5.2)
92
+ addressable (~> 2.8)
93
+ base64
94
+ dry-schema (~> 1.14)
95
+ json (~> 2.0)
96
+ mime-types (~> 3.4)
97
+ rack (~> 3.1)
58
98
  ffi (1.17.2-arm64-darwin)
59
99
  ffi (1.17.2-x86_64-linux-gnu)
60
100
  formatador (1.1.0)
@@ -73,14 +113,14 @@ GEM
73
113
  guard-minitest (2.4.6)
74
114
  guard-compat (~> 1.2)
75
115
  minitest (>= 3.0)
76
- hashdiff (1.1.2)
116
+ hashdiff (1.2.0)
77
117
  i18n (1.14.7)
78
118
  concurrent-ruby (~> 1.0)
79
119
  json (2.12.2)
80
120
  json-schema (5.1.1)
81
121
  addressable (~> 2.8)
82
122
  bigdecimal (~> 3.1)
83
- language_server-protocol (3.17.0.4)
123
+ language_server-protocol (3.17.0.5)
84
124
  lint_roller (1.1.0)
85
125
  listen (3.9.0)
86
126
  rb-fsevent (~> 0.10, >= 0.10.3)
@@ -88,6 +128,10 @@ GEM
88
128
  logger (1.7.0)
89
129
  lumberjack (1.2.10)
90
130
  method_source (1.1.0)
131
+ mime-types (3.7.0)
132
+ logger
133
+ mime-types-data (~> 3.2025, >= 3.2025.0507)
134
+ mime-types-data (3.2025.0603)
91
135
  minitest (5.25.5)
92
136
  minitest-rg (5.3.0)
93
137
  minitest (~> 5.0)
@@ -114,22 +158,23 @@ GEM
114
158
  pry (0.15.2)
115
159
  coderay (~> 1.1)
116
160
  method_source (~> 1.0)
117
- public_suffix (6.0.1)
161
+ public_suffix (6.0.2)
118
162
  racc (1.8.1)
163
+ rack (3.1.16)
119
164
  rainbow (3.1.1)
120
- raix (1.0.0)
165
+ raix (1.0.1)
121
166
  activesupport (>= 6.0)
122
167
  faraday-retry (~> 2.0)
123
168
  open_router (~> 0.2)
124
169
  ostruct
125
170
  ruby-openai (~> 7)
126
- rake (13.2.1)
171
+ rake (13.3.0)
127
172
  rb-fsevent (0.11.2)
128
173
  rb-inotify (0.11.1)
129
174
  ffi (~> 1.0)
130
175
  regexp_parser (2.10.0)
131
176
  rexml (3.4.1)
132
- rubocop (1.75.3)
177
+ rubocop (1.76.0)
133
178
  json (~> 2.3)
134
179
  language_server-protocol (~> 3.17.0.2)
135
180
  lint_roller (~> 1.1.0)
@@ -137,13 +182,13 @@ GEM
137
182
  parser (>= 3.3.0.2)
138
183
  rainbow (>= 2.2.2, < 4.0)
139
184
  regexp_parser (>= 2.9.3, < 3.0)
140
- rubocop-ast (>= 1.44.0, < 2.0)
185
+ rubocop-ast (>= 1.45.0, < 2.0)
141
186
  ruby-progressbar (~> 1.7)
142
187
  unicode-display_width (>= 2.4.0, < 4.0)
143
- rubocop-ast (1.44.1)
188
+ rubocop-ast (1.45.0)
144
189
  parser (>= 3.3.7.2)
145
190
  prism (~> 1.4)
146
- rubocop-shopify (2.17.0)
191
+ rubocop-shopify (2.17.1)
147
192
  rubocop (~> 1.62)
148
193
  ruby-openai (7.4.0)
149
194
  event_stream_parser (>= 0.3.0, < 2.0.0)
@@ -166,14 +211,16 @@ GEM
166
211
  addressable (>= 2.8.0)
167
212
  crack (>= 0.3.2)
168
213
  hashdiff (>= 0.4.0, < 2.0.0)
214
+ zeitwerk (2.7.3)
169
215
 
170
216
  PLATFORMS
171
- arm64-darwin-23
217
+ arm64-darwin
172
218
  x86_64-linux
173
219
 
174
220
  DEPENDENCIES
175
221
  cgi
176
- cli-ui
222
+ claude_swarm
223
+ cli-ui (= 2.3.0)
177
224
  dotenv
178
225
  guard
179
226
  guard-minitest
data/README.md CHANGED
@@ -82,13 +82,13 @@ steps:
82
82
 
83
83
  ## Try it
84
84
 
85
- If you don't have one already, get an OpenAI key from [here](https://platform.openai.com/settings/organization/api-keys). You will need an account with a credit card, make sure that a basic completion works.
85
+ If you dont have one already, get an OpenAI key from [here](https://platform.openai.com/settings/organization/api-keys). You will need an account with a credit card and credits applied to the associated project. Make sure that a basic completion works:
86
86
 
87
87
  ```bash
88
88
  export OPENAI_API_KEY=sk-proj-....
89
89
 
90
90
  curl -H "Content-Type: application/json" \
91
- -H "Authorization: Bearer $API_TOKEN" \
91
+ -H "Authorization: Bearer $OPENAI_API_KEY" \
92
92
  -d '{"model":"gpt-4.1-mini","messages":[{"role":"user","content":"What is 1+1?"}]}' \
93
93
  https://api.openai.com/v1/chat/completions
94
94
  ```
@@ -270,6 +270,70 @@ Roast supports several types of steps:
270
270
  ```
271
271
  This creates a simple prompt-response interaction without tool calls or looping. It's detected by the presence of spaces in the step name and is useful for summarization or simple questions at the end of a workflow.
272
272
 
273
+ 8. **Agent step**: Direct pass-through to coding agents (e.g., Claude Code)
274
+ ```yaml
275
+ steps:
276
+ - ^fix_linting_errors # File-based agent prompt
277
+ - ^Review the code and identify any performance issues # Inline agent prompt
278
+ - regular_analysis # Normal step through LLM
279
+ ```
280
+ Agent steps are prefixed with `^` and send the prompt content directly to the CodingAgent tool without LLM translation. This is useful when you want to give precise instructions to a coding agent without the intermediate interpretation layer. Agent steps support both file-based prompts (`fix_linting_errors/prompt.md`) and inline prompts (text with spaces).
281
+
282
+ 9. **Input step**: Interactive prompts for user input during workflow execution
283
+ ```yaml
284
+ steps:
285
+ - analyze_code
286
+ - get_user_feedback:
287
+ prompt: "Should we proceed with the refactoring? (yes/no)"
288
+ type: confirm
289
+ - review_changes:
290
+ prompt: "Enter your review comments"
291
+ type: text
292
+ - select_strategy:
293
+ prompt: "Choose optimization strategy"
294
+ type: select
295
+ options:
296
+ - "Performance optimization"
297
+ - "Memory optimization"
298
+ - "Code clarity"
299
+ - api_configuration:
300
+ prompt: "Enter API key"
301
+ type: password
302
+ ```
303
+
304
+ Input steps pause workflow execution to collect user input. They support several types:
305
+ - `text`: Free-form text input (default if type not specified)
306
+ - `confirm`: Yes/No confirmation prompts
307
+ - `select`: Choice from a list of options
308
+ - `password`: Masked input for sensitive data
309
+
310
+ The user's input is stored in the workflow output using the step name as the key and can be accessed in subsequent steps via interpolation (e.g., `{{output.get_user_feedback}}`).
311
+
312
+ #### Step Configuration
313
+
314
+ Steps can be configured with various options to control their behavior:
315
+
316
+ ```yaml
317
+ steps:
318
+ - analyze_code # Simple step reference
319
+ - generate_report: # Step with configuration
320
+ model: gpt-4o # Override the global model for this step
321
+ print_response: true # Explicitly control output printing
322
+ json: true # Request JSON-formatted response
323
+ params: # Additional parameters for the API call
324
+ temperature: 0.8
325
+ ```
326
+
327
+ **Configuration options:**
328
+ - `model`: Override the workflow's default model for this specific step
329
+ - `print_response`: Control whether the step's response is included in the final output (default: `false`, except for the last step which defaults to `true` as of v0.3.1)
330
+ - `json`: Request a JSON-formatted response from the model
331
+ - `params`: Additional parameters passed to the model API (temperature, max_tokens, etc.)
332
+ - `path`: Custom directory path for the step's prompt files
333
+ - `coerce_to`: Type coercion for the step result (`:boolean`, `:llm_boolean`, `:iterable`)
334
+
335
+ **Automatic Last Step Output**: As of version 0.3.1, the last step in a workflow automatically has `print_response: true` unless explicitly configured otherwise. This ensures that newcomers to Roast see output from their workflows by default.
336
+
273
337
  #### Shared Configuration
274
338
 
275
339
  Roast supports sharing common configuration and steps across multiple workflows using a `shared.yml` file.
@@ -633,6 +697,52 @@ tools:
633
697
 
634
698
  Custom descriptions help the LLM understand when and how to use each command, making your workflows more effective.
635
699
 
700
+ ### Step-Level Tool Filtering
701
+
702
+ You can restrict which tools are available to specific steps using the `available_tools` configuration:
703
+
704
+ ```yaml
705
+ # Define all tools globally
706
+ tools:
707
+ - Roast::Tools::Grep
708
+ - Roast::Tools::ReadFile
709
+ - Roast::Tools::WriteFile
710
+ - Roast::Tools::Cmd:
711
+ allowed_commands:
712
+ - pwd
713
+ - ls
714
+ - echo
715
+
716
+ # Configure steps with specific tool access
717
+ explore_directory:
718
+ available_tools:
719
+ - pwd
720
+ - ls
721
+
722
+ analyze_files:
723
+ available_tools:
724
+ - grep
725
+ - read_file
726
+
727
+ write_summary:
728
+ available_tools:
729
+ - write_file
730
+ - echo
731
+ ```
732
+
733
+ This feature provides:
734
+ - **Security**: Each step only has access to the tools it needs
735
+ - **Performance**: Reduces the tool list sent to the LLM
736
+ - **Clarity**: Makes tool usage explicit for each step
737
+
738
+ Key points:
739
+ - Use snake_case tool names (e.g., `read_file` for `Roast::Tools::ReadFile`)
740
+ - For `Cmd` tool, use the specific command names (e.g., `pwd`, `ls`)
741
+ - When `available_tools` is not specified, all tools remain available (backward compatible)
742
+ - Empty array (`available_tools: []`) means no tools for that step
743
+
744
+ See the [available_tools_demo](examples/available_tools_demo/) for a complete example.
745
+
636
746
  #### ReadFile
637
747
 
638
748
  Reads the contents of a file from the filesystem.
@@ -811,14 +921,14 @@ tools:
811
921
  - Documentation:
812
922
  url: https://gitmcp.io/myorg/myrepo/docs
813
923
  env:
814
- - "Authorization: Bearer {{env.API_TOKEN}}"
924
+ - "Authorization: Bearer {{ENV['API_TOKEN']}}"
815
925
 
816
926
  # MCP tools with stdio
817
927
  - GitHub:
818
928
  command: npx
819
929
  args: ["-y", "@modelcontextprotocol/server-github"]
820
930
  env:
821
- GITHUB_PERSONAL_ACCESS_TOKEN: "{{env.GITHUB_TOKEN}}"
931
+ GITHUB_PERSONAL_ACCESS_TOKEN: "{{ENV['GITHUB_TOKEN']}}"
822
932
  only:
823
933
  - search_repositories
824
934
  - get_issue
@@ -847,7 +957,7 @@ Connect to local processes implementing the MCP protocol:
847
957
  command: docker
848
958
  args: ["run", "-i", "--rm", "ghcr.io/example/mcp-server"]
849
959
  env:
850
- API_KEY: "{{env.API_KEY}}"
960
+ API_KEY: "{{ENV['API_KEY']}}"
851
961
  ```
852
962
 
853
963
  See the [MCP tools example](examples/mcp/) for complete documentation and more examples.
data/bin/roast CHANGED
@@ -8,7 +8,7 @@
8
8
  # this file is here to facilitate running it.
9
9
  #
10
10
 
11
- ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../.ruby-lsp/Gemfile", __dir__)
11
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
12
12
 
13
13
  bundle_binstub = File.expand_path("bundle", __dir__)
14
14