roast-ai 0.1.0 → 0.1.2

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 (56) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/cla.yml +1 -1
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +28 -0
  5. data/CLAUDE.md +3 -1
  6. data/Gemfile +0 -1
  7. data/Gemfile.lock +3 -4
  8. data/README.md +419 -5
  9. data/Rakefile +1 -6
  10. data/docs/INSTRUMENTATION.md +202 -0
  11. data/examples/api_workflow/README.md +85 -0
  12. data/examples/api_workflow/fetch_api_data/prompt.md +10 -0
  13. data/examples/api_workflow/generate_report/prompt.md +10 -0
  14. data/examples/api_workflow/prompt.md +10 -0
  15. data/examples/api_workflow/transform_data/prompt.md +10 -0
  16. data/examples/api_workflow/workflow.yml +30 -0
  17. data/examples/grading/format_result.rb +25 -9
  18. data/examples/grading/js_test_runner +31 -0
  19. data/examples/grading/rb_test_runner +19 -0
  20. data/examples/grading/read_dependencies/prompt.md +14 -0
  21. data/examples/grading/run_coverage.rb +2 -2
  22. data/examples/grading/workflow.yml +3 -12
  23. data/examples/instrumentation.rb +76 -0
  24. data/examples/rspec_to_minitest/README.md +68 -0
  25. data/examples/rspec_to_minitest/analyze_spec/prompt.md +30 -0
  26. data/examples/rspec_to_minitest/create_minitest/prompt.md +33 -0
  27. data/examples/rspec_to_minitest/run_and_improve/prompt.md +35 -0
  28. data/examples/rspec_to_minitest/workflow.md +10 -0
  29. data/examples/rspec_to_minitest/workflow.yml +40 -0
  30. data/lib/roast/helpers/function_caching_interceptor.rb +72 -8
  31. data/lib/roast/helpers/prompt_loader.rb +2 -0
  32. data/lib/roast/resources/api_resource.rb +137 -0
  33. data/lib/roast/resources/base_resource.rb +47 -0
  34. data/lib/roast/resources/directory_resource.rb +40 -0
  35. data/lib/roast/resources/file_resource.rb +33 -0
  36. data/lib/roast/resources/none_resource.rb +29 -0
  37. data/lib/roast/resources/url_resource.rb +63 -0
  38. data/lib/roast/resources.rb +100 -0
  39. data/lib/roast/tools/coding_agent.rb +69 -0
  40. data/lib/roast/tools.rb +1 -0
  41. data/lib/roast/version.rb +1 -1
  42. data/lib/roast/workflow/base_step.rb +21 -17
  43. data/lib/roast/workflow/base_workflow.rb +69 -17
  44. data/lib/roast/workflow/configuration.rb +83 -8
  45. data/lib/roast/workflow/configuration_parser.rb +218 -3
  46. data/lib/roast/workflow/file_state_repository.rb +156 -0
  47. data/lib/roast/workflow/prompt_step.rb +16 -0
  48. data/lib/roast/workflow/session_manager.rb +82 -0
  49. data/lib/roast/workflow/state_repository.rb +21 -0
  50. data/lib/roast/workflow/workflow_executor.rb +99 -9
  51. data/lib/roast/workflow.rb +4 -0
  52. data/lib/roast.rb +2 -5
  53. data/roast.gemspec +1 -1
  54. data/schema/workflow.json +12 -0
  55. metadata +34 -6
  56. data/.rspec +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d4f229785a3a00ff70e98323c5edc14f0722c113993de498136054eb7716b7aa
4
- data.tar.gz: 5ec6dbc6d4d44d7cda7d451d0226b7eb7730942193d452fdd41c67c222d0c952
3
+ metadata.gz: 303226cd96dea4eb1edad783b8dd44c6457bc7ee5f639e31819800a0c5927aec
4
+ data.tar.gz: b00fa9b11708139368b0902a9992fb044397002b30323ac0aa19d8d47ada1e8c
5
5
  SHA512:
6
- metadata.gz: cd9c770a184b0a93b16ddccec14100eb922d0432c15513497c0dccab9223b473054198c2af5b169d251b9fcb72aad3665c0339799ad72aa7054eeb03a3a1acec
7
- data.tar.gz: 3414b3447e3636b80f224d5560b90981acfc018ab702ad0c4a152bfe203db79d070263d4a34ecca787a21a651f0ecc6715ed4ac3eef961f2fb825b56ebb3ae70
6
+ metadata.gz: e109b56b0c3ae1c192e2e427be837c37e20ec445021fbebe3cd84570b65acbc031d1c875c9ab38be9f01a62a1e64cabcef04e8eade793dbf28994b5147f5b0cd
7
+ data.tar.gz: 8f51781fdb486a77b4e03daee346e7efd6e932e57a0c2f803a73dded9d3fc3941b27653da1b3b05664eb7b8d47169e238b5c4a32d9b64fb69ee7f278715ab1b4
@@ -14,7 +14,7 @@ jobs:
14
14
  && !github.event.issue.pull_request.merged_at
15
15
  && contains(github.event.comment.body, 'signed')
16
16
  )
17
- || (github.event.pull_request && !github.event.pull_request.merged)
17
+ || (github.event.pull_request && !github.event.pull_request.merged)
18
18
  steps:
19
19
  - uses: Shopify/shopify-cla-action@v1
20
20
  with:
data/.gitignore CHANGED
@@ -11,3 +11,4 @@
11
11
  **/.claude/settings.local.json
12
12
 
13
13
  **/CLAUDE.local.md
14
+ .roast/
data/CHANGELOG.md CHANGED
@@ -0,0 +1,28 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.2] - 2024-05-09
9
+
10
+ ### Fixed
11
+ - problem with step loading using `--replay` option
12
+ - made access to `workflow.output` more robust by using hash with indifferent access
13
+
14
+ [0.1.2]: https://github.com/Shopify/roast/releases/tag/v0.1.2
15
+
16
+ ## [0.1.1] - 2024-05-09
17
+
18
+ ### Added
19
+ - Initial public release of Roast, extracted from Shopify's internal AI orchestration tools
20
+ - Core workflow execution engine for structured AI interactions
21
+ - Step-based workflow definition system
22
+ - Instrumentation hooks for monitoring and debugging
23
+ - Integration with various LLM providers (via [Raix](https://github.com/OlympiaAI/raix))
24
+ - Schema validation for workflow inputs and outputs
25
+ - Command-line interface for running workflows
26
+ - Comprehensive documentation and examples
27
+
28
+ [0.1.1]: https://github.com/Shopify/roast/releases/tag/v0.1.1
data/CLAUDE.md CHANGED
@@ -12,6 +12,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
12
12
  - Run single test: `bundle exec rspec spec/path/to/test_file.rb`
13
13
  - Lint: `bundle exec rubocop -A`
14
14
  - Default (tests + lint): `bundle exec rake`
15
+ - Run all tests plus rubocop: `bundle exec rake`
15
16
 
16
17
  ## Tech stack
17
18
  - `cli-kit` and `cli-ui` for the CLI tool
@@ -28,4 +29,5 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
28
29
  - Dependencies: Prefer existing gems in the Gemfile before adding new ones
29
30
  - Define class methods inside `class << self; end` declarations.
30
31
  - Add runtime dependencies to `roast.gemspec`.
31
- - Add development dependencies to `Gemfile`.
32
+ - Add development dependencies to `Gemfile`.
33
+ - Don't ever test private methods directly. Specs should test behavior, not implementation.
data/Gemfile CHANGED
@@ -13,7 +13,6 @@ gem "guard"
13
13
  gem "mocha"
14
14
  gem "pry"
15
15
  gem "rake", require: false
16
- gem "rspec", require: false
17
16
  gem "rubocop-shopify", require: false
18
17
  gem "vcr", require: false
19
18
  gem "webmock", require: false
data/Gemfile.lock CHANGED
@@ -1,11 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- roast-ai (0.1.0)
4
+ roast-ai (0.1.2)
5
5
  activesupport (~> 8.0)
6
6
  faraday-retry
7
7
  json-schema
8
- raix (= 0.8.3)
8
+ raix (~> 0.8.4)
9
9
  thor (~> 1.3)
10
10
 
11
11
  GEM
@@ -111,7 +111,7 @@ GEM
111
111
  public_suffix (6.0.1)
112
112
  racc (1.8.1)
113
113
  rainbow (3.1.1)
114
- raix (0.8.3)
114
+ raix (0.8.4)
115
115
  activesupport (>= 6.0)
116
116
  faraday-retry (~> 2.0)
117
117
  open_router (~> 0.2)
@@ -185,7 +185,6 @@ DEPENDENCIES
185
185
  pry
186
186
  rake
187
187
  roast-ai!
188
- rspec
189
188
  rubocop-shopify
190
189
  vcr
191
190
  webmock
data/README.md CHANGED
@@ -1,23 +1,437 @@
1
- ![image](https://github.com/user-attachments/assets/39589441-d15a-452b-b51c-3bf28f470308)
1
+ ![roast-horiz-logo](https://github.com/user-attachments/assets/f9b1ace2-5478-4f4a-ac8e-5945ed75c5b4)
2
2
 
3
3
  # Roast
4
4
 
5
5
  A convention-oriented framework for creating structured AI workflows, maintained by the Augmented Engineering team at Shopify.
6
6
 
7
7
  ## Why you should use Roast
8
- TBD
8
+
9
+ Roast provides a structured, declarative approach to building AI workflows with:
10
+
11
+ - **Convention over configuration**: Define powerful workflows using simple YAML configuration files and prompts written in markdown (with ERB support)
12
+ - **Built-in tools**: Ready-to-use tools for file operations, search, and AI interactions
13
+ - **Ruby integration**: When prompts aren't enough, write custom steps in Ruby using a clean, extensible architecture
14
+ - **Shared context**: Each step shares its conversation transcript with its parent workflow by default
15
+ - **Step customization**: Steps can be fully configured with their own AI models and parameters.
16
+ - **Session replay**: Rerun previous sessions starting at a specified step to speed up development time
17
+ - **Parallel execution**: Run multiple steps concurrently to speed up workflow execution
18
+ - **Function caching:**: Flexibly cache the results of tool function calls to speed up workflows
19
+ - **Extensive instrumentation**: Monitor and track workflow execution, AI calls, and tool usage ([see instrumentation documentation](docs/INSTRUMENTATION.md))
9
20
 
10
21
  ## What does it look like?
11
- TBD
22
+
23
+ Here's a simple workflow that analyzes test files:
24
+
25
+ ```yaml
26
+ name: analyze_tests
27
+ # Default model for all steps
28
+ model: gpt-4o-mini
29
+ tools:
30
+ - Roast::Tools::ReadFile
31
+ - Roast::Tools::Grep
32
+
33
+ steps:
34
+ - read_test_file
35
+ - analyze_coverage
36
+ - generate_report
37
+
38
+ # Step-specific model overrides the global model
39
+ analyze_coverage:
40
+ model: gpt-4-turbo
41
+ json: true
42
+ ```
43
+
44
+ Each step can have its own prompt file (e.g., `analyze_coverage/prompt.md`) and configuration. Steps can be run in parallel by nesting them in arrays:
45
+
46
+ ```yaml
47
+ steps:
48
+ - prepare_data
49
+ -
50
+ - analyze_code_quality
51
+ - check_test_coverage
52
+ - verify_documentation
53
+ - generate_final_report
54
+ ```
55
+
56
+ Workflows can include steps that run bash commands (wrap in `$()`) and even simple inlined prompts as a natural language string.
57
+
58
+ ```yaml
59
+ steps:
60
+ - analyze_spec
61
+ - create_minitest
62
+ - run_and_improve
63
+ - $(bundle exec rubocop -A)
64
+ - Summarize the changes made to the codebase.
65
+ ```
12
66
 
13
67
  ## How to use Roast
14
- TBD
15
68
 
16
- ## Installation
69
+ 1. Create a workflow YAML file defining your steps and tools
70
+ 2. Create prompt files for each step (e.g., `step_name/prompt.md`)
71
+ 3. Run the workflow:
72
+
73
+ ```bash
74
+ # With a target file
75
+ roast execute workflow.yml target_file.rb
76
+
77
+ # Or for a targetless workflow (API calls, data generation, etc.)
78
+ roast execute workflow.yml
79
+ ```
80
+
81
+ ### Understanding Workflows
82
+
83
+ In Roast, workflows maintain a single conversation with the AI model throughout execution. Each step represents one or more user-assistant interactions within this conversation, with optional tool calls. Steps naturally build upon each other through the shared context.
84
+
85
+ #### Step Types
86
+
87
+ Roast supports several types of steps:
88
+
89
+ 1. **Standard step**: References a directory containing at least a `prompt.md` and optional `output.txt` template. This is the most common type of step.
90
+ ```yaml
91
+ steps:
92
+ - analyze_code
93
+ ```
94
+
95
+ As an alternative to a directory, you can also implement a custom step as a Ruby class, optionally extending `Roast::Workflow::BaseStep`.
96
+
97
+ In the example given above, the script would live at `workflow/analyze_code.rb` and should contain a class named `AnalyzeCode` with an initializer that takes a workflow object as context, and a `call` method that will be invoked to run the step. The result of the `call` method will be stored in the `workflow.output` hash.
98
+
99
+
100
+ 2. **Parallel steps**: Groups of steps executed concurrently
101
+ ```yaml
102
+ steps:
103
+ -
104
+ - analyze_code_quality
105
+ - check_test_coverage
106
+ ```
107
+
108
+ 3. **Command execution step**: Executes shell commands directly, just wrap in `$(expr)`
109
+ ```yaml
110
+ steps:
111
+ - $(command line expr)
112
+ - rubocop: $(bundle exec rubocop -A)
113
+ ```
114
+ This will execute the command and store the result in the workflow output hash. Explicit key name is optional (`rubocop` in the second line of the example).
115
+
116
+ 4. **Raw prompt step**: Simple text prompts for the model without tools
117
+ ```yaml
118
+ steps:
119
+ - Summarize the changes made to the codebase.
120
+ ```
121
+ 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.
122
+
123
+ #### Data Flow Between Steps
124
+
125
+ Roast handles data flow between steps in two primary ways:
126
+
127
+ 1. **Conversation Context (Implicit)**: The LLM naturally remembers the entire conversation history, including all previous prompts and responses. In most cases, this is all you need for a step to reference and build upon previous results. This is the preferred approach for most prompt-oriented workflows.
128
+
129
+ 2. **Output Hash (Explicit)**: Each step's result is automatically stored in the `workflow.output` hash using the step name as the key. This programmatic access is mainly useful when:
130
+ - You need to perform non-LLM transformations on data
131
+ - You're writing custom output logic
132
+ - You need to access specific values for presentation or logging
133
+
134
+ For typical AI workflows, the continuous conversation history provides seamless data flow without requiring explicit access to the output hash. Steps can simply refer to previous information in their prompts, and the AI model will use its memory of the conversation to provide context-aware responses.
135
+
136
+ ### Command Line Options
137
+
138
+ #### Basic Options
139
+ - `-o, --output FILE`: Save results to a file instead of outputting to STDOUT
140
+ - `-c, --concise`: Use concise output templates (exposed as a boolean flag on `workflow`)
141
+ - `-v, --verbose`: Show output from all steps as they execute
142
+ - `-r, --replay STEP_NAME`: Resume a workflow from a specific step, optionally with a specific session timestamp
143
+
144
+ #### Session Replay
145
+
146
+ The session replay feature allows you to resume workflows from specific steps, saving time during development and debugging:
147
+
148
+ ```bash
149
+ # Resume from a specific step
150
+ roast execute workflow.yml -r step_name
151
+
152
+ # Resume from a specific step in a specific session
153
+ roast execute workflow.yml -r 20250507_123456_789:step_name
154
+ ```
155
+
156
+ Sessions are automatically saved during workflow execution. Each step's state, including the conversation transcript and output, is persisted to a session directory. The session directories are organized by workflow name and file, with timestamps for each run.
157
+
158
+ This feature is particularly useful when:
159
+ - Debugging specific steps in a long workflow
160
+ - Iterating on prompts without rerunning the entire workflow
161
+ - Resuming after failures in long-running workflows
162
+
163
+ Sessions are stored in the `.roast/sessions/` directory in your project. Note that there is no automatic cleanup of session data, so you might want to periodically delete old sessions yourself.
164
+
165
+ #### Target Option (`-t, --target`)
166
+
167
+ The target option is highly flexible and accepts several formats:
168
+
169
+ **Single file path:**
170
+ ```bash
171
+ roast execute workflow.yml -t path/to/file.rb
172
+
173
+ # is equivalent to
174
+ roast execute workflow.yml path/to/file.rb
175
+ ```
176
+
177
+ **Directory path:**
178
+ ```bash
179
+ roast execute workflow.yml -t path/to/directory
180
+
181
+ # Roast will run on the directory as a resource
182
+ ```
183
+
184
+ **Glob patterns:**
185
+ ```bash
186
+ roast execute workflow.yml -t "**/*_test.rb"
187
+
188
+ # Roast will run the workflow on each matching file
189
+ ```
190
+
191
+ **URL as target:**
192
+ ```bash
193
+ roast execute workflow.yml -t "https://api.example.com/data"
194
+
195
+ # Roast will run the workflow using the URL as a resource
196
+ ```
197
+
198
+ **API configuration (Fetch API-style):**
199
+ ```bash
200
+ roast execute workflow.yml -t '{
201
+ "url": "https://api.example.com/resource",
202
+ "options": {
203
+ "method": "POST",
204
+ "headers": {
205
+ "Content-Type": "application/json",
206
+ "Authorization": "Bearer ${API_TOKEN}"
207
+ },
208
+ "body": {
209
+ "query": "search term",
210
+ "limit": 10
211
+ }
212
+ }
213
+ }'
214
+
215
+ # Roast will recognize this as an API configuration with Fetch API-style format
216
+ ```
217
+
218
+ **Shell command execution with $(...):**
219
+ ```bash
220
+ roast execute workflow.yml -t "$(find . -name '*.rb' -mtime -1)"
221
+
222
+ # Roast will run the workflow on each file returned (expects one per line)
223
+ ```
224
+
225
+ **Git integration examples:**
226
+ ```bash
227
+ # Process changed test files
228
+ roast execute workflow.yml -t "$(git diff --name-only HEAD | grep _test.rb)"
229
+
230
+ # Process staged files
231
+ roast execute workflow.yml -t "$(git diff --cached --name-only)"
232
+ ```
233
+
234
+ #### Targetless Workflows
235
+
236
+ Roast also supports workflows that don't operate on a specific pre-defined set of target files:
237
+
238
+ **API-driven workflows:**
239
+ ```yaml
240
+ name: API Integration Workflow
241
+ tools:
242
+ - Roast::Tools::ReadFile
243
+ - Roast::Tools::WriteFile
244
+
245
+ # Dynamic API token using shell command
246
+ api_token: $(cat ~/.my_token)
247
+
248
+ # Option 1: Use a targetless workflow with API logic in steps
249
+ steps:
250
+ - fetch_api_data # Step will make API calls
251
+ - transform_data
252
+ - generate_report
253
+
254
+ # Option 2: Specify an API target directly in the workflow
255
+ target: '{
256
+ "url": "https://api.example.com/resource",
257
+ "options": {
258
+ "method": "GET",
259
+ "headers": {
260
+ "Authorization": "Bearer ${API_TOKEN}"
261
+ }
262
+ }
263
+ }'
264
+
265
+ steps:
266
+ - process_api_response
267
+ - generate_report
268
+ ```
269
+
270
+ **Data generation workflows:**
271
+ ```yaml
272
+ name: Generate Documentation
273
+ tools:
274
+ - Roast::Tools::WriteFile
275
+ steps:
276
+ - generate_outline
277
+ - write_documentation
278
+ - create_examples
279
+ ```
280
+
281
+ These targetless workflows are ideal for:
282
+ - API integrations
283
+ - Content generation
284
+ - Report creation
285
+ - Interactive tools
286
+ - Scheduled automation tasks
287
+
288
+ #### Global Model Configuration
289
+
290
+ You can set a default model for all steps in your workflow by specifying the `model` parameter at the top level:
291
+
292
+ ```yaml
293
+ name: My Workflow
294
+ model: gpt-4o-mini # Will be used for all steps unless overridden
295
+ ```
296
+
297
+ Individual steps can override this setting with their own model parameter:
298
+
299
+ ```yaml
300
+ analyze_data:
301
+ model: anthropic:claude-3-haiku # Takes precedence over the global model
302
+ ```
303
+
304
+ #### Dynamic API Tokens
305
+
306
+ Roast allows you to dynamically fetch API tokens using shell commands directly in your workflow configuration:
307
+
308
+ ```yaml
309
+ # This will execute the shell command and use the result as the API token
310
+ api_token: $(print-token --key)
311
+
312
+ # Or a simpler example for demonstration:
313
+ api_token: $(echo $OPENAI_API_KEY)
314
+ ```
315
+
316
+ This makes it easy to use environment-specific tokens without hardcoding credentials, especially useful in development environments or CI/CD pipelines.
317
+
318
+ ### Template Output with ERB
319
+
320
+ Each step can have an `output.txt` file that uses ERB templating to format the final output. This allows you to customize how the AI's response is processed and displayed.
321
+
322
+ Example `step_name/output.txt`:
323
+ ```erb
324
+ <% if workflow.verbose %>
325
+ Detailed Analysis:
326
+ <%= response %>
327
+ <% else %>
328
+ Summary: <%= response.lines.first %>
329
+ <% end %>
330
+
331
+ Files analyzed: <%= workflow.file %>
332
+ Status: <%= workflow.output['status'] || 'completed' %>
333
+ ```
334
+
335
+ This is an example of where the `workflow.output` hash is useful - formatting output for display based on data from previous steps.
336
+
337
+ Available in templates:
338
+ - `response`: The AI's response for this step
339
+ - `workflow`: Access to the workflow object
340
+ - `workflow.output`: The shared hash containing results from all steps when you need programmatic access
341
+ - `workflow.file`: Current file being processed (or `nil` for targetless workflows)
342
+ - All workflow configuration options
343
+
344
+ For most workflows, you'll mainly use `response` to access the current step's results. The `workflow.output` hash becomes valuable when you need to reference specific data points from previous steps in your templates or for conditional display logic.
345
+
346
+ ## Advanced Features
347
+
348
+ ### Instrumentation
349
+
350
+ Roast provides extensive instrumentation capabilities using ActiveSupport::Notifications. You can monitor workflow execution, track AI model usage, measure performance, and integrate with external monitoring systems. [Read the full instrumentation documentation](docs/INSTRUMENTATION.md).
351
+
352
+ ### Custom Tools
353
+
354
+ You can create your own tools using the [Raix function dispatch pattern](https://github.com/OlympiaAI/raix-rails?tab=readme-ov-file#use-of-toolsfunctions). Custom tools should be placed in `.roast/initializers/` (subdirectories are supported):
355
+
356
+ ```ruby
357
+ # .roast/initializers/tools/git_analyzer.rb
358
+ module MyProject
359
+ module Tools
360
+ module GitAnalyzer
361
+ extend self
362
+
363
+ def self.included(base)
364
+ base.class_eval do
365
+ function(
366
+ :analyze_commit,
367
+ "Analyze a git commit for code quality and changes",
368
+ commit_sha: { type: "string", description: "The SHA of the commit to analyze" },
369
+ include_diff: { type: "boolean", description: "Include the full diff in the analysis", default: false }
370
+ ) do |params|
371
+ GitAnalyzer.call(params[:commit_sha], params[:include_diff])
372
+ end
373
+ end
374
+ end
375
+
376
+ def call(commit_sha, include_diff = false)
377
+ Roast::Helpers::Logger.info("🔍 Analyzing commit: #{commit_sha}\n")
378
+
379
+ # Your implementation here
380
+ commit_info = `git show #{commit_sha} --stat`
381
+ commit_info += "\n\n" + `git show #{commit_sha}` if include_diff
382
+
383
+ commit_info
384
+ rescue StandardError => e
385
+ "Error analyzing commit: #{e.message}".tap do |error_message|
386
+ Roast::Helpers::Logger.error(error_message + "\n")
387
+ end
388
+ end
389
+ end
390
+ end
391
+ end
392
+ ```
393
+
394
+ Then include your tool in the workflow:
395
+
396
+ ```yaml
397
+ tools:
398
+ - MyProject::Tools::GitAnalyzer
399
+ ```
400
+
401
+ The tool will be available to the AI model during workflow execution, and it can call `analyze_commit` with the appropriate parameters.
402
+
403
+ ### Project-specific Configuration
404
+
405
+ You can extend Roast with project-specific configuration by creating initializers in `.roast/initializers/`. These are automatically loaded when workflows run, allowing you to:
406
+
407
+ - Add custom instrumentation
408
+ - Configure monitoring and metrics
409
+ - Set up project-specific tools
410
+ - Customize workflow behavior
411
+
412
+ Example structure:
17
413
  ```
414
+ your-project/
415
+ ├── .roast/
416
+ │ └── initializers/
417
+ │ ├── metrics.rb
418
+ │ ├── logging.rb
419
+ │ └── custom_tools.rb
420
+ └── ...
421
+ ```
422
+
423
+ ## Installation
424
+
425
+ ```bash
18
426
  $ gem install roast
19
427
  ```
20
428
 
429
+ Or add to your Gemfile:
430
+
431
+ ```ruby
432
+ gem 'roast'
433
+ ```
434
+
21
435
  ## Development
22
436
 
23
437
  After checking out the repo, run `bundle install` to install dependencies. Then, run `bundle exec rake` to run the tests and linter. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/Rakefile CHANGED
@@ -1,21 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
5
4
  require "rubocop/rake_task"
6
5
  require "rake/testtask"
7
6
 
8
- RSpec::Core::RakeTask.new(:spec) do |t|
9
- t.pattern = "spec/**/*_spec.rb"
10
- end
11
-
12
7
  Rake::TestTask.new(:minitest) do |t|
13
8
  t.libs << "test"
14
9
  t.libs << "lib"
15
10
  t.test_files = FileList["test/**/*_test.rb"]
16
11
  end
17
12
 
18
- task test: [:spec, :minitest]
13
+ task test: [:minitest]
19
14
 
20
15
  RuboCop::RakeTask.new do |task|
21
16
  task.options = ["--autocorrect"]