markdown · 17050 bytes Raw Blame History

Workspace Mode Implementation Roadmap

Vision: Transform fac into a workspace-aware editor with persistent state and Fortress-based navigation.

Timeline: 7 phases, estimated 15-20 sessions total


Phase 0: Planning & Design

Duration: 1 session Objective: Document architecture and create foundational specs

Tasks

  • Define workspace data structures
  • Design .fac/ directory structure
  • Design ~/.config/fac/ structure
  • Create workspace.json schema
  • Create favorites.json schema
  • Document Fortress integration points
  • Plan module dependencies

Deliverables

docs/
  workspace_spec.md       # Workspace JSON format
  fortress_integration.md # How fortress modules integrate
  config_spec.md         # Config file formats

Files to Create

  • docs/workspace_spec.md
  • docs/fortress_integration.md
  • docs/config_spec.md

Success Criteria

  • ✅ Clear data structure specifications
  • ✅ Agreed-upon file formats
  • ✅ Module integration plan documented

Phase 1: Fortress Navigator Foundation

Duration: 3-4 sessions Objective: Build basic dual-pane file/directory navigator (Ctrl-O)

Tasks

  • Copy fortress filesystem modules into fac
    • src/fortress/filesystem/ (directory reading, path handling)
  • Copy fortress terminal modules
    • src/fortress/terminal/ (rendering utilities)
  • Adapt fortress UI for embedded mode
    • src/fortress/ui/ (dual-pane display, navigation)
  • Implement dual-pane rendering
    • Left pane: parent directory (30%)
    • Right pane: current directory (70%)
  • Add navigation keybindings
    • ↑/↓: Move cursor
    • →: Enter directory
    • ←: Go to parent
    • ~/: Jump to home/root
    • q: Cancel/exit
    • Enter: Select (return selection)
  • Add Ctrl-O keybinding to main editor
  • Modal Fortress UI (takes over screen, returns selection)

Files to Create

src/fortress/
  filesystem/
    directory_module.f90      # Read dirs, list files
    path_utils_module.f90     # Path manipulation
  terminal/
    fortress_render_module.f90 # Rendering utilities
  ui/
    dual_pane_module.f90      # Dual-pane display
    navigator_module.f90      # Main navigation logic

Files to Modify

  • src/commands/command_handler_module.f90 (add Ctrl-O handler)
  • Makefile (add fortress modules to build)

Success Criteria

  • ✅ Ctrl-O opens dual-pane navigator
  • ✅ Can navigate filesystem
  • ✅ Selecting directory returns path
  • ✅ Selecting file returns path
  • ✅ ESC/q cancels and returns to editor
  • ✅ Visual styling matches fac aesthetic

Testing Checkpoints

  • Navigate to various directories
  • Test with long file lists (scrolling)
  • Test with deep directory trees
  • Test cancellation (ESC)

Phase 2: Workspace Detection & Configuration

Duration: 2-3 sessions Objective: Detect workspace directories, create/load workspace configs

Tasks

  • Create workspace detection logic
    • Check for .fac/workspace.json in directory
    • Hash path for config file lookup
  • Implement workspace config directory structure
    ~/.config/fac/
      favorites.json
      recents.json
    .fac/                    # In workspace root
      workspace.json
      backups/
    
  • Create workspace module
    • workspace_init() - detect or create workspace
    • workspace_load() - load workspace.json
    • workspace_save() - save current state
    • workspace_exists() - check if path has workspace
  • Command line argument parsing
    • fac (no args) → open Fortress welcome menu
    • fac . → load/create workspace for cwd
    • fac /path/to/dir → load/create workspace
    • fac file.txt → check parent for workspace, else single-file mode
  • Create empty workspace with default state
  • Basic save/load (no tabs/panes yet, just metadata)

Files to Create

src/workspace/
  workspace_module.f90       # Core workspace logic
  workspace_config_module.f90 # JSON serialization
  workspace_detection_module.f90 # Path checking

Files to Modify

  • app/main.f90 (parse args, detect workspace mode)
  • src/editor_state_module.f90 (add workspace_path field)

Success Criteria

  • fac . creates .fac/workspace.json
  • fac /existing/workspace loads existing config
  • fac file.txt works as before (single-file mode)
  • fac (no args) opens Fortress welcome (placeholder for now)
  • ✅ Workspace state persists across runs

Testing Checkpoints

  • Create workspace in empty directory
  • Load existing workspace
  • Verify single-file mode unchanged
  • Check .fac/ directory creation

Phase 3: State Serialization (Tabs & Panes)

Duration: 3-4 sessions Objective: Persist and restore all editor state

Tasks

  • Design workspace.json schema
    {
      "version": "1.0",
      "workspace_path": "/home/user/project",
      "last_opened": "2025-01-05T10:30:00Z",
      "tabs": [
        {
          "label": "main.f90",
          "panes": [
            {
              "file": "src/main.f90",
              "cursor": {"line": 42, "col": 10},
              "viewport": {"line": 30, "col": 1},
              "modified": false
            }
          ],
          "split_type": "none|vertical|horizontal",
          "active_pane": 0
        }
      ],
      "orphan_tabs": [
        {
          "file": "/etc/hosts",
          "cursor": {"line": 1, "col": 1},
          "viewport": {"line": 1, "col": 1}
        }
      ],
      "active_tab": 0,
      "fuss_mode": {
        "active": true,
        "width": 30
      }
    }
    
  • Implement tab serialization
    • Serialize tab list, labels, active index
  • Implement pane serialization
    • Serialize pane splits, layout, active pane
  • Implement cursor/viewport serialization
    • Save position per file
  • Implement deserialization (reverse of above)
  • Add orphan tab tracking
    • Mark tabs as orphan vs workspace
    • Different color in tab bar (greyish)
  • Call save on quit
  • Call load on workspace open
  • Handle relative vs absolute paths
    • Store workspace files as relative paths
    • Store orphan files as absolute paths

Files to Create

src/workspace/
  tab_serializer_module.f90   # Tab state save/load
  pane_serializer_module.f90  # Pane state save/load

Files to Modify

  • src/workspace/workspace_module.f90 (save/load implementation)
  • src/editor_state_module.f90 (add orphan flag to tabs)
  • src/terminal/renderer_module.f90 (orphan tab color)
  • app/main.f90 (call save on quit, load on open)

Success Criteria

  • ✅ Quit fac with 3 tabs → reopen → 3 tabs restored
  • ✅ Split panes → quit → reopen → splits preserved
  • ✅ Cursor at line 50 → quit → reopen → cursor at line 50
  • ✅ Orphan tabs show in different color
  • ✅ Workspace files use relative paths
  • ✅ Orphan files use absolute paths

Testing Checkpoints

  • Create complex workspace (multiple tabs, splits)
  • Edit files, move cursors
  • Quit and reopen
  • Verify exact state restoration
  • Test orphan tab creation via Fortress

Phase 4: Backup System

Duration: 2 sessions Objective: Auto-backup dirty buffers, restore with diff option

Tasks

  • Create backup directory structure
    .fac/
      backups/
        main.f90.bak
        test.f90.bak
        .backup-metadata.json
    
  • Implement backup on quit
    • Detect modified buffers
    • Prompt per file: "Save main.f90? [y/n/c]"
    • If 'n', create backup file
    • Write backup with timestamp in metadata
  • Implement backup detection on open
    • Check for backup files in .fac/backups/
    • Compare timestamps (backup vs disk file)
  • Implement restore prompt
    • For each backup: "[r]estore / [i]gnore / [d]iff?"
    • 'd' shows diff (use system diff or built-in)
  • Implement diff viewer
    • Simple side-by-side or unified diff
    • Or shell out to diff command
  • Backup cleanup
    • Delete backup after successful restore
    • Or keep for N days (config option)

Files to Create

src/workspace/
  backup_module.f90          # Backup creation/restoration
  diff_viewer_module.f90     # Simple diff display (optional)

Files to Modify

  • src/workspace/workspace_module.f90 (backup on quit/load)
  • app/main.f90 (call backup logic)

Success Criteria

  • ✅ Quit with unsaved file → prompted to save
  • ✅ Choose 'n' → backup created
  • ✅ Reopen workspace → prompted to restore backup
  • ✅ 'd' shows diff between backup and disk
  • ✅ 'r' restores backup
  • ✅ 'i' ignores backup
  • ✅ Metadata tracks backup timestamps

Testing Checkpoints

  • Edit file, don't save, quit
  • Verify backup created
  • Modify file on disk (external editor)
  • Reopen workspace
  • Verify diff shows both changes
  • Test restore, test ignore

Phase 5: Favorites & Recents

Duration: 2 sessions Objective: Track favorite/recent workspaces, Fortress welcome menu

Tasks

  • Create favorites system
    ~/.config/fac/
      favorites.json
        {
          "favorites": [
            {"path": "/home/user/project", "label": "My Project"},
            {"path": "/home/user/scripts", "label": "Scripts"}
          ]
        }
    
  • Create recents system
    ~/.config/fac/
      recents.json
        {
          "recents": [
            {"path": "/home/user/project", "last_opened": "2025-01-05T10:30:00Z"},
            {"path": "/home/user/other", "last_opened": "2025-01-04T09:15:00Z"}
          ]
        }
    
  • Update recents on workspace open
    • Add current workspace to recents
    • Keep most recent 10-20 entries
  • Implement Fortress welcome menu
    • Press '8' to toggle between favorites/recents view
    • Two separate panes/dialogs
    • Favorites pane: list favorites, keybind to add/remove ('f')
    • Recents pane: list by most recent first
    • Navigate with ↑/↓, Enter to select
  • Implement fac (no args) behavior
    • Launch Fortress welcome menu
    • Select favorite/recent → load workspace
    • Or navigate filesystem to find new workspace
  • Add keybind in Fortress to add current dir to favorites ('f')
  • Add keybind to remove favorite ('r' or 'x')

Files to Create

src/workspace/
  favorites_module.f90       # Manage favorites
  recents_module.f90         # Manage recents
src/fortress/ui/
  welcome_menu_module.f90    # Favorites/recents display

Files to Modify

  • src/fortress/ui/navigator_module.f90 (add '8' toggle, 'f' favorite)
  • src/workspace/workspace_module.f90 (update recents on open)
  • app/main.f90 (no args → welcome menu)

Success Criteria

  • fac opens welcome menu with favorites/recents
  • ✅ Press '8' toggles between favorites and recents views
  • ✅ Selecting from list opens that workspace
  • ✅ 'f' in Fortress adds directory to favorites
  • ✅ Recents automatically updated on workspace open
  • ✅ Most recent workspaces appear first

Testing Checkpoints

  • Run fac with no args
  • Verify favorites/recents display
  • Add favorite, verify persists
  • Open workspace, verify appears in recents
  • Toggle between views with '8'

Phase 6: Workspace Switching & Integration

Duration: 2-3 sessions Objective: Connect all pieces, handle workspace switching

Tasks

  • Implement workspace switching flow
    • Ctrl-O in workspace → Fortress navigator
    • Select directory → save current workspace
    • Load new workspace (or create if new)
    • Restore tabs/panes/state
  • Handle orphan tab creation
    • Fortress select file → open in new tab
    • Mark tab as orphan
    • Style with grey/subtle color
    • Don't persist orphan tabs in workspace.json
    • OR persist in separate "orphan_tabs" array (decided in Phase 3)
  • Implement save prompts on switch
    • Before switching workspace
    • For each dirty buffer: "Save file? [y/n/c]"
    • 'c' cancels workspace switch
  • Handle edge cases
    • Missing files in workspace.json
      • Show warning: "File not found: src/missing.f90"
      • Skip that tab, continue loading others
    • Deleted workspace directory
      • Detect and remove from recents
    • Corrupted workspace.json
      • Fallback to empty workspace
      • Log error
  • Update file tree (Ctrl-B) for workspace mode
    • Show workspace root (not parent of first file)
    • Update tree when switching workspaces

Files to Modify

  • src/fortress/ui/navigator_module.f90 (return file vs dir)
  • src/workspace/workspace_module.f90 (switch logic)
  • src/commands/command_handler_module.f90 (Ctrl-O handler)
  • src/workspace/file_tree_module.f90 (workspace root)
  • app/main.f90 (orchestrate switching)

Success Criteria

  • ✅ Ctrl-O from workspace opens Fortress
  • ✅ Selecting new directory switches workspace
  • ✅ Current workspace saved before switch
  • ✅ New workspace loaded with all state
  • ✅ Dirty buffers prompt to save before switch
  • ✅ Orphan tabs work correctly
  • ✅ Missing files handled gracefully
  • ✅ File tree shows workspace root

Testing Checkpoints

  • Create two workspaces with different files
  • Switch between them via Fortress
  • Verify state saves/loads correctly
  • Test with dirty buffers
  • Test missing file handling

Phase 7: Polish, Testing & Documentation

Duration: 2 sessions Objective: Bug fixes, edge cases, user testing

Tasks

  • Performance optimization
    • Large workspaces (100+ files)
    • Deep directory trees in Fortress
  • Visual polish
    • Orphan tab color (grey/subtle)
    • Fortress UI styling
    • Welcome menu appearance
  • Error handling
    • Permissions errors
    • Disk full
    • Invalid JSON
  • Edge case testing
    • Symlinks in workspace
    • Very long file paths
    • Unicode in filenames/paths
    • Binary files in backups
  • Documentation
    • Update README.md
    • Update --help output
    • Create WORKSPACE.md guide
    • Add examples
  • User testing
    • Real-world projects
    • Multiple sessions
    • Collect feedback
  • Fix any cursor/rendering bugs that emerge
  • Remove debug logging

Files to Create

  • WORKSPACE.md (user guide)

Files to Modify

  • README.md (document workspace features)
  • app/main.f90 (update --help)

Success Criteria

  • ✅ All features working smoothly
  • ✅ No regressions in existing features
  • ✅ Performance acceptable on large projects
  • ✅ Documentation complete
  • ✅ Ready for release

Testing Checkpoints

  • Test with Linux kernel source (large workspace)
  • Test with multiple nested directories
  • Test workspace switching under load
  • Test all edge cases
  • User acceptance testing

Module Dependency Graph

app/main.f90
  ├── workspace_module.f90
  │   ├── workspace_config_module.f90
  │   ├── workspace_detection_module.f90
  │   ├── tab_serializer_module.f90
  │   ├── pane_serializer_module.f90
  │   ├── backup_module.f90
  │   ├── favorites_module.f90
  │   └── recents_module.f90
  │
  └── fortress/
      ├── filesystem/
      │   ├── directory_module.f90
      │   └── path_utils_module.f90
      ├── terminal/
      │   └── fortress_render_module.f90
      └── ui/
          ├── dual_pane_module.f90
          ├── navigator_module.f90
          └── welcome_menu_module.f90

Risk Mitigation

Cursor/Rendering Bugs

Risk: New pane/tab logic breaks cursor positioning Mitigation:

  • Test after each phase
  • Keep parity tests from current build
  • Incremental changes, test often

State Corruption

Risk: Corrupted workspace.json breaks workspace Mitigation:

  • JSON validation on load
  • Fallback to empty workspace
  • Keep backup of last-good workspace.json

Performance

Risk: Large workspaces slow down editor Mitigation:

  • Lazy load tabs (don't load all buffers at once)
  • Profile and optimize
  • Set reasonable limits (e.g., max 50 tabs)

Backwards Compatibility

Risk: Breaking existing fac usage Mitigation:

  • Single-file mode must work unchanged
  • Feature flags during development
  • Extensive testing of non-workspace mode

Success Metrics

Phase Completion:

  • All tasks in phase completed
  • Success criteria met
  • Tests passing
  • No regressions

Overall Success:

  • fac launches welcome menu
  • fac . creates/loads workspace
  • Ctrl-O navigates to workspaces/files
  • Tabs/panes/cursors persist across sessions
  • Orphan tabs work as expected
  • Favorites/recents work
  • Backups restore correctly
  • Documentation complete
  • No bugs in existing features

Timeline Estimate

  • Phase 0: 1 session (4-6 hours)
  • Phase 1: 3-4 sessions (12-16 hours)
  • Phase 2: 2-3 sessions (8-12 hours)
  • Phase 3: 3-4 sessions (12-16 hours)
  • Phase 4: 2 sessions (8-10 hours)
  • Phase 5: 2 sessions (8-10 hours)
  • Phase 6: 2-3 sessions (8-12 hours)
  • Phase 7: 2 sessions (8-10 hours)

Total: ~15-20 sessions (~60-80 hours)


Next Steps

  1. Review this roadmap
  2. Make any adjustments
  3. Begin Phase 0 (Planning & Design)
  4. Create specification documents
  5. Start Phase 1 (Fortress Navigator)

Ready to proceed? 🚀

View source
1 # Workspace Mode Implementation Roadmap
2
3 **Vision**: Transform fac into a workspace-aware editor with persistent state and Fortress-based navigation.
4
5 **Timeline**: 7 phases, estimated 15-20 sessions total
6
7 ---
8
9 ## Phase 0: Planning & Design
10 **Duration**: 1 session
11 **Objective**: Document architecture and create foundational specs
12
13 ### Tasks
14 - [x] Define workspace data structures
15 - [ ] Design `.fac/` directory structure
16 - [ ] Design `~/.config/fac/` structure
17 - [ ] Create workspace.json schema
18 - [ ] Create favorites.json schema
19 - [ ] Document Fortress integration points
20 - [ ] Plan module dependencies
21
22 ### Deliverables
23 ```
24 docs/
25 workspace_spec.md # Workspace JSON format
26 fortress_integration.md # How fortress modules integrate
27 config_spec.md # Config file formats
28 ```
29
30 ### Files to Create
31 - `docs/workspace_spec.md`
32 - `docs/fortress_integration.md`
33 - `docs/config_spec.md`
34
35 ### Success Criteria
36 - ✅ Clear data structure specifications
37 - ✅ Agreed-upon file formats
38 - ✅ Module integration plan documented
39
40 ---
41
42 ## Phase 1: Fortress Navigator Foundation
43 **Duration**: 3-4 sessions
44 **Objective**: Build basic dual-pane file/directory navigator (Ctrl-O)
45
46 ### Tasks
47 - [ ] Copy fortress filesystem modules into fac
48 - `src/fortress/filesystem/` (directory reading, path handling)
49 - [ ] Copy fortress terminal modules
50 - `src/fortress/terminal/` (rendering utilities)
51 - [ ] Adapt fortress UI for embedded mode
52 - `src/fortress/ui/` (dual-pane display, navigation)
53 - [ ] Implement dual-pane rendering
54 - Left pane: parent directory (30%)
55 - Right pane: current directory (70%)
56 - [ ] Add navigation keybindings
57 - ↑/↓: Move cursor
58 - →: Enter directory
59 - ←: Go to parent
60 - ~/: Jump to home/root
61 - q: Cancel/exit
62 - Enter: Select (return selection)
63 - [ ] Add Ctrl-O keybinding to main editor
64 - [ ] Modal Fortress UI (takes over screen, returns selection)
65
66 ### Files to Create
67 ```
68 src/fortress/
69 filesystem/
70 directory_module.f90 # Read dirs, list files
71 path_utils_module.f90 # Path manipulation
72 terminal/
73 fortress_render_module.f90 # Rendering utilities
74 ui/
75 dual_pane_module.f90 # Dual-pane display
76 navigator_module.f90 # Main navigation logic
77 ```
78
79 ### Files to Modify
80 - `src/commands/command_handler_module.f90` (add Ctrl-O handler)
81 - `Makefile` (add fortress modules to build)
82
83 ### Success Criteria
84 - ✅ Ctrl-O opens dual-pane navigator
85 - ✅ Can navigate filesystem
86 - ✅ Selecting directory returns path
87 - ✅ Selecting file returns path
88 - ✅ ESC/q cancels and returns to editor
89 - ✅ Visual styling matches fac aesthetic
90
91 ### Testing Checkpoints
92 - Navigate to various directories
93 - Test with long file lists (scrolling)
94 - Test with deep directory trees
95 - Test cancellation (ESC)
96
97 ---
98
99 ## Phase 2: Workspace Detection & Configuration
100 **Duration**: 2-3 sessions
101 **Objective**: Detect workspace directories, create/load workspace configs
102
103 ### Tasks
104 - [ ] Create workspace detection logic
105 - Check for `.fac/workspace.json` in directory
106 - Hash path for config file lookup
107 - [ ] Implement workspace config directory structure
108 ```
109 ~/.config/fac/
110 favorites.json
111 recents.json
112 .fac/ # In workspace root
113 workspace.json
114 backups/
115 ```
116 - [ ] Create workspace module
117 - `workspace_init()` - detect or create workspace
118 - `workspace_load()` - load workspace.json
119 - `workspace_save()` - save current state
120 - `workspace_exists()` - check if path has workspace
121 - [ ] Command line argument parsing
122 - `fac` (no args) → open Fortress welcome menu
123 - `fac .` → load/create workspace for cwd
124 - `fac /path/to/dir` → load/create workspace
125 - `fac file.txt` → check parent for workspace, else single-file mode
126 - [ ] Create empty workspace with default state
127 - [ ] Basic save/load (no tabs/panes yet, just metadata)
128
129 ### Files to Create
130 ```
131 src/workspace/
132 workspace_module.f90 # Core workspace logic
133 workspace_config_module.f90 # JSON serialization
134 workspace_detection_module.f90 # Path checking
135 ```
136
137 ### Files to Modify
138 - `app/main.f90` (parse args, detect workspace mode)
139 - `src/editor_state_module.f90` (add workspace_path field)
140
141 ### Success Criteria
142 - ✅ `fac .` creates `.fac/workspace.json`
143 - ✅ `fac /existing/workspace` loads existing config
144 - ✅ `fac file.txt` works as before (single-file mode)
145 - ✅ `fac` (no args) opens Fortress welcome (placeholder for now)
146 - ✅ Workspace state persists across runs
147
148 ### Testing Checkpoints
149 - Create workspace in empty directory
150 - Load existing workspace
151 - Verify single-file mode unchanged
152 - Check `.fac/` directory creation
153
154 ---
155
156 ## Phase 3: State Serialization (Tabs & Panes)
157 **Duration**: 3-4 sessions
158 **Objective**: Persist and restore all editor state
159
160 ### Tasks
161 - [ ] Design workspace.json schema
162 ```json
163 {
164 "version": "1.0",
165 "workspace_path": "/home/user/project",
166 "last_opened": "2025-01-05T10:30:00Z",
167 "tabs": [
168 {
169 "label": "main.f90",
170 "panes": [
171 {
172 "file": "src/main.f90",
173 "cursor": {"line": 42, "col": 10},
174 "viewport": {"line": 30, "col": 1},
175 "modified": false
176 }
177 ],
178 "split_type": "none|vertical|horizontal",
179 "active_pane": 0
180 }
181 ],
182 "orphan_tabs": [
183 {
184 "file": "/etc/hosts",
185 "cursor": {"line": 1, "col": 1},
186 "viewport": {"line": 1, "col": 1}
187 }
188 ],
189 "active_tab": 0,
190 "fuss_mode": {
191 "active": true,
192 "width": 30
193 }
194 }
195 ```
196 - [ ] Implement tab serialization
197 - Serialize tab list, labels, active index
198 - [ ] Implement pane serialization
199 - Serialize pane splits, layout, active pane
200 - [ ] Implement cursor/viewport serialization
201 - Save position per file
202 - [ ] Implement deserialization (reverse of above)
203 - [ ] Add orphan tab tracking
204 - Mark tabs as orphan vs workspace
205 - Different color in tab bar (greyish)
206 - [ ] Call save on quit
207 - [ ] Call load on workspace open
208 - [ ] Handle relative vs absolute paths
209 - Store workspace files as relative paths
210 - Store orphan files as absolute paths
211
212 ### Files to Create
213 ```
214 src/workspace/
215 tab_serializer_module.f90 # Tab state save/load
216 pane_serializer_module.f90 # Pane state save/load
217 ```
218
219 ### Files to Modify
220 - `src/workspace/workspace_module.f90` (save/load implementation)
221 - `src/editor_state_module.f90` (add orphan flag to tabs)
222 - `src/terminal/renderer_module.f90` (orphan tab color)
223 - `app/main.f90` (call save on quit, load on open)
224
225 ### Success Criteria
226 - ✅ Quit fac with 3 tabs → reopen → 3 tabs restored
227 - ✅ Split panes → quit → reopen → splits preserved
228 - ✅ Cursor at line 50 → quit → reopen → cursor at line 50
229 - ✅ Orphan tabs show in different color
230 - ✅ Workspace files use relative paths
231 - ✅ Orphan files use absolute paths
232
233 ### Testing Checkpoints
234 - Create complex workspace (multiple tabs, splits)
235 - Edit files, move cursors
236 - Quit and reopen
237 - Verify exact state restoration
238 - Test orphan tab creation via Fortress
239
240 ---
241
242 ## Phase 4: Backup System
243 **Duration**: 2 sessions
244 **Objective**: Auto-backup dirty buffers, restore with diff option
245
246 ### Tasks
247 - [ ] Create backup directory structure
248 ```
249 .fac/
250 backups/
251 main.f90.bak
252 test.f90.bak
253 .backup-metadata.json
254 ```
255 - [ ] Implement backup on quit
256 - Detect modified buffers
257 - Prompt per file: "Save main.f90? [y/n/c]"
258 - If 'n', create backup file
259 - Write backup with timestamp in metadata
260 - [ ] Implement backup detection on open
261 - Check for backup files in `.fac/backups/`
262 - Compare timestamps (backup vs disk file)
263 - [ ] Implement restore prompt
264 - For each backup: "[r]estore / [i]gnore / [d]iff?"
265 - 'd' shows diff (use system diff or built-in)
266 - [ ] Implement diff viewer
267 - Simple side-by-side or unified diff
268 - Or shell out to `diff` command
269 - [ ] Backup cleanup
270 - Delete backup after successful restore
271 - Or keep for N days (config option)
272
273 ### Files to Create
274 ```
275 src/workspace/
276 backup_module.f90 # Backup creation/restoration
277 diff_viewer_module.f90 # Simple diff display (optional)
278 ```
279
280 ### Files to Modify
281 - `src/workspace/workspace_module.f90` (backup on quit/load)
282 - `app/main.f90` (call backup logic)
283
284 ### Success Criteria
285 - ✅ Quit with unsaved file → prompted to save
286 - ✅ Choose 'n' → backup created
287 - ✅ Reopen workspace → prompted to restore backup
288 - ✅ 'd' shows diff between backup and disk
289 - ✅ 'r' restores backup
290 - ✅ 'i' ignores backup
291 - ✅ Metadata tracks backup timestamps
292
293 ### Testing Checkpoints
294 - Edit file, don't save, quit
295 - Verify backup created
296 - Modify file on disk (external editor)
297 - Reopen workspace
298 - Verify diff shows both changes
299 - Test restore, test ignore
300
301 ---
302
303 ## Phase 5: Favorites & Recents
304 **Duration**: 2 sessions
305 **Objective**: Track favorite/recent workspaces, Fortress welcome menu
306
307 ### Tasks
308 - [ ] Create favorites system
309 ```
310 ~/.config/fac/
311 favorites.json
312 {
313 "favorites": [
314 {"path": "/home/user/project", "label": "My Project"},
315 {"path": "/home/user/scripts", "label": "Scripts"}
316 ]
317 }
318 ```
319 - [ ] Create recents system
320 ```
321 ~/.config/fac/
322 recents.json
323 {
324 "recents": [
325 {"path": "/home/user/project", "last_opened": "2025-01-05T10:30:00Z"},
326 {"path": "/home/user/other", "last_opened": "2025-01-04T09:15:00Z"}
327 ]
328 }
329 ```
330 - [ ] Update recents on workspace open
331 - Add current workspace to recents
332 - Keep most recent 10-20 entries
333 - [ ] Implement Fortress welcome menu
334 - Press '8' to toggle between favorites/recents view
335 - Two separate panes/dialogs
336 - Favorites pane: list favorites, keybind to add/remove ('f')
337 - Recents pane: list by most recent first
338 - Navigate with ↑/↓, Enter to select
339 - [ ] Implement `fac` (no args) behavior
340 - Launch Fortress welcome menu
341 - Select favorite/recent → load workspace
342 - Or navigate filesystem to find new workspace
343 - [ ] Add keybind in Fortress to add current dir to favorites ('f')
344 - [ ] Add keybind to remove favorite ('r' or 'x')
345
346 ### Files to Create
347 ```
348 src/workspace/
349 favorites_module.f90 # Manage favorites
350 recents_module.f90 # Manage recents
351 src/fortress/ui/
352 welcome_menu_module.f90 # Favorites/recents display
353 ```
354
355 ### Files to Modify
356 - `src/fortress/ui/navigator_module.f90` (add '8' toggle, 'f' favorite)
357 - `src/workspace/workspace_module.f90` (update recents on open)
358 - `app/main.f90` (no args → welcome menu)
359
360 ### Success Criteria
361 - ✅ `fac` opens welcome menu with favorites/recents
362 - ✅ Press '8' toggles between favorites and recents views
363 - ✅ Selecting from list opens that workspace
364 - ✅ 'f' in Fortress adds directory to favorites
365 - ✅ Recents automatically updated on workspace open
366 - ✅ Most recent workspaces appear first
367
368 ### Testing Checkpoints
369 - Run `fac` with no args
370 - Verify favorites/recents display
371 - Add favorite, verify persists
372 - Open workspace, verify appears in recents
373 - Toggle between views with '8'
374
375 ---
376
377 ## Phase 6: Workspace Switching & Integration
378 **Duration**: 2-3 sessions
379 **Objective**: Connect all pieces, handle workspace switching
380
381 ### Tasks
382 - [ ] Implement workspace switching flow
383 - Ctrl-O in workspace → Fortress navigator
384 - Select directory → save current workspace
385 - Load new workspace (or create if new)
386 - Restore tabs/panes/state
387 - [ ] Handle orphan tab creation
388 - Fortress select file → open in new tab
389 - Mark tab as orphan
390 - Style with grey/subtle color
391 - Don't persist orphan tabs in workspace.json
392 - OR persist in separate "orphan_tabs" array (decided in Phase 3)
393 - [ ] Implement save prompts on switch
394 - Before switching workspace
395 - For each dirty buffer: "Save file? [y/n/c]"
396 - 'c' cancels workspace switch
397 - [ ] Handle edge cases
398 - Missing files in workspace.json
399 - Show warning: "File not found: src/missing.f90"
400 - Skip that tab, continue loading others
401 - Deleted workspace directory
402 - Detect and remove from recents
403 - Corrupted workspace.json
404 - Fallback to empty workspace
405 - Log error
406 - [ ] Update file tree (Ctrl-B) for workspace mode
407 - Show workspace root (not parent of first file)
408 - Update tree when switching workspaces
409
410 ### Files to Modify
411 - `src/fortress/ui/navigator_module.f90` (return file vs dir)
412 - `src/workspace/workspace_module.f90` (switch logic)
413 - `src/commands/command_handler_module.f90` (Ctrl-O handler)
414 - `src/workspace/file_tree_module.f90` (workspace root)
415 - `app/main.f90` (orchestrate switching)
416
417 ### Success Criteria
418 - ✅ Ctrl-O from workspace opens Fortress
419 - ✅ Selecting new directory switches workspace
420 - ✅ Current workspace saved before switch
421 - ✅ New workspace loaded with all state
422 - ✅ Dirty buffers prompt to save before switch
423 - ✅ Orphan tabs work correctly
424 - ✅ Missing files handled gracefully
425 - ✅ File tree shows workspace root
426
427 ### Testing Checkpoints
428 - Create two workspaces with different files
429 - Switch between them via Fortress
430 - Verify state saves/loads correctly
431 - Test with dirty buffers
432 - Test missing file handling
433
434 ---
435
436 ## Phase 7: Polish, Testing & Documentation
437 **Duration**: 2 sessions
438 **Objective**: Bug fixes, edge cases, user testing
439
440 ### Tasks
441 - [ ] Performance optimization
442 - Large workspaces (100+ files)
443 - Deep directory trees in Fortress
444 - [ ] Visual polish
445 - Orphan tab color (grey/subtle)
446 - Fortress UI styling
447 - Welcome menu appearance
448 - [ ] Error handling
449 - Permissions errors
450 - Disk full
451 - Invalid JSON
452 - [ ] Edge case testing
453 - Symlinks in workspace
454 - Very long file paths
455 - Unicode in filenames/paths
456 - Binary files in backups
457 - [ ] Documentation
458 - Update README.md
459 - Update --help output
460 - Create WORKSPACE.md guide
461 - Add examples
462 - [ ] User testing
463 - Real-world projects
464 - Multiple sessions
465 - Collect feedback
466 - [ ] Fix any cursor/rendering bugs that emerge
467 - [ ] Remove debug logging
468
469 ### Files to Create
470 - `WORKSPACE.md` (user guide)
471
472 ### Files to Modify
473 - `README.md` (document workspace features)
474 - `app/main.f90` (update --help)
475
476 ### Success Criteria
477 - ✅ All features working smoothly
478 - ✅ No regressions in existing features
479 - ✅ Performance acceptable on large projects
480 - ✅ Documentation complete
481 - ✅ Ready for release
482
483 ### Testing Checkpoints
484 - Test with Linux kernel source (large workspace)
485 - Test with multiple nested directories
486 - Test workspace switching under load
487 - Test all edge cases
488 - User acceptance testing
489
490 ---
491
492 ## Module Dependency Graph
493
494 ```
495 app/main.f90
496 ├── workspace_module.f90
497 │ ├── workspace_config_module.f90
498 │ ├── workspace_detection_module.f90
499 │ ├── tab_serializer_module.f90
500 │ ├── pane_serializer_module.f90
501 │ ├── backup_module.f90
502 │ ├── favorites_module.f90
503 │ └── recents_module.f90
504
505 └── fortress/
506 ├── filesystem/
507 │ ├── directory_module.f90
508 │ └── path_utils_module.f90
509 ├── terminal/
510 │ └── fortress_render_module.f90
511 └── ui/
512 ├── dual_pane_module.f90
513 ├── navigator_module.f90
514 └── welcome_menu_module.f90
515 ```
516
517 ---
518
519 ## Risk Mitigation
520
521 ### Cursor/Rendering Bugs
522 **Risk**: New pane/tab logic breaks cursor positioning
523 **Mitigation**:
524 - Test after each phase
525 - Keep parity tests from current build
526 - Incremental changes, test often
527
528 ### State Corruption
529 **Risk**: Corrupted workspace.json breaks workspace
530 **Mitigation**:
531 - JSON validation on load
532 - Fallback to empty workspace
533 - Keep backup of last-good workspace.json
534
535 ### Performance
536 **Risk**: Large workspaces slow down editor
537 **Mitigation**:
538 - Lazy load tabs (don't load all buffers at once)
539 - Profile and optimize
540 - Set reasonable limits (e.g., max 50 tabs)
541
542 ### Backwards Compatibility
543 **Risk**: Breaking existing fac usage
544 **Mitigation**:
545 - Single-file mode must work unchanged
546 - Feature flags during development
547 - Extensive testing of non-workspace mode
548
549 ---
550
551 ## Success Metrics
552
553 **Phase Completion:**
554 - All tasks in phase completed
555 - Success criteria met
556 - Tests passing
557 - No regressions
558
559 **Overall Success:**
560 - `fac` launches welcome menu
561 - `fac .` creates/loads workspace
562 - Ctrl-O navigates to workspaces/files
563 - Tabs/panes/cursors persist across sessions
564 - Orphan tabs work as expected
565 - Favorites/recents work
566 - Backups restore correctly
567 - Documentation complete
568 - No bugs in existing features
569
570 ---
571
572 ## Timeline Estimate
573
574 - **Phase 0**: 1 session (4-6 hours)
575 - **Phase 1**: 3-4 sessions (12-16 hours)
576 - **Phase 2**: 2-3 sessions (8-12 hours)
577 - **Phase 3**: 3-4 sessions (12-16 hours)
578 - **Phase 4**: 2 sessions (8-10 hours)
579 - **Phase 5**: 2 sessions (8-10 hours)
580 - **Phase 6**: 2-3 sessions (8-12 hours)
581 - **Phase 7**: 2 sessions (8-10 hours)
582
583 **Total**: ~15-20 sessions (~60-80 hours)
584
585 ---
586
587 ## Next Steps
588
589 1. Review this roadmap
590 2. Make any adjustments
591 3. Begin Phase 0 (Planning & Design)
592 4. Create specification documents
593 5. Start Phase 1 (Fortress Navigator)
594
595 Ready to proceed? 🚀