rooibos 0.5.0 → 0.6.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 (169) hide show
  1. checksums.yaml +4 -4
  2. data/.builds/ruby-3.2.yml +9 -5
  3. data/.builds/ruby-3.3.yml +9 -5
  4. data/.builds/ruby-3.4.yml +9 -5
  5. data/.builds/ruby-4.0.0.yml +9 -5
  6. data/AGENTS.md +1 -1
  7. data/CHANGELOG.md +46 -0
  8. data/README.md +2 -2
  9. data/README.rdoc +374 -0
  10. data/REUSE.toml +5 -0
  11. data/Rakefile +1 -1
  12. data/doc/best_practices/forms_and_validation.md +20 -0
  13. data/doc/best_practices/http_workflows.md +20 -0
  14. data/doc/best_practices/index.md +26 -0
  15. data/doc/best_practices/lists_and_tables.md +20 -0
  16. data/doc/best_practices/modal_dialogs.md +20 -0
  17. data/doc/best_practices/no_stateful_widgets.md +184 -0
  18. data/doc/best_practices/orchestration.md +20 -0
  19. data/doc/best_practices/streaming_data.md +20 -0
  20. data/doc/contributors/design/commands_and_outlets.md +1 -1
  21. data/doc/contributors/documentation_plan.md +616 -0
  22. data/doc/contributors/documentation_stub_audit.md +112 -0
  23. data/doc/contributors/documentation_style.md +275 -0
  24. data/doc/contributors/e2e_pty.md +168 -0
  25. data/doc/contributors/specs/earliest_tutorial_steps_per_story.md +70 -0
  26. data/doc/contributors/specs/file_browser.md +789 -0
  27. data/doc/contributors/specs/file_browser_stories.md +774 -0
  28. data/doc/contributors/specs/tutorials_to_stories.rb +167 -0
  29. data/doc/contributors/todo/scrollbar.md +118 -0
  30. data/doc/contributors/tutorial_old/01_project_setup.md +20 -0
  31. data/doc/contributors/tutorial_old/02_hello_world.md +24 -0
  32. data/doc/contributors/tutorial_old/03_adding_state.md +26 -0
  33. data/doc/contributors/tutorial_old/06_organizing_your_code.md +20 -0
  34. data/doc/contributors/tutorial_old/07_your_first_command.md +21 -0
  35. data/doc/contributors/tutorial_old/08_the_preview_pane.md +20 -0
  36. data/doc/contributors/tutorial_old/09_loading_states.md +20 -0
  37. data/doc/contributors/tutorial_old/10_testing_your_app.md +20 -0
  38. data/doc/contributors/tutorial_old/11_polish_and_refine.md +20 -0
  39. data/doc/contributors/tutorial_old/12_going_further.md +20 -0
  40. data/doc/contributors/tutorial_old/index.md +20 -0
  41. data/doc/essentials/commands.md +20 -0
  42. data/doc/essentials/index.md +31 -0
  43. data/doc/essentials/messages.md +21 -0
  44. data/doc/essentials/models.md +21 -0
  45. data/doc/essentials/shortcuts.md +19 -0
  46. data/doc/essentials/the_elm_architecture.md +24 -0
  47. data/doc/essentials/the_runtime.md +21 -0
  48. data/doc/essentials/update_functions.md +20 -0
  49. data/doc/essentials/views.md +22 -0
  50. data/doc/getting_started/for_go_developers.md +16 -0
  51. data/doc/getting_started/for_python_developers.md +16 -0
  52. data/doc/getting_started/for_react_developers.md +17 -0
  53. data/doc/getting_started/index.md +52 -0
  54. data/doc/getting_started/install.md +20 -0
  55. data/doc/getting_started/quickstart.md +9 -45
  56. data/doc/getting_started/ruby_primer.md +19 -0
  57. data/doc/getting_started/why_rooibos.md +20 -0
  58. data/doc/index.md +79 -11
  59. data/doc/scaling_up/async_patterns.md +20 -0
  60. data/doc/scaling_up/command_composition.md +20 -0
  61. data/doc/scaling_up/custom_commands.md +21 -0
  62. data/doc/scaling_up/fractal_architecture.md +20 -0
  63. data/doc/scaling_up/index.md +30 -0
  64. data/doc/scaling_up/message_routing.md +20 -0
  65. data/doc/scaling_up/ractor_safety.md +20 -0
  66. data/doc/scaling_up/testing.md +21 -0
  67. data/doc/troubleshooting/common_errors.md +20 -0
  68. data/doc/troubleshooting/debugging.md +21 -0
  69. data/doc/troubleshooting/index.md +23 -0
  70. data/doc/troubleshooting/performance.md +20 -0
  71. data/doc/tutorial/01_project_setup.md +44 -0
  72. data/doc/tutorial/02_hello_world.md +45 -0
  73. data/doc/tutorial/03_static_file_list.md +44 -0
  74. data/doc/tutorial/04_arrow_navigation.md +47 -0
  75. data/doc/tutorial/05_real_files.md +45 -0
  76. data/doc/tutorial/06_safe_refactoring.md +21 -0
  77. data/doc/tutorial/07_red_first_tdd.md +26 -0
  78. data/doc/tutorial/08_file_metadata.md +42 -0
  79. data/doc/tutorial/09_text_preview.md +44 -0
  80. data/doc/tutorial/10_directory_tree.md +42 -0
  81. data/doc/tutorial/11_pane_focus.md +40 -0
  82. data/doc/tutorial/12_sorting.md +41 -0
  83. data/doc/tutorial/13_filtering.md +43 -0
  84. data/doc/tutorial/14_toggle_hidden.md +41 -0
  85. data/doc/tutorial/15_text_input_widget.md +43 -0
  86. data/doc/tutorial/16_rename_files.md +42 -0
  87. data/doc/tutorial/17_confirmation_dialogs.md +43 -0
  88. data/doc/tutorial/18_progress_indicators.md +43 -0
  89. data/doc/tutorial/19_atomic_operations.md +42 -0
  90. data/doc/tutorial/20_external_editor.md +42 -0
  91. data/doc/tutorial/21_modal_overlays.md +41 -0
  92. data/doc/tutorial/22_error_handling.md +43 -0
  93. data/doc/tutorial/23_terminal_capabilities.md +53 -0
  94. data/doc/tutorial/24_mouse_events.md +43 -0
  95. data/doc/tutorial/25_resize_events.md +43 -0
  96. data/doc/tutorial/26_loading_states.md +42 -0
  97. data/doc/tutorial/27_performance.md +43 -0
  98. data/doc/tutorial/28_color_schemes.md +47 -0
  99. data/doc/tutorial/29_configuration.md +124 -0
  100. data/doc/tutorial/30_going_further.md +17 -0
  101. data/doc/tutorial/index.md +17 -0
  102. data/examples/app_file_browser/app.rb +40 -0
  103. data/examples/app_fractal_dashboard/dashboard/update_manual.rb +7 -7
  104. data/examples/app_fractal_dashboard/fragments/custom_shell_input.rb +5 -5
  105. data/examples/app_fractal_dashboard/fragments/custom_shell_modal.rb +1 -1
  106. data/examples/app_fractal_dashboard/fragments/disk_usage.rb +2 -2
  107. data/examples/app_fractal_dashboard/fragments/network_panel.rb +4 -4
  108. data/examples/app_fractal_dashboard/fragments/ping.rb +2 -2
  109. data/examples/app_fractal_dashboard/fragments/stats_panel.rb +4 -4
  110. data/examples/app_fractal_dashboard/fragments/system_info.rb +2 -2
  111. data/examples/app_fractal_dashboard/fragments/uptime.rb +2 -2
  112. data/examples/verify_website_first_app/app.rb +85 -0
  113. data/examples/verify_website_hello_mvu/app.rb +31 -0
  114. data/examples/widget_command_system/app.rb +15 -13
  115. data/exe/rooibos +10 -0
  116. data/generate_tutorial_stubs.rb +126 -0
  117. data/lib/rooibos/cli/commands/new.rb +373 -0
  118. data/lib/rooibos/cli/commands/run.rb +98 -0
  119. data/lib/rooibos/cli.rb +78 -0
  120. data/lib/rooibos/command/all.rb +25 -20
  121. data/lib/rooibos/command/batch.rb +26 -25
  122. data/lib/rooibos/command/custom.rb +84 -1
  123. data/lib/rooibos/command/http.rb +59 -55
  124. data/lib/rooibos/command/lifecycle.rb +5 -5
  125. data/lib/rooibos/command/open.rb +86 -0
  126. data/lib/rooibos/command/outlet.rb +105 -3
  127. data/lib/rooibos/command/wait.rb +5 -5
  128. data/lib/rooibos/command.rb +57 -74
  129. data/lib/rooibos/message/batch.rb +39 -0
  130. data/lib/rooibos/message/canceled.rb +51 -0
  131. data/lib/rooibos/message/error.rb +48 -0
  132. data/lib/rooibos/message/open.rb +30 -0
  133. data/lib/rooibos/message.rb +84 -4
  134. data/lib/rooibos/router.rb +11 -14
  135. data/lib/rooibos/runtime.rb +40 -43
  136. data/lib/rooibos/shortcuts.rb +47 -0
  137. data/lib/rooibos/test_helper.rb +71 -6
  138. data/lib/rooibos/version.rb +1 -1
  139. data/lib/rooibos/welcome.rb +237 -0
  140. data/lib/rooibos.rb +4 -3
  141. data/mise.toml +1 -1
  142. data/rbs_collection.lock.yaml +2 -2
  143. data/sig/concurrent.rbs +3 -0
  144. data/sig/gem.rbs +20 -0
  145. data/sig/rooibos/cli.rbs +42 -0
  146. data/sig/rooibos/command.rbs +48 -0
  147. data/sig/rooibos/message.rbs +60 -0
  148. data/sig/rooibos/shortcuts.rbs +14 -0
  149. data/sig/rooibos/test_helper.rbs +6 -2
  150. data/sig/rooibos/welcome.rbs +75 -0
  151. data/tasks/install.rake +29 -0
  152. data/tasks/resources/build.yml.erb +2 -0
  153. metadata +272 -38
  154. data/doc/concepts/application_architecture.md +0 -197
  155. data/doc/concepts/application_testing.md +0 -49
  156. data/doc/concepts/async_work.md +0 -164
  157. data/doc/concepts/commands.md +0 -530
  158. data/doc/concepts/message_processing.md +0 -51
  159. data/doc/contributors/WIP/decomposition_strategies_analysis.md +0 -258
  160. data/doc/contributors/WIP/implementation_plan.md +0 -409
  161. data/doc/contributors/WIP/init_callable_proposal.md +0 -344
  162. data/doc/contributors/WIP/runtime_refactoring_status.md +0 -47
  163. data/doc/contributors/WIP/task.md +0 -36
  164. data/doc/contributors/WIP/v0.4.0_todo.md +0 -468
  165. data/doc/contributors/kit-no-outlet.md +0 -238
  166. data/doc/contributors/priorities.md +0 -38
  167. data/doc/images/.gitkeep +0 -0
  168. data/exe/.gitkeep +0 -0
  169. /data/doc/contributors/{WIP → design}/mvu_tea_implementations_research.md +0 -0
@@ -0,0 +1,789 @@
1
+ <!--
2
+ SPDX-FileCopyrightText: 2026 Kerrick Long <me@kerricklong.com>
3
+ SPDX-License-Identifier: CC-BY-SA-4.0
4
+ -->
5
+
6
+ # File Browser Application Specification
7
+
8
+ **Version:** 1.0
9
+ **Status:** Final
10
+ **Date:** 2026-01-22
11
+ **Author:** Business Analysis Team
12
+
13
+ ## Executive Summary
14
+
15
+ This document specifies the requirements for a professional-grade terminal-based file browser application. The application provides efficient keyboard-driven navigation and file management capabilities optimized for terminal users who value speed, clarity, and reliability.
16
+
17
+ ## 1. Purpose and Scope
18
+
19
+ ### 1.1 Purpose
20
+
21
+ The File Browser enables users to navigate directory structures, view file metadata, preview file contents, and perform common file operations entirely within a terminal interface.
22
+
23
+ ### 1.2 Target Users
24
+
25
+ - Software developers navigating project directories
26
+ - System administrators managing server filesystems
27
+ - Power users who prefer keyboard-driven workflows
28
+ - Anyone working in terminal-only environments (SSH sessions, containers)
29
+
30
+ ### 1.3 Scope
31
+
32
+ **In Scope:**
33
+ - Directory tree navigation
34
+ - File and directory listing with metadata
35
+ - Text file preview
36
+ - File and directory operations (create, rename, delete, copy, move)
37
+ - Search and filtering
38
+ - Keyboard-driven interface
39
+ - Error handling and user feedback
40
+
41
+ **Out of Scope:**
42
+ - File editing (users should use their preferred editor)
43
+ - Binary file manipulation
44
+ - Network filesystem operations
45
+ - Archive extraction/creation
46
+ - File permissions modification
47
+ - Symbolic link creation
48
+
49
+ ## 2. User Interface Requirements
50
+
51
+ ### 2.1 Layout
52
+
53
+ The application uses a three-pane layout optimized for terminal displays:
54
+
55
+ **Left Pane: Directory Tree (25% width)**
56
+ - Hierarchical view of directory structure
57
+ - Expandable/collapsible directories
58
+ - Visual indicators for directory state (expanded/collapsed)
59
+ - Current location indicator
60
+
61
+ **Center Pane: File List (40% width)**
62
+ - Detailed listing of current directory contents
63
+ - Sortable columns (name, size, modified date, type)
64
+ - Visual distinction between files and directories
65
+ - Selection indicator
66
+
67
+ **Right Pane: Preview (35% width)**
68
+ - File content preview for text files
69
+ - Metadata display for all file types
70
+ - Scrollable content area
71
+
72
+ **Status Bar (Bottom)**
73
+ - Current path
74
+ - Item count (files/directories)
75
+ - Selected item information
76
+ - Operation status messages
77
+
78
+ **Title Bar (Top)**
79
+ - Application name
80
+ - Current operation mode
81
+ - Help hint
82
+
83
+ ### 2.2 Visual Design
84
+
85
+ **Color Scheme:**
86
+ - Directories: Blue (bold)
87
+ - Regular files: Default terminal color
88
+ - Executable files: Green
89
+ - Hidden files: Dim/gray
90
+ - Selected item: Inverted colors or highlighted background
91
+ - Error messages: Red
92
+ - Success messages: Green
93
+ - Information messages: Yellow
94
+
95
+ **Typography:**
96
+ - Monospace font (terminal default)
97
+ - Box-drawing characters for tree structure
98
+ - Unicode symbols for file type indicators (📁 📄 🔗)
99
+
100
+ **Spacing:**
101
+ - Single-line spacing between items
102
+ - Borders between panes using box-drawing characters
103
+ - Padding: 1 space inside pane borders
104
+
105
+ ### 2.3 Accessibility
106
+
107
+ - High contrast color scheme
108
+ - Clear visual hierarchy
109
+ - Keyboard-only operation (no mouse required)
110
+ - Screen reader compatible (plain text output)
111
+ - Configurable color scheme for color blindness
112
+
113
+ ## 3. Functional Requirements
114
+
115
+ ### 3.1 Navigation
116
+
117
+ **FR-NAV-001: Directory Tree Navigation**
118
+ - User can expand/collapse directories in tree pane
119
+ - User can navigate up/down through tree items
120
+ - User can jump to parent directory
121
+ - User can jump to home directory
122
+ - User can jump to root directory
123
+
124
+ **FR-NAV-002: File List Navigation**
125
+ - User can navigate up/down through file list
126
+ - User can page up/down through long lists
127
+ - User can jump to first/last item
128
+ - User can navigate to parent directory (..)
129
+
130
+ **FR-NAV-003: Preview Pane Scrolling**
131
+ - User can scroll preview content up/down
132
+ - User can page up/down in preview
133
+ - User can jump to top/bottom of preview
134
+
135
+ **FR-NAV-004: Focus Management**
136
+ - User can switch focus between panes (tree, list, preview)
137
+ - Active pane is visually indicated
138
+ - Keyboard shortcuts work in context of active pane
139
+
140
+ ### 3.2 File Operations
141
+
142
+ **FR-FILE-001: View File Information**
143
+ - Display file name, size, modification date, permissions
144
+ - Display file type (regular, directory, symlink)
145
+ - Display line count for text files
146
+ - Display human-readable file sizes (KB, MB, GB)
147
+
148
+ **FR-FILE-002: Preview Text Files**
149
+ - Display first N lines of text files in preview pane
150
+ - Support UTF-8 encoded files
151
+ - Handle large files gracefully (don't load entire file)
152
+ - Display "Binary file" message for non-text files
153
+
154
+ **FR-FILE-003: Create Directory**
155
+ - User can create new directory in current location
156
+ - Prompt for directory name
157
+ - Validate directory name (no invalid characters)
158
+ - Display success/error message
159
+ - Refresh view to show new directory
160
+
161
+ **FR-FILE-004: Rename File/Directory**
162
+ - User can rename selected file or directory
163
+ - Pre-populate input with current name
164
+ - Validate new name (no invalid characters, no conflicts)
165
+ - Display success/error message
166
+ - Update view to reflect new name
167
+
168
+ **FR-FILE-005: Delete File/Directory**
169
+ - User can delete selected file or directory
170
+ - Require confirmation before deletion
171
+ - Display clear warning for directory deletion
172
+ - Display success/error message
173
+ - Refresh view after deletion
174
+
175
+ **FR-FILE-006: Copy File/Directory**
176
+ - User can copy selected file or directory
177
+ - Prompt for destination path
178
+ - Validate destination (exists, writable)
179
+ - Display progress for large operations
180
+ - Display success/error message
181
+
182
+ **FR-FILE-007: Move File/Directory**
183
+ - User can move selected file or directory
184
+ - Prompt for destination path
185
+ - Validate destination (exists, writable, no conflicts)
186
+ - Display success/error message
187
+ - Update view to reflect new location
188
+
189
+ **FR-FILE-008: Open File in External Editor**
190
+ - User can open selected file in $EDITOR
191
+ - Suspend file browser while editor is running
192
+ - Resume file browser when editor closes
193
+ - Refresh view to show any changes
194
+
195
+ ### 3.3 Search and Filtering
196
+
197
+ **FR-SEARCH-001: Filter by Name**
198
+ - User can enter filter pattern
199
+ - Display only items matching pattern
200
+ - Support wildcards (* and ?)
201
+ - Case-insensitive matching
202
+ - Clear filter to show all items
203
+
204
+ **FR-SEARCH-002: Show/Hide Hidden Files**
205
+ - User can toggle visibility of hidden files (starting with .)
206
+ - Persist preference during session
207
+ - Visual indicator of current filter state
208
+
209
+ **FR-SEARCH-003: Sort Options**
210
+ - User can sort by name (ascending/descending)
211
+ - User can sort by size (ascending/descending)
212
+ - User can sort by modification date (ascending/descending)
213
+ - User can sort by type (directories first/last)
214
+ - Visual indicator of current sort order
215
+
216
+ ### 3.4 Error Handling
217
+
218
+ **FR-ERROR-001: Permission Errors**
219
+ - Display clear message when directory cannot be read
220
+ - Display clear message when file cannot be accessed
221
+ - Suggest resolution (check permissions)
222
+ - Allow user to continue browsing accessible areas
223
+
224
+ **FR-ERROR-002: File System Errors**
225
+ - Handle missing files gracefully (deleted externally)
226
+ - Handle renamed files gracefully
227
+ - Handle full disk scenarios
228
+ - Display specific error messages, not generic failures
229
+
230
+ **FR-ERROR-003: Invalid Input**
231
+ - Validate user input before operations
232
+ - Display specific validation errors
233
+ - Highlight invalid characters in input
234
+ - Provide examples of valid input
235
+
236
+ ### 3.5 Performance
237
+
238
+ **FR-PERF-001: Large Directories**
239
+ - Handle directories with 10,000+ items
240
+ - Use pagination or virtual scrolling
241
+ - Maintain responsive UI during loading
242
+ - Display loading indicator for slow operations
243
+
244
+ **FR-PERF-002: Large Files**
245
+ - Preview large files without loading entire content
246
+ - Limit preview to first 1,000 lines
247
+ - Display file size warning for very large files
248
+ - Maintain responsive UI during preview loading
249
+
250
+ **FR-PERF-003: Startup Time**
251
+ - Launch in under 500ms on modern hardware
252
+ - Initial directory scan in under 200ms
253
+ - Responsive to user input immediately
254
+
255
+ ## 4. Event Handling
256
+
257
+ ### 4.1 Keyboard Shortcuts
258
+
259
+ #### 4.1.1 Navigation Shortcuts
260
+
261
+ | Key | Action |
262
+ |-----|--------|
263
+ | `↑` / `k` | Move selection up |
264
+ | `↓` / `j` | Move selection down |
265
+ | `←` / `h` | Collapse directory or move to parent |
266
+ | `→` / `l` | Expand directory or enter directory |
267
+ | `PgUp` | Page up |
268
+ | `PgDn` | Page down |
269
+ | `Home` / `g` | Jump to first item |
270
+ | `End` / `G` | Jump to last item |
271
+ | `Backspace` | Go to parent directory |
272
+ | `~` | Go to home directory |
273
+ | `/` | Go to root directory |
274
+ | `Tab` | Switch focus between panes |
275
+
276
+ #### 4.1.2 Operation Shortcuts
277
+
278
+ | Key | Action |
279
+ |-----|--------|
280
+ | `Enter` | Open file in editor or enter directory |
281
+ | `Space` | Toggle preview pane |
282
+ | `n` | Create new directory |
283
+ | `r` | Rename selected item |
284
+ | `d` | Delete selected item |
285
+ | `c` | Copy selected item |
286
+ | `m` | Move selected item |
287
+ | `e` | Open in external editor |
288
+ | `f` | Filter by name |
289
+ | `.` | Toggle hidden files |
290
+ | `s` | Cycle sort options |
291
+ | `R` | Refresh current view |
292
+ | `?` | Show help overlay |
293
+ | `q` / `Ctrl+C` | Quit application |
294
+
295
+ #### 4.1.3 Preview Pane Shortcuts (when focused)
296
+
297
+ | Key | Action |
298
+ |-----|--------|
299
+ | `↑` / `k` | Scroll preview up |
300
+ | `↓` / `j` | Scroll preview down |
301
+ | `PgUp` | Page up in preview |
302
+ | `PgDn` | Page down in preview |
303
+ | `Home` / `g` | Jump to top of preview |
304
+ | `End` / `G` | Jump to bottom of preview |
305
+
306
+ ### 4.2 Mouse Events
307
+
308
+ The application provides optional mouse support for users whose terminals support mouse events. All functionality remains fully accessible via keyboard.
309
+
310
+ **EV-MOUSE-001: Pane Focus**
311
+ - User can click on a pane to focus it
312
+ - Visual feedback indicates which pane has focus
313
+ - Click events do not interfere with terminal text selection
314
+
315
+ **EV-MOUSE-002: Item Selection**
316
+ - User can click on an item in the file list to select it
317
+ - User can click on a directory in the tree to select it
318
+ - Selected item is highlighted immediately
319
+ - Preview updates to show selected item
320
+
321
+ **EV-MOUSE-003: Directory Expansion**
322
+ - User can click on expand/collapse indicator (▶/▼) to toggle directory
323
+ - User can double-click on directory name to expand/collapse
324
+ - Visual feedback shows expansion state change
325
+
326
+ **EV-MOUSE-004: Scrolling**
327
+ - User can scroll with mouse wheel in any pane
328
+ - Scroll wheel moves selection in file list and tree
329
+ - Scroll wheel scrolls content in preview pane
330
+ - Scroll speed is configurable (default: 3 lines per wheel event)
331
+
332
+ **EV-MOUSE-005: Button Actions**
333
+ - User can click on buttons in dialogs (Yes/No, OK/Cancel)
334
+ - Hover state provides visual feedback
335
+ - Click activates button action
336
+
337
+ **EV-MOUSE-006: Drag and Drop (Future Enhancement)**
338
+ - Explicitly deferred to future version
339
+ - Would enable drag files to move/copy between directories
340
+
341
+ ### 4.3 Responsive Design with Resize Events
342
+
343
+ The application must gracefully handle terminal resize events and adapt the layout dynamically.
344
+
345
+ **EV-RESIZE-001: Minimum Size Handling**
346
+ - Application must function at minimum terminal size of 80x24
347
+ - If terminal is smaller, display warning message
348
+ - Suggest increasing terminal size for optimal experience
349
+ - Allow user to continue at their own risk
350
+
351
+ **EV-RESIZE-002: Dynamic Layout Adjustment**
352
+ - Pane widths adjust proportionally when terminal width changes
353
+ - Pane heights adjust proportionally when terminal height changes
354
+ - Maintain 25% / 40% / 35% ratio for panes when possible
355
+ - Status bar and title bar always visible
356
+
357
+ **EV-RESIZE-003: Content Reflow**
358
+ - File list reflows to fit new width
359
+ - Preview content reflows to fit new width
360
+ - Long filenames truncate with ellipsis (...) when space limited
361
+ - Column headers adjust to available space
362
+
363
+ **EV-RESIZE-004: Graceful Degradation**
364
+ - At narrow widths (< 120 columns), hide preview pane automatically
365
+ - At very narrow widths (< 80 columns), hide tree pane
366
+ - Display single-pane file list as fallback
367
+ - Restore panes when terminal size increases
368
+
369
+ **EV-RESIZE-005: Preserve State**
370
+ - Current selection remains selected after resize
371
+ - Scroll position maintained when possible
372
+ - Expanded directories remain expanded
373
+ - Active pane focus preserved
374
+
375
+ **EV-RESIZE-006: Performance**
376
+ - Resize events processed within 50ms
377
+ - No flickering or visual artifacts during resize
378
+ - Smooth transition between layout states
379
+ - Debounce rapid resize events (100ms window)
380
+
381
+ **EV-RESIZE-007: Orientation Changes**
382
+ - Handle extreme aspect ratios (very wide or very tall)
383
+ - Adjust pane layout for optimal readability
384
+ - Maintain usability across all reasonable terminal sizes
385
+ - Test with common terminal sizes: 80x24, 120x40, 200x60, 300x100
386
+
387
+
388
+ ## 5. Data Requirements
389
+
390
+ ### 5.1 File Metadata
391
+
392
+ For each file/directory, the application must track:
393
+ - Full path
394
+ - Name
395
+ - Type (file, directory, symlink)
396
+ - Size (bytes)
397
+ - Modification timestamp
398
+ - Permissions (read/write/execute)
399
+ - Hidden status (name starts with .)
400
+
401
+ ### 5.2 Application State
402
+
403
+ The application must maintain:
404
+ - Current working directory
405
+ - Selected item in file list
406
+ - Expanded directories in tree view
407
+ - Current sort order
408
+ - Current filter pattern
409
+ - Hidden files visibility preference
410
+ - Active pane focus
411
+ - Preview scroll position
412
+
413
+ ### 5.3 Configuration
414
+
415
+ User preferences (future enhancement):
416
+ - Default sort order
417
+ - Default hidden files visibility
418
+ - Color scheme preference
419
+ - Preview pane default state (visible/hidden)
420
+ - Default editor command
421
+
422
+ ## 6. Non-Functional Requirements
423
+
424
+ ### 6.1 Performance
425
+
426
+ - **Response Time:** All keyboard interactions must respond within 50ms
427
+ - **Startup Time:** Application must launch in under 500ms
428
+ - **Memory Usage:** Must not exceed 50MB for typical usage (1,000 files)
429
+ - **CPU Usage:** Must not exceed 5% CPU during idle state
430
+
431
+ ### 6.2 Reliability
432
+
433
+ - **Error Recovery:** Application must not crash on invalid input
434
+ - **Data Integrity:** File operations must be atomic (complete or rollback)
435
+ - **Graceful Degradation:** Continue functioning when individual operations fail
436
+
437
+ ### 6.3 Usability
438
+
439
+ - **Learnability:** New users should accomplish basic navigation within 2 minutes
440
+ - **Efficiency:** Expert users should navigate faster than GUI file browsers
441
+ - **Error Prevention:** Confirm destructive operations before execution
442
+ - **Help Accessibility:** Help overlay accessible via single keystroke
443
+
444
+ ### 6.4 Compatibility
445
+
446
+ - **Terminal Support:** Must work on any terminal supporting ANSI escape codes
447
+ - **Operating Systems:** Must work on macOS, Linux, and BSD systems
448
+ - **Ruby Version:** Must work on Ruby 3.0 or newer
449
+ - **Terminal Size:** Must adapt to terminal sizes from 80x24 to 300x100
450
+
451
+ ### 6.5 Maintainability
452
+
453
+ - **Code Quality:** All code must follow Ruby style guidelines
454
+ - **Test Coverage:** Minimum 80% test coverage for core functionality
455
+ - **Documentation:** All public interfaces must be documented
456
+ - **Error Messages:** All error messages must be actionable and specific
457
+
458
+ ## 7. User Scenarios
459
+
460
+ ### 7.1 Scenario: Quick File Lookup
461
+
462
+ **Actor:** Software Developer
463
+ **Goal:** Find and open a specific file in a project
464
+
465
+ **Steps:**
466
+ 1. Launch file browser in project directory
467
+ 2. Use filter to narrow down files by name
468
+ 3. Navigate to matching file
469
+ 4. Press Enter to open in editor
470
+ 5. Edit file and save
471
+ 6. Return to file browser (auto-refreshed)
472
+
473
+ **Expected Outcome:** File located and opened in under 10 seconds
474
+
475
+ ### 7.2 Scenario: Directory Cleanup
476
+
477
+ **Actor:** System Administrator
478
+ **Goal:** Remove old log files from a directory
479
+
480
+ **Steps:**
481
+ 1. Navigate to log directory
482
+ 2. Sort by modification date (oldest first)
483
+ 3. Review old files in preview pane
484
+ 4. Select and delete obsolete files
485
+ 5. Confirm each deletion
486
+ 6. Verify cleanup in refreshed view
487
+
488
+ **Expected Outcome:** Safe, confirmed deletion of unwanted files
489
+
490
+ ### 7.3 Scenario: Project Organization
491
+
492
+ **Actor:** Developer
493
+ **Goal:** Reorganize project files into new directory structure
494
+
495
+ **Steps:**
496
+ 1. Create new directories for organization
497
+ 2. Move files into appropriate directories
498
+ 3. Rename files for consistency
499
+ 4. Verify structure in tree view
500
+ 5. Confirm all files moved correctly
501
+
502
+ **Expected Outcome:** Reorganized project with clear structure
503
+
504
+ ### 7.4 Scenario: File Investigation
505
+
506
+ **Actor:** DevOps Engineer
507
+ **Goal:** Investigate which files changed recently
508
+
509
+ **Steps:**
510
+ 1. Navigate to application directory
511
+ 2. Sort by modification date (newest first)
512
+ 3. Preview recently modified files
513
+ 4. Identify unexpected changes
514
+ 5. Open suspicious files in editor for review
515
+
516
+ **Expected Outcome:** Quick identification of recent file changes
517
+
518
+ ## 8. Success Criteria
519
+
520
+ The File Browser application will be considered successful when:
521
+
522
+ 1. **Adoption:** Users choose it over `ls`, `cd`, and GUI file browsers for daily work
523
+ 2. **Efficiency:** Users navigate filesystems 2x faster than with traditional CLI commands
524
+ 3. **Reliability:** Zero data loss incidents in production use
525
+ 4. **Satisfaction:** 90% of users rate the experience as "good" or "excellent"
526
+ 5. **Performance:** Maintains responsive UI with directories containing 10,000+ files
527
+
528
+ ## 9. Future Enhancements
529
+
530
+ The following features are explicitly deferred to future versions:
531
+
532
+ - Bookmarks/favorites for frequently accessed directories
533
+ - Multi-file selection and batch operations
534
+ - File content search (grep integration)
535
+ - Git integration (show file status)
536
+ - Trash/recycle bin instead of permanent deletion
537
+ - Configurable keyboard shortcuts
538
+ - Themes and color scheme customization
539
+ - Dual-pane mode for easier file copying
540
+ - Archive preview (zip, tar, etc.)
541
+ - Image preview (ASCII art representation)
542
+ - File type icons and custom colors
543
+ - Integration with external tools (diff, etc.)
544
+
545
+ ## 10. Appendix
546
+
547
+ ### 10.1 Terminology
548
+
549
+ - **Pane:** A distinct rectangular region of the interface
550
+ - **Focus:** The currently active pane that receives keyboard input
551
+ - **Selection:** The currently highlighted item in a list
552
+ - **Preview:** Read-only display of file contents
553
+ - **Filter:** Temporary reduction of visible items based on criteria
554
+ - **Sort:** Reordering of items based on a property
555
+
556
+ ### 10.2 References
557
+
558
+ - IBM Common User Access (CUA) Guidelines
559
+ - Modern TUI Design Patterns (lazygit, btop, gh-dash)
560
+ - Ruby Standard Library: Pathname, File, Dir
561
+ - Terminal Capabilities: ANSI escape codes, box-drawing characters
562
+
563
+ ### 10.3 Revision History
564
+
565
+ | Version | Date | Author | Changes |
566
+ |---------|------|--------|---------|
567
+ | 1.0 | 2026-01-22 | Business Analysis Team | Initial specification |
568
+
569
+ ### 10.4 Screenshots
570
+
571
+ #### Default View - Directory Listing
572
+
573
+ ```
574
+ ┌─ File Browser ──────────────────────────────────────────────────────────────────────┐
575
+ │ ~/projects/myapp ? for help │
576
+ ├──────────────────────┬────────────────────────────────┬────────────────────────────┤
577
+ │ Directory Tree │ Files │ Preview │
578
+ │ │ │ │
579
+ │ 📁 myapp │ Name Size Modified │ README.md │
580
+ │ ├─ 📁 app │ ──────────────────────────────│ │
581
+ │ │ ├─ 📁 models │ .. - - │ # My Application │
582
+ │ │ ├─ 📁 views │ 📁 app - 2024-01-15│ │
583
+ │ │ └─ 📁 controllers │ 📁 config - 2024-01-10│ A sample application │
584
+ │ ├─ 📁 config │ 📁 lib - 2024-01-12│ demonstrating the file │
585
+ │ ├─ 📁 lib │ 📁 test - 2024-01-20│ browser capabilities. │
586
+ │ ├─ 📁 test │ 📄 Gemfile 1.2KB 2024-01-18│ │
587
+ │ ├─ 📄 Gemfile │ 📄 README.md 3.4KB 2024-01-22│ ## Features │
588
+ │ ├─ 📄 README.md │ 📄 Rakefile 856B 2024-01-10│ │
589
+ │ └─ 📄 Rakefile │ │ - Fast navigation │
590
+ │ │ │ - File preview │
591
+ │ │ │ - Search and filter │
592
+ │ │ │ │
593
+ │ │ │ │
594
+ │ │ │ │
595
+ │ │ │ │
596
+ ├──────────────────────┴────────────────────────────────┴────────────────────────────┤
597
+ │ ~/projects/myapp │ 8 items (5 dirs, 3 files) │ README.md - 3.4KB │
598
+ └──────────────────────────────────────────────────────────────────────────────────────┘
599
+ ```
600
+
601
+ #### File Preview - Source Code
602
+
603
+ ```
604
+ ┌─ File Browser ──────────────────────────────────────────────────────────────────────┐
605
+ │ ~/projects/myapp/app/models ? for help │
606
+ ├──────────────────────┬────────────────────────────────┬────────────────────────────┤
607
+ │ Directory Tree │ Files │ Preview │
608
+ │ │ │ │
609
+ │ 📁 myapp │ Name Size Modified │ user.rb │
610
+ │ ├─ 📁 app │ ──────────────────────────────│ │
611
+ │ │ ├─ 📁 models ▼ │ .. - - │ class User │
612
+ │ │ │ ├─ 📄 user.rb │ 📄 user.rb 2.1KB 2024-01-20│ include ActiveModel::... │
613
+ │ │ │ └─ 📄 post.rb │ 📄 post.rb 1.8KB 2024-01-19│ │
614
+ │ │ ├─ 📁 views │ │ attr_accessor :name, ... │
615
+ │ │ └─ 📁 controllers │ │ │
616
+ │ ├─ 📁 config │ │ validates :name, │
617
+ │ ├─ 📁 lib │ │ presence: true │
618
+ │ ├─ 📁 test │ │ │
619
+ │ ├─ 📄 Gemfile │ │ validates :email, │
620
+ │ ├─ 📄 README.md │ │ presence: true, │
621
+ │ └─ 📄 Rakefile │ │ format: { with: URI... │
622
+ │ │ │ │
623
+ │ │ │ def full_name │
624
+ │ │ │ "#{first_name} #{la... │
625
+ │ │ │ end │
626
+ │ │ │ end │
627
+ ├──────────────────────┴────────────────────────────────┴────────────────────────────┤
628
+ │ ~/projects/myapp/app/models │ 2 items │ user.rb - 2.1KB - 45 lines │
629
+ └──────────────────────────────────────────────────────────────────────────────────────┘
630
+ ```
631
+
632
+ #### Filter Active - Searching for Files
633
+
634
+ ```
635
+ ┌─ File Browser ──────────────────────────────────────────────────────────────────────┐
636
+ │ ~/projects/myapp ? for help │
637
+ ├──────────────────────┬────────────────────────────────┬────────────────────────────┤
638
+ │ Directory Tree │ Files (filter: *test*) │ Preview │
639
+ │ │ │ │
640
+ │ 📁 myapp │ Name Size Modified│ user_test.rb │
641
+ │ ├─ 📁 app │ ──────────────────────────────│ │
642
+ │ ├─ 📁 config │ 📁 test - 2024-..│ require 'test_helper' │
643
+ │ ├─ 📁 lib │ 📄 user_test.rb 1.5KB 2024-..│ │
644
+ │ ├─ 📁 test ▼ │ 📄 post_test.rb 1.2KB 2024-..│ class UserTest < Minite... │
645
+ │ │ ├─ 📄 test_help.. │ 📄 test_helper.rb 892B 2024-..│ def test_valid_user │
646
+ │ │ ├─ 📄 user_test.. │ │ user = User.new( │
647
+ │ │ └─ 📄 post_test.. │ │ name: "John Doe", │
648
+ │ ├─ 📄 Gemfile │ │ email: "john@exa... │
649
+ │ ├─ 📄 README.md │ │ ) │
650
+ │ └─ 📄 Rakefile │ │ assert user.valid? │
651
+ │ │ │ end │
652
+ │ │ │ │
653
+ │ │ │ def test_invalid_wit... │
654
+ │ │ │ user = User.new │
655
+ │ │ │ refute user.valid? │
656
+ │ │ │ end │
657
+ │ │ │ end │
658
+ ├──────────────────────┴────────────────────────────────┴────────────────────────────┤
659
+ │ Filter: *test* │ 3 matches │ Press Esc to clear filter │
660
+ └──────────────────────────────────────────────────────────────────────────────────────┘
661
+ ```
662
+
663
+ #### Delete Confirmation Dialog
664
+
665
+ ```
666
+ ┌─ File Browser ──────────────────────────────────────────────────────────────────────┐
667
+ │ ~/projects/myapp/test ? for help │
668
+ ├──────────────────────┬────────────────────────────────┬────────────────────────────┤
669
+ │ Directory Tree │ Files │ Preview │
670
+ │ │ │ │
671
+ │ 📁 myapp │ Name Size Modified│ old_test.rb │
672
+ │ ├─ 📁 app │ ──────────────────────────────│ │
673
+ │ ├─ 📁 config │ .. - - │ # Deprecated test file │
674
+ │ ├─ 📁 lib │ 📄 test_helper.rb 892B 2024-..│ # TODO: Remove this │
675
+ │ ├─ 📁 test ▼ │ 📄 user_test.rb 1.5KB 2024-..│ │
676
+ │ │ ├─ 📄 test_help.. │ 📄 post_test.rb 1.2KB 2024-..│ │
677
+ │ │ ├─ 📄 user_test.. │ 📄 old_test.rb 456B 2023-..│ │
678
+ │ │ ├─ 📄 post_test.. │ ┌────────────────────────┐ │ │
679
+ │ │ └─ 📄 old_test.rb │ │ Delete File? │ │ │
680
+ │ ├─ 📄 Gemfile │ │ │ │ │
681
+ │ ├─ 📄 README.md │ │ old_test.rb (456B) │ │ │
682
+ │ └─ 📄 Rakefile │ │ │ │ │
683
+ │ │ │ This cannot be undone. │ │ │
684
+ │ │ │ │ │ │
685
+ │ │ │ [Y] Yes [N] No │ │ │
686
+ │ │ └────────────────────────┘ │ │
687
+ │ │ │ │
688
+ ├──────────────────────┴────────────────────────────────┴────────────────────────────┤
689
+ │ ~/projects/myapp/test │ 4 items │ old_test.rb - 456B │
690
+ └──────────────────────────────────────────────────────────────────────────────────────┘
691
+ ```
692
+
693
+ #### Help Overlay
694
+
695
+ ```
696
+ ┌─ File Browser ──────────────────────────────────────────────────────────────────────┐
697
+ │ ~/projects/myapp ? for help │
698
+ ├──────────────────────┬────────────────────────────────┬────────────────────────────┤
699
+ │ Directory Tree │ ┌─ Keyboard Shortcuts ───────┐│ Preview │
700
+ │ │ │ ││ │
701
+ │ 📁 myapp │ │ Navigation: ││ README.md │
702
+ │ ├─ 📁 app │ │ ↑/k Move up ││ │
703
+ │ ├─ 📁 config │ │ ↓/j Move down ││ # My Application │
704
+ │ ├─ 📁 lib │ │ ←/h Collapse/parent ││ │
705
+ │ ├─ 📁 test │ │ →/l Expand/enter ││ A sample application │
706
+ │ ├─ 📄 Gemfile │ │ PgUp/Dn Page up/down ││ demonstrating the file │
707
+ │ ├─ 📄 README.md │ │ Home/g First item ││ browser capabilities. │
708
+ │ └─ 📄 Rakefile │ │ End/G Last item ││ │
709
+ │ │ │ Tab Switch pane ││ ## Features │
710
+ │ │ │ ││ │
711
+ │ │ │ Operations: ││ - Fast navigation │
712
+ │ │ │ Enter Open/enter ││ - File preview │
713
+ │ │ │ n New directory ││ - Search and filter │
714
+ │ │ │ r Rename ││ │
715
+ │ │ │ d Delete ││ │
716
+ │ │ │ c Copy ││ │
717
+ │ │ │ m Move ││ │
718
+ │ │ │ e Edit in $EDITOR ││ │
719
+ │ │ │ f Filter ││ │
720
+ │ │ │ . Toggle hidden ││ │
721
+ │ │ │ s Sort options ││ │
722
+ │ │ │ R Refresh ││ │
723
+ │ │ │ q/Ctrl+C Quit ││ │
724
+ │ │ │ ││ │
725
+ │ │ │ Press any key to close... ││ │
726
+ │ │ └─────────────────────────────┘│ │
727
+ ├──────────────────────┴────────────────────────────────┴────────────────────────────┤
728
+ │ ~/projects/myapp │ 8 items (5 dirs, 3 files) │ README.md - 3.4KB │
729
+ └──────────────────────────────────────────────────────────────────────────────────────┘
730
+ ```
731
+
732
+ #### Error State - Permission Denied
733
+
734
+ ```
735
+ ┌─ File Browser ──────────────────────────────────────────────────────────────────────┐
736
+ │ ~/restricted ? for help │
737
+ ├──────────────────────┬────────────────────────────────┬────────────────────────────┤
738
+ │ Directory Tree │ Files │ Preview │
739
+ │ │ │ │
740
+ │ 📁 home │ Name Size Modified │ │
741
+ │ ├─ 📁 user │ ──────────────────────────────│ │
742
+ │ ├─ 📁 restricted ▼ │ .. - - │ │
743
+ │ │ └─ 📁 secret │ 📁 secret - - │ │
744
+ │ └─ 📁 public │ │ │
745
+ │ │ │ │
746
+ │ │ │ │
747
+ │ │ │ │
748
+ │ │ │ │
749
+ │ │ │ │
750
+ │ │ │ │
751
+ │ │ │ │
752
+ │ │ │ │
753
+ │ │ │ │
754
+ │ │ │ │
755
+ │ │ │ │
756
+ ├──────────────────────┴────────────────────────────────┴────────────────────────────┤
757
+ │ ⚠ Error: Permission denied - Cannot read directory /restricted/secret │
758
+ └──────────────────────────────────────────────────────────────────────────────────────┘
759
+ ```
760
+
761
+ #### Loading State - Large Directory
762
+
763
+ ```
764
+ ┌─ File Browser ──────────────────────────────────────────────────────────────────────┐
765
+ │ ~/large-project/node_modules ? for help │
766
+ ├──────────────────────┬────────────────────────────────┬────────────────────────────┤
767
+ │ Directory Tree │ Files │ Preview │
768
+ │ │ │ │
769
+ │ 📁 large-project │ Name Size Modified │ │
770
+ │ ├─ 📁 src │ ──────────────────────────────│ │
771
+ │ ├─ 📁 node_modules ▼ │ .. - - │ │
772
+ │ │ ├─ 📁 @babel │ │ │
773
+ │ │ ├─ 📁 @types │ Loading directory... │ │
774
+ │ │ ├─ 📁 eslint │ │ │
775
+ │ │ └─ ... │ ⣾ 1,247 items found │ │
776
+ │ ├─ 📁 public │ │ │
777
+ │ ├─ 📄 package.json │ │ │
778
+ │ └─ 📄 README.md │ │ │
779
+ │ │ │ │
780
+ │ │ │ │
781
+ │ │ │ │
782
+ │ │ │ │
783
+ │ │ │ │
784
+ │ │ │ │
785
+ ├──────────────────────┴────────────────────────────────┴────────────────────────────┤
786
+ │ ~/large-project/node_modules │ Loading... │ Press Esc to cancel │
787
+ └──────────────────────────────────────────────────────────────────────────────────────┘
788
+ ```
789
+