roast-ai 0.4.3 → 0.4.5
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.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +2 -0
- data/.github/workflows/ci.yaml +1 -0
- data/.gitignore +0 -26
- data/.rubocop.yml +13 -0
- data/.rubocop_todo.yml +21 -0
- data/CHANGELOG.md +29 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +47 -29
- data/bin/rubocop +27 -0
- data/bin/spoom +27 -0
- data/bin/srb +27 -0
- data/bin/srb-rbi +27 -0
- data/bin/tapioca +27 -0
- data/docs/INSTRUMENTATION.md +3 -3
- data/dsl/simple.rb +10 -0
- data/lib/roast/dsl/executor.rb +26 -0
- data/lib/roast/dsl.rb +7 -0
- data/lib/roast/errors.rb +1 -0
- data/lib/roast/factories/api_provider_factory.rb +1 -0
- data/lib/roast/helpers/function_caching_interceptor.rb +3 -0
- data/lib/roast/helpers/logger.rb +6 -9
- data/lib/roast/helpers/metadata_access.rb +1 -0
- data/lib/roast/helpers/minitest_coverage_runner.rb +1 -0
- data/lib/roast/helpers/path_resolver.rb +8 -18
- data/lib/roast/helpers/prompt_loader.rb +3 -2
- data/lib/roast/helpers/timeout_handler.rb +3 -5
- data/lib/roast/initializers.rb +1 -0
- data/lib/roast/resources/api_resource.rb +4 -3
- data/lib/roast/resources/base_resource.rb +1 -0
- data/lib/roast/resources/directory_resource.rb +1 -0
- data/lib/roast/resources/file_resource.rb +1 -0
- data/lib/roast/resources/none_resource.rb +1 -0
- data/lib/roast/resources/url_resource.rb +2 -1
- data/lib/roast/resources.rb +1 -2
- data/lib/roast/services/context_threshold_checker.rb +1 -0
- data/lib/roast/services/token_counting_service.rb +1 -0
- data/lib/roast/tools/apply_diff.rb +1 -0
- data/lib/roast/tools/ask_user.rb +1 -0
- data/lib/roast/tools/bash.rb +1 -0
- data/lib/roast/tools/cmd.rb +1 -0
- data/lib/roast/tools/coding_agent.rb +1 -0
- data/lib/roast/tools/context_summarizer.rb +1 -0
- data/lib/roast/tools/grep.rb +1 -0
- data/lib/roast/tools/helpers/coding_agent_message_formatter.rb +1 -0
- data/lib/roast/tools/read_file.rb +1 -0
- data/lib/roast/tools/search_file.rb +1 -0
- data/lib/roast/tools/swarm.rb +1 -0
- data/lib/roast/tools/update_files.rb +1 -0
- data/lib/roast/tools/write_file.rb +1 -0
- data/lib/roast/tools.rb +2 -0
- data/lib/roast/value_objects/api_token.rb +1 -0
- data/lib/roast/value_objects/step_name.rb +1 -0
- data/lib/roast/value_objects/uri_base.rb +1 -0
- data/lib/roast/value_objects/workflow_path.rb +1 -0
- data/lib/roast/value_objects.rb +1 -0
- data/lib/roast/version.rb +2 -1
- data/lib/roast/workflow/agent_step.rb +1 -0
- data/lib/roast/workflow/api_configuration.rb +1 -0
- data/lib/roast/workflow/base_iteration_step.rb +1 -0
- data/lib/roast/workflow/base_step.rb +1 -0
- data/lib/roast/workflow/base_workflow.rb +1 -0
- data/lib/roast/workflow/case_executor.rb +1 -0
- data/lib/roast/workflow/case_step.rb +1 -0
- data/lib/roast/workflow/command_executor.rb +1 -0
- data/lib/roast/workflow/conditional_executor.rb +1 -0
- data/lib/roast/workflow/conditional_step.rb +1 -0
- data/lib/roast/workflow/configuration.rb +9 -0
- data/lib/roast/workflow/configuration_loader.rb +4 -1
- data/lib/roast/workflow/context_manager.rb +1 -0
- data/lib/roast/workflow/context_path_resolver.rb +1 -0
- data/lib/roast/workflow/dot_access_hash.rb +1 -0
- data/lib/roast/workflow/each_step.rb +1 -0
- data/lib/roast/workflow/error_handler.rb +7 -1
- data/lib/roast/workflow/expression_evaluator.rb +1 -0
- data/lib/roast/workflow/expression_utils.rb +1 -0
- data/lib/roast/workflow/file_state_repository.rb +2 -1
- data/lib/roast/workflow/input_executor.rb +1 -0
- data/lib/roast/workflow/input_step.rb +1 -0
- data/lib/roast/workflow/interpolator.rb +2 -1
- data/lib/roast/workflow/iteration_executor.rb +1 -0
- data/lib/roast/workflow/llm_boolean_coercer.rb +1 -0
- data/lib/roast/workflow/metadata_manager.rb +1 -0
- data/lib/roast/workflow/output_handler.rb +1 -0
- data/lib/roast/workflow/output_manager.rb +1 -0
- data/lib/roast/workflow/parallel_executor.rb +1 -0
- data/lib/roast/workflow/prompt_step.rb +1 -0
- data/lib/roast/workflow/repeat_step.rb +1 -0
- data/lib/roast/workflow/replay_handler.rb +1 -0
- data/lib/roast/workflow/resource_resolver.rb +2 -6
- data/lib/roast/workflow/session_manager.rb +1 -0
- data/lib/roast/workflow/shell_script_step.rb +1 -0
- data/lib/roast/workflow/sqlite_state_repository.rb +1 -0
- data/lib/roast/workflow/state_manager.rb +1 -0
- data/lib/roast/workflow/state_repository.rb +1 -0
- data/lib/roast/workflow/state_repository_factory.rb +4 -2
- data/lib/roast/workflow/step_completion_reporter.rb +1 -0
- data/lib/roast/workflow/step_executor_coordinator.rb +9 -5
- data/lib/roast/workflow/step_executor_factory.rb +1 -0
- data/lib/roast/workflow/step_executor_registry.rb +2 -3
- data/lib/roast/workflow/step_executor_with_reporting.rb +1 -0
- data/lib/roast/workflow/step_executors/base_step_executor.rb +1 -0
- data/lib/roast/workflow/step_executors/hash_step_executor.rb +1 -0
- data/lib/roast/workflow/step_executors/parallel_step_executor.rb +1 -0
- data/lib/roast/workflow/step_executors/string_step_executor.rb +1 -0
- data/lib/roast/workflow/step_factory.rb +1 -0
- data/lib/roast/workflow/step_finder.rb +1 -0
- data/lib/roast/workflow/step_loader.rb +1 -0
- data/lib/roast/workflow/step_name_extractor.rb +1 -0
- data/lib/roast/workflow/step_runner.rb +1 -0
- data/lib/roast/workflow/step_type_resolver.rb +1 -0
- data/lib/roast/workflow/validation_command.rb +1 -0
- data/lib/roast/workflow/validator.rb +1 -0
- data/lib/roast/workflow/validators/base_validator.rb +1 -0
- data/lib/roast/workflow/validators/dependency_validator.rb +1 -0
- data/lib/roast/workflow/validators/linting_validator.rb +1 -0
- data/lib/roast/workflow/validators/schema_validator.rb +1 -0
- data/lib/roast/workflow/validators/step_collector.rb +1 -0
- data/lib/roast/workflow/validators/validation_orchestrator.rb +1 -0
- data/lib/roast/workflow/workflow_context.rb +1 -0
- data/lib/roast/workflow/workflow_execution_context.rb +1 -0
- data/lib/roast/workflow/workflow_executor.rb +2 -1
- data/lib/roast/workflow/workflow_initializer.rb +1 -0
- data/lib/roast/workflow/workflow_runner.rb +66 -55
- data/lib/roast/workflow.rb +1 -0
- data/lib/roast/workflow_diagram_generator.rb +3 -2
- data/lib/roast.rb +23 -8
- data/roast.gemspec +1 -1
- data/sorbet/config +8 -0
- data/sorbet/rbi/dsl/.gitattributes +1 -0
- data/sorbet/rbi/dsl/active_support/callbacks.rbi +21 -0
- data/sorbet/rbi/gems/.gitattributes +1 -0
- data/sorbet/rbi/gems/activesupport@8.0.2.rbi +19107 -0
- data/sorbet/rbi/gems/addressable@2.8.7.rbi +1994 -0
- data/sorbet/rbi/gems/ast@2.4.3.rbi +585 -0
- data/sorbet/rbi/gems/base64@0.3.0.rbi +545 -0
- data/sorbet/rbi/gems/benchmark@0.4.1.rbi +619 -0
- data/sorbet/rbi/gems/bigdecimal@3.2.2.rbi +62 -0
- data/sorbet/rbi/gems/cgi@0.5.0.rbi +2961 -0
- data/sorbet/rbi/gems/claude_swarm@0.1.19.rbi +568 -0
- data/sorbet/rbi/gems/cli-kit@5.0.1.rbi +1991 -0
- data/sorbet/rbi/gems/cli-ui@2.3.0.rbi +3181 -0
- data/sorbet/rbi/gems/coderay@1.1.3.rbi +9 -0
- data/sorbet/rbi/gems/concurrent-ruby@1.3.5.rbi +11657 -0
- data/sorbet/rbi/gems/connection_pool@2.5.3.rbi +9 -0
- data/sorbet/rbi/gems/crack@1.0.0.rbi +145 -0
- data/sorbet/rbi/gems/diff-lcs@1.6.2.rbi +972 -0
- data/sorbet/rbi/gems/dotenv@3.1.8.rbi +295 -0
- data/sorbet/rbi/gems/drb@2.2.3.rbi +1661 -0
- data/sorbet/rbi/gems/dry-configurable@1.3.0.rbi +672 -0
- data/sorbet/rbi/gems/dry-core@1.1.0.rbi +1894 -0
- data/sorbet/rbi/gems/dry-inflector@1.2.0.rbi +659 -0
- data/sorbet/rbi/gems/dry-initializer@3.2.0.rbi +781 -0
- data/sorbet/rbi/gems/dry-logic@1.6.0.rbi +1127 -0
- data/sorbet/rbi/gems/dry-schema@1.14.1.rbi +3727 -0
- data/sorbet/rbi/gems/dry-types@1.8.3.rbi +3969 -0
- data/sorbet/rbi/gems/erubi@1.13.1.rbi +155 -0
- data/sorbet/rbi/gems/event_stream_parser@1.0.0.rbi +49 -0
- data/sorbet/rbi/gems/faraday-multipart@1.1.1.rbi +283 -0
- data/sorbet/rbi/gems/faraday-net_http@3.4.1.rbi +147 -0
- data/sorbet/rbi/gems/faraday-retry@2.3.2.rbi +9 -0
- data/sorbet/rbi/gems/faraday@2.13.1.rbi +2977 -0
- data/sorbet/rbi/gems/fast-mcp-annotations@1.5.3.rbi +1588 -0
- data/sorbet/rbi/gems/ffi@1.17.2.rbi +9 -0
- data/sorbet/rbi/gems/formatador@1.1.0.rbi +9 -0
- data/sorbet/rbi/gems/guard-compat@1.2.1.rbi +102 -0
- data/sorbet/rbi/gems/guard-minitest@2.4.6.rbi +402 -0
- data/sorbet/rbi/gems/guard@2.19.1.rbi +2283 -0
- data/sorbet/rbi/gems/hashdiff@1.2.0.rbi +355 -0
- data/sorbet/rbi/gems/i18n@1.14.7.rbi +2359 -0
- data/sorbet/rbi/gems/json-schema@5.1.1.rbi +1466 -0
- data/sorbet/rbi/gems/json@2.12.2.rbi +2051 -0
- data/sorbet/rbi/gems/language_server-protocol@3.17.0.5.rbi +9 -0
- data/sorbet/rbi/gems/lint_roller@1.1.0.rbi +9 -0
- data/sorbet/rbi/gems/listen@3.9.0.rbi +1206 -0
- data/sorbet/rbi/gems/logger@1.7.0.rbi +963 -0
- data/sorbet/rbi/gems/lumberjack@1.2.10.rbi +1830 -0
- data/sorbet/rbi/gems/method_source@1.1.0.rbi +9 -0
- data/sorbet/rbi/gems/mime-types-data@3.2025.0617.rbi +136 -0
- data/sorbet/rbi/gems/mime-types@3.7.0.rbi +1342 -0
- data/sorbet/rbi/gems/minitest-rg@5.3.0.rbi +160 -0
- data/sorbet/rbi/gems/minitest@5.25.5.rbi +1640 -0
- data/sorbet/rbi/gems/mocha@2.7.1.rbi +12 -0
- data/sorbet/rbi/gems/multipart-post@2.4.1.rbi +244 -0
- data/sorbet/rbi/gems/nenv@0.3.0.rbi +147 -0
- data/sorbet/rbi/gems/net-http@0.6.0.rbi +4247 -0
- data/sorbet/rbi/gems/netrc@0.11.0.rbi +159 -0
- data/sorbet/rbi/gems/notiffany@0.1.3.rbi +1079 -0
- data/sorbet/rbi/gems/open_router@0.3.3.rbi +230 -0
- data/sorbet/rbi/gems/ostruct@0.6.2.rbi +354 -0
- data/sorbet/rbi/gems/parallel@1.27.0.rbi +291 -0
- data/sorbet/rbi/gems/parser@3.3.8.0.rbi +5535 -0
- data/sorbet/rbi/gems/prism@1.4.0.rbi +41732 -0
- data/sorbet/rbi/gems/pry@0.15.2.rbi +9 -0
- data/sorbet/rbi/gems/public_suffix@6.0.2.rbi +936 -0
- data/sorbet/rbi/gems/racc@1.8.1.rbi +158 -0
- data/sorbet/rbi/gems/rack@2.2.17.rbi +5659 -0
- data/sorbet/rbi/gems/rainbow@3.1.1.rbi +9 -0
- data/sorbet/rbi/gems/raix@1.0.2.rbi +1104 -0
- data/sorbet/rbi/gems/rake@13.3.0.rbi +3036 -0
- data/sorbet/rbi/gems/rb-fsevent@0.11.2.rbi +9 -0
- data/sorbet/rbi/gems/rb-inotify@0.11.1.rbi +9 -0
- data/sorbet/rbi/gems/rbi@0.3.6.rbi +6893 -0
- data/sorbet/rbi/gems/rbs@3.9.4.rbi +6978 -0
- data/sorbet/rbi/gems/regexp_parser@2.10.0.rbi +9 -0
- data/sorbet/rbi/gems/rexml@3.4.1.rbi +5346 -0
- data/sorbet/rbi/gems/rubocop-ast@1.45.1.rbi +9 -0
- data/sorbet/rbi/gems/rubocop-shopify@2.17.1.rbi +9 -0
- data/sorbet/rbi/gems/rubocop@1.77.0.rbi +9 -0
- data/sorbet/rbi/gems/ruby-graphviz@1.2.5.rbi +1333 -0
- data/sorbet/rbi/gems/ruby-openai@8.1.0.rbi +758 -0
- data/sorbet/rbi/gems/ruby-progressbar@1.13.0.rbi +9 -0
- data/sorbet/rbi/gems/ruby2_keywords@0.0.5.rbi +9 -0
- data/sorbet/rbi/gems/securerandom@0.4.1.rbi +75 -0
- data/sorbet/rbi/gems/shellany@0.0.1.rbi +102 -0
- data/sorbet/rbi/gems/spoom@1.6.3.rbi +6985 -0
- data/sorbet/rbi/gems/sqlite3@2.7.0.rbi +1900 -0
- data/sorbet/rbi/gems/tapioca@0.16.11.rbi +3628 -0
- data/sorbet/rbi/gems/thor@1.4.0.rbi +4399 -0
- data/sorbet/rbi/gems/tzinfo@2.0.6.rbi +5918 -0
- data/sorbet/rbi/gems/unicode-display_width@3.1.4.rbi +9 -0
- data/sorbet/rbi/gems/unicode-emoji@4.0.4.rbi +9 -0
- data/sorbet/rbi/gems/uri@1.0.3.rbi +2349 -0
- data/sorbet/rbi/gems/vcr@6.3.1.rbi +3040 -0
- data/sorbet/rbi/gems/webmock@3.25.1.rbi +1792 -0
- data/sorbet/rbi/gems/yard-sorbet@0.9.0.rbi +435 -0
- data/sorbet/rbi/gems/yard@0.9.37.rbi +18492 -0
- data/sorbet/rbi/gems/zeitwerk@2.7.3.rbi +1429 -0
- data/sorbet/tapioca/config.yml +13 -0
- data/sorbet/tapioca/require.rb +36 -0
- metadata +116 -5
- data/lib/roast/workflow/configuration_parser.rb +0 -54
@@ -1,8 +1,6 @@
|
|
1
|
+
# typed: true
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require "timeout"
|
4
|
-
require "open3"
|
5
|
-
|
6
4
|
module Roast
|
7
5
|
module Helpers
|
8
6
|
# Shared timeout handling logic for command-based tools
|
@@ -29,8 +27,8 @@ module Roast
|
|
29
27
|
def call(command, timeout: DEFAULT_TIMEOUT, working_directory: Dir.pwd)
|
30
28
|
timeout = validate_timeout(timeout)
|
31
29
|
output = ""
|
32
|
-
exit_status = nil
|
33
|
-
wait_thr = nil
|
30
|
+
exit_status = nil #: Integer?
|
31
|
+
wait_thr = nil #: Process::Waiter?
|
34
32
|
|
35
33
|
begin
|
36
34
|
Timeout.timeout(timeout) do
|
data/lib/roast/initializers.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# typed: true
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Roast
|
@@ -57,7 +58,7 @@ module Roast
|
|
57
58
|
http.use_ssl = (uri.scheme == "https")
|
58
59
|
|
59
60
|
# Use HEAD request to check existence
|
60
|
-
request = Net::HTTP::Head.new(uri.path
|
61
|
+
request = Net::HTTP::Head.new(uri.path&.empty? ? "/" : uri.path)
|
61
62
|
|
62
63
|
# Add headers if present in options
|
63
64
|
if options["headers"].is_a?(Hash)
|
@@ -124,8 +125,8 @@ module Roast
|
|
124
125
|
# Replace environment variables in the format ${VAR_NAME}
|
125
126
|
def process_env_vars(text)
|
126
127
|
text.gsub(/\${([^}]+)}/) do |_match|
|
127
|
-
var_name = ::Regexp.last_match(1)
|
128
|
-
ENV.fetch(var_name, "${#{var_name}}")
|
128
|
+
var_name = ::Regexp.last_match(1)&.strip
|
129
|
+
ENV.fetch(var_name, "${#{var_name}}") unless var_name.nil?
|
129
130
|
end
|
130
131
|
end
|
131
132
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# typed: true
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Roast
|
@@ -18,7 +19,7 @@ module Roast
|
|
18
19
|
http.use_ssl = (uri.scheme == "https")
|
19
20
|
|
20
21
|
# Just check the head to see if the resource exists
|
21
|
-
response = http.request_head(uri.path
|
22
|
+
response = http.request_head(uri.path&.empty? ? "/" : uri.path)
|
22
23
|
|
23
24
|
# Consider 2xx and 3xx as success
|
24
25
|
response.code.to_i < 400
|
data/lib/roast/resources.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# typed: true
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Roast
|
@@ -21,8 +22,6 @@ module Roast
|
|
21
22
|
UrlResource.new(target)
|
22
23
|
when :api
|
23
24
|
ApiResource.new(target)
|
24
|
-
when :command
|
25
|
-
CommandResource.new(target)
|
26
25
|
when :none
|
27
26
|
NoneResource.new(target)
|
28
27
|
else
|
data/lib/roast/tools/ask_user.rb
CHANGED
data/lib/roast/tools/bash.rb
CHANGED
data/lib/roast/tools/cmd.rb
CHANGED
data/lib/roast/tools/grep.rb
CHANGED
data/lib/roast/tools/swarm.rb
CHANGED
data/lib/roast/tools.rb
CHANGED
data/lib/roast/value_objects.rb
CHANGED
data/lib/roast/version.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# typed: true
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Roast
|
@@ -87,6 +88,14 @@ module Roast
|
|
87
88
|
@tool_configs[tool_name.to_s] || {}
|
88
89
|
end
|
89
90
|
|
91
|
+
def pre_processing?
|
92
|
+
pre_processing.any?
|
93
|
+
end
|
94
|
+
|
95
|
+
def post_processing?
|
96
|
+
post_processing.any?
|
97
|
+
end
|
98
|
+
|
90
99
|
private
|
91
100
|
|
92
101
|
attr_reader :api_configuration
|
@@ -1,9 +1,12 @@
|
|
1
|
+
# typed: true
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Roast
|
4
5
|
module Workflow
|
5
6
|
# Handles loading and parsing of workflow configuration files
|
6
7
|
class ConfigurationLoader
|
8
|
+
class ValidationError < StandardError; end
|
9
|
+
|
7
10
|
class << self
|
8
11
|
# Load configuration from a YAML file
|
9
12
|
# @param workflow_path [String] Path to the workflow YAML file
|
@@ -187,7 +190,7 @@ module Roast
|
|
187
190
|
message
|
188
191
|
end.join("\n")
|
189
192
|
|
190
|
-
raise
|
193
|
+
raise ValidationError, <<~ERROR
|
191
194
|
Workflow validation failed with #{validator.errors.size} error(s):
|
192
195
|
|
193
196
|
#{error_messages}
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# typed: true
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Roast
|
4
5
|
module Workflow
|
5
6
|
# Handles error logging and instrumentation for workflow execution
|
6
7
|
class ErrorHandler
|
7
|
-
def initialize
|
8
|
+
def initialize(workflow = nil)
|
9
|
+
@workflow = workflow
|
8
10
|
# Use the Roast logger singleton
|
9
11
|
end
|
10
12
|
|
@@ -14,6 +16,7 @@ module Roast
|
|
14
16
|
ActiveSupport::Notifications.instrument("roast.step.start", {
|
15
17
|
step_name: step_name,
|
16
18
|
resource_type: resource_type,
|
19
|
+
workflow_name: @workflow&.name,
|
17
20
|
})
|
18
21
|
|
19
22
|
result = yield
|
@@ -23,6 +26,7 @@ module Roast
|
|
23
26
|
ActiveSupport::Notifications.instrument("roast.step.complete", {
|
24
27
|
step_name: step_name,
|
25
28
|
resource_type: resource_type,
|
29
|
+
workflow_name: @workflow&.name,
|
26
30
|
success: true,
|
27
31
|
execution_time: execution_time,
|
28
32
|
result_size: result.to_s.length,
|
@@ -64,6 +68,7 @@ module Roast
|
|
64
68
|
ActiveSupport::Notifications.instrument("roast.step.error", {
|
65
69
|
step_name: step_name,
|
66
70
|
resource_type: resource_type,
|
71
|
+
workflow_name: @workflow&.name,
|
67
72
|
error: error.class.name,
|
68
73
|
message: error.message,
|
69
74
|
execution_time: execution_time,
|
@@ -76,6 +81,7 @@ module Roast
|
|
76
81
|
ActiveSupport::Notifications.instrument("roast.step.error", {
|
77
82
|
step_name: step_name,
|
78
83
|
resource_type: resource_type,
|
84
|
+
workflow_name: @workflow&.name,
|
79
85
|
error: error.class.name,
|
80
86
|
message: error.message,
|
81
87
|
execution_time: execution_time,
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# typed: true
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Roast
|
@@ -53,7 +54,7 @@ module Roast
|
|
53
54
|
state_data = load_state_file(state_file)
|
54
55
|
|
55
56
|
# Extract the loaded step name for diagnostics
|
56
|
-
loaded_step = File.basename(state_file).split("_", 3)[2].sub(/\.json$/, "")
|
57
|
+
loaded_step = File.basename(state_file).split("_", 3)[2].to_s.sub(/\.json$/, "")
|
57
58
|
$stderr.puts "Found state from step: #{loaded_step} (will replay from here to #{step_name})"
|
58
59
|
|
59
60
|
# If no timestamp provided and workflow has no session, copy states to new session
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# typed: true
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Roast
|
@@ -16,7 +17,7 @@ module Roast
|
|
16
17
|
|
17
18
|
# Replace all {{expression}} with their evaluated values
|
18
19
|
text.gsub(/\{\{([^}]+)\}\}/) do |match|
|
19
|
-
expression = Regexp.last_match(1).strip
|
20
|
+
expression = Regexp.last_match(1).to_s.strip
|
20
21
|
begin
|
21
22
|
# Evaluate the expression in the context
|
22
23
|
result = @context.instance_eval(expression).to_s
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# typed: true
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Roast
|
@@ -51,12 +52,7 @@ module Roast
|
|
51
52
|
def process_shell_command(command)
|
52
53
|
# If it's a bash command with the $(command) syntax
|
53
54
|
if command =~ /^\$\((.*)\)$/
|
54
|
-
return Open3.capture2e({}, ::Regexp.last_match(1)).first.strip
|
55
|
-
end
|
56
|
-
|
57
|
-
# Legacy % prefix for backward compatibility
|
58
|
-
if command.start_with?("% ")
|
59
|
-
return Open3.capture2e({}, *command.split(" ")[1..-1]).first.strip
|
55
|
+
return Open3.capture2e({}, ::Regexp.last_match(1).to_s).first.strip
|
60
56
|
end
|
61
57
|
|
62
58
|
# Not a shell command, return as is
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# typed: true
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Roast
|
@@ -22,9 +23,10 @@ module Roast
|
|
22
23
|
private
|
23
24
|
|
24
25
|
def default_type
|
26
|
+
state_storage = ENV["ROAST_STATE_STORAGE"]
|
25
27
|
# Check environment variable first (for backwards compatibility)
|
26
|
-
if
|
27
|
-
|
28
|
+
if state_storage
|
29
|
+
state_storage.downcase
|
28
30
|
else
|
29
31
|
# Default to SQLite for better functionality
|
30
32
|
"sqlite"
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# typed: true
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module Roast
|
@@ -145,9 +146,11 @@ module Roast
|
|
145
146
|
def execute_command_step(step, options)
|
146
147
|
exit_on_error = options.fetch(:exit_on_error, true)
|
147
148
|
resource_type = @context.resource_type
|
149
|
+
step_key = options[:step_key]
|
150
|
+
display_name = step_key || step
|
148
151
|
|
149
|
-
error_handler.with_error_handling(
|
150
|
-
$stderr.puts "Executing: #{
|
152
|
+
error_handler.with_error_handling(display_name, resource_type: resource_type) do
|
153
|
+
$stderr.puts "Executing: #{display_name} (Resource type: #{resource_type || "unknown"})"
|
151
154
|
|
152
155
|
begin
|
153
156
|
output = command_executor.execute(step, exit_on_error: exit_on_error)
|
@@ -169,7 +172,7 @@ module Roast
|
|
169
172
|
output
|
170
173
|
rescue CommandExecutor::CommandExecutionError => e
|
171
174
|
# Print user-friendly error message
|
172
|
-
$stderr.puts "\n❌ Command failed: #{
|
175
|
+
$stderr.puts "\n❌ Command failed: #{display_name}"
|
173
176
|
$stderr.puts " Exit status: #{e.exit_status}" if e.exit_status
|
174
177
|
|
175
178
|
# Show command output if available
|
@@ -257,9 +260,10 @@ module Roast
|
|
257
260
|
interpolated_step = interpolator.interpolate(step)
|
258
261
|
|
259
262
|
if StepTypeResolver.command_step?(interpolated_step)
|
260
|
-
# Command step - execute directly, preserving any passed options
|
263
|
+
# Command step - execute directly, preserving any passed options including step_key
|
261
264
|
exit_on_error = options.fetch(:exit_on_error, true)
|
262
|
-
|
265
|
+
step_key = options[:step_key]
|
266
|
+
execute_command_step(interpolated_step, { exit_on_error:, step_key: })
|
263
267
|
else
|
264
268
|
exit_on_error = options.fetch(:exit_on_error, context.exit_on_error?(step))
|
265
269
|
execute_standard_step(interpolated_step, options.merge(exit_on_error:))
|