aidp 0.5.0 → 0.8.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.
- checksums.yaml +4 -4
- data/README.md +128 -151
- data/bin/aidp +1 -1
- data/lib/aidp/analysis/kb_inspector.rb +471 -0
- data/lib/aidp/analysis/seams.rb +159 -0
- data/lib/aidp/analysis/tree_sitter_grammar_loader.rb +480 -0
- data/lib/aidp/analysis/tree_sitter_scan.rb +686 -0
- data/lib/aidp/analyze/error_handler.rb +2 -78
- data/lib/aidp/analyze/json_file_storage.rb +292 -0
- data/lib/aidp/analyze/progress.rb +12 -0
- data/lib/aidp/analyze/progress_visualizer.rb +12 -17
- data/lib/aidp/analyze/ruby_maat_integration.rb +13 -31
- data/lib/aidp/analyze/runner.rb +256 -87
- data/lib/aidp/analyze/steps.rb +6 -0
- data/lib/aidp/cli/jobs_command.rb +103 -435
- data/lib/aidp/cli.rb +317 -191
- data/lib/aidp/config.rb +298 -10
- data/lib/aidp/debug_logger.rb +195 -0
- data/lib/aidp/debug_mixin.rb +187 -0
- data/lib/aidp/execute/progress.rb +9 -0
- data/lib/aidp/execute/runner.rb +221 -40
- data/lib/aidp/execute/steps.rb +17 -7
- data/lib/aidp/execute/workflow_selector.rb +211 -0
- data/lib/aidp/harness/completion_checker.rb +268 -0
- data/lib/aidp/harness/condition_detector.rb +1526 -0
- data/lib/aidp/harness/config_loader.rb +373 -0
- data/lib/aidp/harness/config_manager.rb +382 -0
- data/lib/aidp/harness/config_schema.rb +1006 -0
- data/lib/aidp/harness/config_validator.rb +355 -0
- data/lib/aidp/harness/configuration.rb +477 -0
- data/lib/aidp/harness/enhanced_runner.rb +494 -0
- data/lib/aidp/harness/error_handler.rb +616 -0
- data/lib/aidp/harness/provider_config.rb +423 -0
- data/lib/aidp/harness/provider_factory.rb +306 -0
- data/lib/aidp/harness/provider_manager.rb +1269 -0
- data/lib/aidp/harness/provider_type_checker.rb +88 -0
- data/lib/aidp/harness/runner.rb +411 -0
- data/lib/aidp/harness/state/errors.rb +28 -0
- data/lib/aidp/harness/state/metrics.rb +219 -0
- data/lib/aidp/harness/state/persistence.rb +128 -0
- data/lib/aidp/harness/state/provider_state.rb +132 -0
- data/lib/aidp/harness/state/ui_state.rb +68 -0
- data/lib/aidp/harness/state/workflow_state.rb +123 -0
- data/lib/aidp/harness/state_manager.rb +586 -0
- data/lib/aidp/harness/status_display.rb +888 -0
- data/lib/aidp/harness/ui/base.rb +16 -0
- data/lib/aidp/harness/ui/enhanced_tui.rb +545 -0
- data/lib/aidp/harness/ui/enhanced_workflow_selector.rb +252 -0
- data/lib/aidp/harness/ui/error_handler.rb +132 -0
- data/lib/aidp/harness/ui/frame_manager.rb +361 -0
- data/lib/aidp/harness/ui/job_monitor.rb +500 -0
- data/lib/aidp/harness/ui/navigation/main_menu.rb +311 -0
- data/lib/aidp/harness/ui/navigation/menu_formatter.rb +120 -0
- data/lib/aidp/harness/ui/navigation/menu_item.rb +142 -0
- data/lib/aidp/harness/ui/navigation/menu_state.rb +139 -0
- data/lib/aidp/harness/ui/navigation/submenu.rb +202 -0
- data/lib/aidp/harness/ui/navigation/workflow_selector.rb +176 -0
- data/lib/aidp/harness/ui/progress_display.rb +280 -0
- data/lib/aidp/harness/ui/question_collector.rb +141 -0
- data/lib/aidp/harness/ui/spinner_group.rb +184 -0
- data/lib/aidp/harness/ui/spinner_helper.rb +152 -0
- data/lib/aidp/harness/ui/status_manager.rb +312 -0
- data/lib/aidp/harness/ui/status_widget.rb +280 -0
- data/lib/aidp/harness/ui/workflow_controller.rb +312 -0
- data/lib/aidp/harness/user_interface.rb +2381 -0
- data/lib/aidp/provider_manager.rb +131 -7
- data/lib/aidp/providers/anthropic.rb +28 -109
- data/lib/aidp/providers/base.rb +170 -0
- data/lib/aidp/providers/cursor.rb +52 -183
- data/lib/aidp/providers/gemini.rb +24 -109
- data/lib/aidp/providers/macos_ui.rb +99 -5
- data/lib/aidp/providers/opencode.rb +194 -0
- data/lib/aidp/storage/csv_storage.rb +172 -0
- data/lib/aidp/storage/file_manager.rb +214 -0
- data/lib/aidp/storage/json_storage.rb +140 -0
- data/lib/aidp/version.rb +1 -1
- data/lib/aidp.rb +56 -35
- data/templates/ANALYZE/06a_tree_sitter_scan.md +217 -0
- data/templates/COMMON/AGENT_BASE.md +11 -0
- data/templates/EXECUTE/00_PRD.md +4 -4
- data/templates/EXECUTE/02_ARCHITECTURE.md +5 -4
- data/templates/EXECUTE/07_TEST_PLAN.md +4 -1
- data/templates/EXECUTE/08_TASKS.md +4 -4
- data/templates/EXECUTE/10_IMPLEMENTATION_AGENT.md +4 -4
- data/templates/README.md +279 -0
- data/templates/aidp-development.yml.example +373 -0
- data/templates/aidp-minimal.yml.example +48 -0
- data/templates/aidp-production.yml.example +475 -0
- data/templates/aidp.yml.example +598 -0
- metadata +106 -64
- data/lib/aidp/analyze/agent_personas.rb +0 -71
- data/lib/aidp/analyze/agent_tool_executor.rb +0 -445
- data/lib/aidp/analyze/data_retention_manager.rb +0 -426
- data/lib/aidp/analyze/database.rb +0 -260
- data/lib/aidp/analyze/dependencies.rb +0 -335
- data/lib/aidp/analyze/export_manager.rb +0 -425
- data/lib/aidp/analyze/focus_guidance.rb +0 -517
- data/lib/aidp/analyze/incremental_analyzer.rb +0 -543
- data/lib/aidp/analyze/language_analysis_strategies.rb +0 -897
- data/lib/aidp/analyze/large_analysis_progress.rb +0 -504
- data/lib/aidp/analyze/memory_manager.rb +0 -365
- data/lib/aidp/analyze/metrics_storage.rb +0 -336
- data/lib/aidp/analyze/parallel_processor.rb +0 -460
- data/lib/aidp/analyze/performance_optimizer.rb +0 -694
- data/lib/aidp/analyze/repository_chunker.rb +0 -704
- data/lib/aidp/analyze/static_analysis_detector.rb +0 -577
- data/lib/aidp/analyze/storage.rb +0 -662
- data/lib/aidp/analyze/tool_configuration.rb +0 -456
- data/lib/aidp/analyze/tool_modernization.rb +0 -750
- data/lib/aidp/database/pg_adapter.rb +0 -148
- data/lib/aidp/database_config.rb +0 -69
- data/lib/aidp/database_connection.rb +0 -72
- data/lib/aidp/database_migration.rb +0 -158
- data/lib/aidp/job_manager.rb +0 -41
- data/lib/aidp/jobs/base_job.rb +0 -47
- data/lib/aidp/jobs/provider_execution_job.rb +0 -96
- data/lib/aidp/project_detector.rb +0 -117
- data/lib/aidp/providers/agent_supervisor.rb +0 -348
- data/lib/aidp/providers/supervised_base.rb +0 -317
- data/lib/aidp/providers/supervised_cursor.rb +0 -22
- data/lib/aidp/sync.rb +0 -13
- data/lib/aidp/workspace.rb +0 -19
@@ -0,0 +1,252 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "enhanced_tui"
|
4
|
+
|
5
|
+
module Aidp
|
6
|
+
module Harness
|
7
|
+
module UI
|
8
|
+
# Enhanced workflow selector with TTY components
|
9
|
+
class EnhancedWorkflowSelector
|
10
|
+
class WorkflowError < StandardError; end
|
11
|
+
|
12
|
+
def initialize(tui = nil)
|
13
|
+
@tui = tui || EnhancedTUI.new
|
14
|
+
@user_input = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def select_workflow(harness_mode: false, mode: :analyze)
|
18
|
+
if harness_mode
|
19
|
+
select_workflow_with_defaults(mode)
|
20
|
+
else
|
21
|
+
select_workflow_interactive(mode)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def select_workflow_interactive(mode)
|
28
|
+
case mode
|
29
|
+
when :analyze
|
30
|
+
select_analyze_workflow_interactive
|
31
|
+
when :execute
|
32
|
+
select_execute_workflow_interactive
|
33
|
+
else
|
34
|
+
raise ArgumentError, "Unknown mode: #{mode}"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def select_workflow_with_defaults(mode)
|
39
|
+
case mode
|
40
|
+
when :analyze
|
41
|
+
select_analyze_workflow_defaults
|
42
|
+
when :execute
|
43
|
+
select_execute_workflow_defaults
|
44
|
+
else
|
45
|
+
raise ArgumentError, "Unknown mode: #{mode}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def select_analyze_workflow_interactive
|
50
|
+
# For analyze mode, we don't need complex project setup
|
51
|
+
# Just use default values and start analysis
|
52
|
+
@user_input = {
|
53
|
+
project_description: "Codebase analysis",
|
54
|
+
analysis_scope: "full",
|
55
|
+
focus_areas: "all"
|
56
|
+
}
|
57
|
+
|
58
|
+
# Analyze mode uses predefined steps
|
59
|
+
steps = Aidp::Analyze::Steps::SPEC.keys
|
60
|
+
|
61
|
+
{
|
62
|
+
workflow_type: :analysis,
|
63
|
+
steps: steps,
|
64
|
+
user_input: @user_input
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def select_execute_workflow_interactive
|
69
|
+
# Step 1: Collect project information
|
70
|
+
collect_project_info_interactive
|
71
|
+
|
72
|
+
# Step 2: Choose workflow type
|
73
|
+
workflow_type = choose_workflow_type_interactive
|
74
|
+
|
75
|
+
# Step 3: Generate workflow steps
|
76
|
+
steps = generate_workflow_steps_interactive(workflow_type)
|
77
|
+
|
78
|
+
{
|
79
|
+
workflow_type: workflow_type,
|
80
|
+
steps: steps,
|
81
|
+
user_input: @user_input
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
def select_analyze_workflow_defaults
|
86
|
+
@tui.show_message("🚀 Starting analyze mode with default configuration...", :info)
|
87
|
+
|
88
|
+
@user_input = {
|
89
|
+
project_description: "Codebase analysis",
|
90
|
+
analysis_scope: "full",
|
91
|
+
focus_areas: "all"
|
92
|
+
}
|
93
|
+
|
94
|
+
steps = Aidp::Analyze::Steps::SPEC.keys
|
95
|
+
|
96
|
+
{
|
97
|
+
workflow_type: :analysis,
|
98
|
+
steps: steps,
|
99
|
+
user_input: @user_input
|
100
|
+
}
|
101
|
+
end
|
102
|
+
|
103
|
+
def select_execute_workflow_defaults
|
104
|
+
@tui.show_message("🚀 Starting execute mode with default workflow configuration...", :info)
|
105
|
+
|
106
|
+
# Use default project information
|
107
|
+
@user_input = {
|
108
|
+
project_description: "AI-powered development pipeline project",
|
109
|
+
tech_stack: "Ruby/Rails",
|
110
|
+
target_users: "developers",
|
111
|
+
success_criteria: "Successful automation of development workflows"
|
112
|
+
}
|
113
|
+
|
114
|
+
# Default to exploration workflow for harness mode
|
115
|
+
workflow_type = :exploration
|
116
|
+
|
117
|
+
# Generate workflow steps
|
118
|
+
steps = generate_workflow_steps(workflow_type)
|
119
|
+
|
120
|
+
{
|
121
|
+
workflow_type: workflow_type,
|
122
|
+
steps: steps,
|
123
|
+
user_input: @user_input
|
124
|
+
}
|
125
|
+
end
|
126
|
+
|
127
|
+
def collect_project_info_interactive
|
128
|
+
@tui.show_message("📋 Project Setup", :info)
|
129
|
+
@tui.show_message("Let's set up your development workflow", :info)
|
130
|
+
|
131
|
+
@user_input[:project_description] = @tui.get_user_input("What do you want to build? (Be specific about features and goals)")
|
132
|
+
@tui.show_message("✅ Project description captured", :success)
|
133
|
+
|
134
|
+
@user_input[:tech_stack] = @tui.get_user_input("What technology stack are you using? (e.g., Ruby/Rails, Node.js, Python/Django) [optional]")
|
135
|
+
@tui.show_message("✅ Tech stack captured", :success)
|
136
|
+
|
137
|
+
@user_input[:target_users] = @tui.get_user_input("Who are the target users? (e.g., developers, end users, internal team) [optional]")
|
138
|
+
@tui.show_message("✅ Target users captured", :success)
|
139
|
+
|
140
|
+
@user_input[:success_criteria] = @tui.get_user_input("How will you know this is successful? (e.g., performance metrics, user adoption) [optional]")
|
141
|
+
@tui.show_message("✅ Success criteria captured", :success)
|
142
|
+
end
|
143
|
+
|
144
|
+
def choose_workflow_type_interactive
|
145
|
+
@tui.show_message("🛠️ Workflow Selection", :info)
|
146
|
+
@tui.show_message("Choose your development approach:", :info)
|
147
|
+
|
148
|
+
workflow_options = [
|
149
|
+
"🔬 Exploration/Experiment - Quick prototype or proof of concept",
|
150
|
+
"🏗️ Full Development - Production-ready feature or system"
|
151
|
+
]
|
152
|
+
|
153
|
+
selected = @tui.single_select("Select workflow type", workflow_options, default: 1)
|
154
|
+
@user_input[:workflow_type] = selected
|
155
|
+
|
156
|
+
if selected.include?("Exploration")
|
157
|
+
@tui.show_message("🔬 Using exploration workflow - fast iteration, minimal documentation", :info)
|
158
|
+
:exploration
|
159
|
+
else
|
160
|
+
@tui.show_message("🏗️ Using full development workflow - comprehensive planning and documentation", :info)
|
161
|
+
:full
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def generate_workflow_steps_interactive(workflow_type)
|
166
|
+
case workflow_type
|
167
|
+
when :exploration
|
168
|
+
generate_exploration_steps
|
169
|
+
when :full
|
170
|
+
generate_full_steps_interactive
|
171
|
+
else
|
172
|
+
generate_exploration_steps
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def generate_exploration_steps
|
177
|
+
@tui.show_message("🔬 Using exploration workflow - fast iteration, minimal documentation", :info)
|
178
|
+
[
|
179
|
+
"00_PRD", # Generate PRD from user input (no manual gate)
|
180
|
+
"10_TESTING_STRATEGY", # Ensure we have tests
|
181
|
+
"11_STATIC_ANALYSIS", # Code quality
|
182
|
+
"16_IMPLEMENTATION" # Special step for actual development work
|
183
|
+
]
|
184
|
+
end
|
185
|
+
|
186
|
+
def generate_full_steps_interactive
|
187
|
+
@tui.show_message("🏗️ Customize Full Workflow", :info)
|
188
|
+
@tui.show_message("Customizing your full development workflow", :info)
|
189
|
+
|
190
|
+
available_steps = [
|
191
|
+
"00_PRD - Product Requirements Document (required)",
|
192
|
+
"01_NFRS - Non-Functional Requirements (optional)",
|
193
|
+
"02_ARCHITECTURE - System Architecture (optional)",
|
194
|
+
"03_ADR_FACTORY - Architecture Decision Records (optional)",
|
195
|
+
"04_DOMAIN_DECOMPOSITION - Domain Analysis (optional)",
|
196
|
+
"05_API_DESIGN - API and Interface Design (optional)",
|
197
|
+
"07_SECURITY_REVIEW - Security Analysis (optional)",
|
198
|
+
"08_PERFORMANCE_REVIEW - Performance Planning (optional)",
|
199
|
+
"10_TESTING_STRATEGY - Testing Strategy (required)",
|
200
|
+
"11_STATIC_ANALYSIS - Code Quality Analysis (required)",
|
201
|
+
"12_OBSERVABILITY_SLOS - Monitoring & SLOs (optional)",
|
202
|
+
"13_DELIVERY_ROLLOUT - Deployment Planning (optional)"
|
203
|
+
]
|
204
|
+
|
205
|
+
# Use TTY multiselect with required steps pre-selected
|
206
|
+
selected = @tui.multiselect("Select steps to include in your workflow", available_steps, selected: [0, 8, 9])
|
207
|
+
|
208
|
+
# Convert back to step keys
|
209
|
+
selected_steps = selected.map do |step_name|
|
210
|
+
step_name.split(" - ").first
|
211
|
+
end
|
212
|
+
|
213
|
+
# Add implementation at the end
|
214
|
+
selected_steps << "16_IMPLEMENTATION"
|
215
|
+
|
216
|
+
@tui.show_message("✅ Selected #{selected_steps.length} steps for your workflow", :success)
|
217
|
+
selected_steps
|
218
|
+
end
|
219
|
+
|
220
|
+
def generate_workflow_steps(workflow_type)
|
221
|
+
case workflow_type
|
222
|
+
when :exploration
|
223
|
+
generate_exploration_steps
|
224
|
+
when :full
|
225
|
+
generate_full_steps
|
226
|
+
else
|
227
|
+
generate_exploration_steps
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
def generate_full_steps
|
232
|
+
# Default full workflow steps
|
233
|
+
[
|
234
|
+
"00_PRD",
|
235
|
+
"01_NFRS",
|
236
|
+
"02_ARCHITECTURE",
|
237
|
+
"03_ADR_FACTORY",
|
238
|
+
"04_DOMAIN_DECOMPOSITION",
|
239
|
+
"05_API_DESIGN",
|
240
|
+
"07_SECURITY_REVIEW",
|
241
|
+
"08_PERFORMANCE_REVIEW",
|
242
|
+
"10_TESTING_STRATEGY",
|
243
|
+
"11_STATIC_ANALYSIS",
|
244
|
+
"12_OBSERVABILITY_SLOS",
|
245
|
+
"13_DELIVERY_ROLLOUT",
|
246
|
+
"16_IMPLEMENTATION"
|
247
|
+
]
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "pastel"
|
4
|
+
|
5
|
+
module Aidp
|
6
|
+
module Harness
|
7
|
+
module UI
|
8
|
+
# Centralized error handling for UI components
|
9
|
+
class ErrorHandler
|
10
|
+
class UIError < StandardError; end
|
11
|
+
class ComponentError < UIError; end
|
12
|
+
class ValidationError < UIError; end
|
13
|
+
class DisplayError < UIError; end
|
14
|
+
class InteractionError < UIError; end
|
15
|
+
|
16
|
+
def initialize(ui_components = {})
|
17
|
+
@logger = ui_components[:logger] || default_logger
|
18
|
+
@formatter = ui_components[:formatter] || ErrorFormatter.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def handle_error(error, context = {})
|
22
|
+
log_error(error, context)
|
23
|
+
display_error(error, context)
|
24
|
+
end
|
25
|
+
|
26
|
+
def handle_validation_error(error, field_name = nil)
|
27
|
+
message = @formatter.format_validation_error(error, field_name)
|
28
|
+
display_user_friendly_error(message)
|
29
|
+
end
|
30
|
+
|
31
|
+
def handle_display_error(error, component_name = nil)
|
32
|
+
message = @formatter.format_display_error(error, component_name)
|
33
|
+
display_user_friendly_error(message)
|
34
|
+
end
|
35
|
+
|
36
|
+
def handle_interaction_error(error, interaction_type = nil)
|
37
|
+
message = @formatter.format_interaction_error(error, interaction_type)
|
38
|
+
display_user_friendly_error(message)
|
39
|
+
end
|
40
|
+
|
41
|
+
def handle_component_error(error, component_name = nil)
|
42
|
+
message = @formatter.format_component_error(error, component_name)
|
43
|
+
display_user_friendly_error(message)
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def log_error(error, context)
|
49
|
+
@logger.error("UI Error: #{error.class.name}: #{error.message}")
|
50
|
+
@logger.error("Context: #{context}") unless context.empty?
|
51
|
+
@logger.error("Backtrace: #{error.backtrace.join("\n")}") if error.backtrace
|
52
|
+
end
|
53
|
+
|
54
|
+
def display_error(error, context)
|
55
|
+
case error
|
56
|
+
when ValidationError
|
57
|
+
handle_validation_error(error, context[:field_name])
|
58
|
+
when DisplayError
|
59
|
+
handle_display_error(error, context[:component_name])
|
60
|
+
when InteractionError
|
61
|
+
handle_interaction_error(error, context[:interaction_type])
|
62
|
+
when ComponentError
|
63
|
+
handle_component_error(error, context[:component_name])
|
64
|
+
else
|
65
|
+
display_generic_error(error)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def display_user_friendly_error(message)
|
70
|
+
pastel = Pastel.new
|
71
|
+
puts("#{pastel.red("Error:")} #{message}")
|
72
|
+
end
|
73
|
+
|
74
|
+
def display_generic_error(error)
|
75
|
+
message = @formatter.format_generic_error(error)
|
76
|
+
display_user_friendly_error(message)
|
77
|
+
end
|
78
|
+
|
79
|
+
def default_logger
|
80
|
+
require "logger"
|
81
|
+
Logger.new($stderr)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Formats error messages for display
|
86
|
+
class ErrorFormatter
|
87
|
+
def format_validation_error(error, field_name = nil)
|
88
|
+
base_message = "Validation failed"
|
89
|
+
field_suffix = field_name ? " for #{field_name}" : ""
|
90
|
+
"#{base_message}#{field_suffix}: #{error.message}"
|
91
|
+
end
|
92
|
+
|
93
|
+
def format_display_error(error, component_name = nil)
|
94
|
+
base_message = "Display error"
|
95
|
+
component_suffix = component_name ? " in #{component_name}" : ""
|
96
|
+
"#{base_message}#{component_suffix}: #{error.message}"
|
97
|
+
end
|
98
|
+
|
99
|
+
def format_interaction_error(error, interaction_type = nil)
|
100
|
+
base_message = "Interaction error"
|
101
|
+
type_suffix = interaction_type ? " during #{interaction_type}" : ""
|
102
|
+
"#{base_message}#{type_suffix}: #{error.message}"
|
103
|
+
end
|
104
|
+
|
105
|
+
def format_component_error(error, component_name = nil)
|
106
|
+
base_message = "Component error"
|
107
|
+
component_suffix = component_name ? " in #{component_name}" : ""
|
108
|
+
"#{base_message}#{component_suffix}: #{error.message}"
|
109
|
+
end
|
110
|
+
|
111
|
+
def format_generic_error(error)
|
112
|
+
"An unexpected error occurred: #{error.message}"
|
113
|
+
end
|
114
|
+
|
115
|
+
def format_recovery_suggestion(error_type)
|
116
|
+
case error_type
|
117
|
+
when :validation
|
118
|
+
"Please check your input and try again."
|
119
|
+
when :display
|
120
|
+
"The display may not render correctly. Please try again."
|
121
|
+
when :interaction
|
122
|
+
"Please try the interaction again."
|
123
|
+
when :component
|
124
|
+
"The component may not function properly. Please restart the application."
|
125
|
+
else
|
126
|
+
"Please try again or restart the application if the problem persists."
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|