docs(04-02): complete directory listing plan
- 04-02-SUMMARY.md created with full deviations, decisions, and dependency graph - STATE.md updated: position to plan 2/3, decisions, session continuity, metrics - ROADMAP.md updated: phase 4 progress 2/3 plans complete - REQUIREMENTS.md: LIVE-02 marked complete
This commit is contained in:
@@ -49,7 +49,7 @@ Requirements for initial release. Each maps to roadmap phases.
|
|||||||
### Live Content
|
### Live Content
|
||||||
|
|
||||||
- [ ] **LIVE-01**: App watches filesystem for changes and auto-refreshes current page
|
- [ ] **LIVE-01**: App watches filesystem for changes and auto-refreshes current page
|
||||||
- [ ] **LIVE-02**: User can browse a vault-wide directory listing
|
- [x] **LIVE-02**: User can browse a vault-wide directory listing
|
||||||
|
|
||||||
### Configuration
|
### Configuration
|
||||||
|
|
||||||
@@ -129,7 +129,7 @@ Which phases cover which requirements. Updated during roadmap creation.
|
|||||||
| BBS-01 | Phase 4 | Pending |
|
| BBS-01 | Phase 4 | Pending |
|
||||||
| BBS-02 | Phase 4 | Pending |
|
| BBS-02 | Phase 4 | Pending |
|
||||||
| LIVE-01 | Phase 4 | Pending |
|
| LIVE-01 | Phase 4 | Pending |
|
||||||
| LIVE-02 | Phase 4 | Pending |
|
| LIVE-02 | Phase 4 | Complete |
|
||||||
|
|
||||||
**Coverage:**
|
**Coverage:**
|
||||||
- v1 requirements: 32 total
|
- v1 requirements: 32 total
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ Plans:
|
|||||||
2. Each page shows the file's last-modified timestamp
|
2. Each page shows the file's last-modified timestamp
|
||||||
3. When a markdown file in the vault is modified on disk, the currently displayed page auto-refreshes without the user doing anything
|
3. When a markdown file in the vault is modified on disk, the currently displayed page auto-refreshes without the user doing anything
|
||||||
4. User can navigate to a vault-wide directory listing showing all available documents
|
4. User can navigate to a vault-wide directory listing showing all available documents
|
||||||
**Plans:** 3 plans
|
**Plans:** 2/3 plans executed
|
||||||
Plans:
|
Plans:
|
||||||
- [x] 04-01-PLAN.md — ANSI splash screen on index.md and file metadata in status bar
|
- [x] 04-01-PLAN.md — ANSI splash screen on index.md and file metadata in status bar
|
||||||
- [ ] 04-02-PLAN.md — Virtual directory listing via [[Directory]] wiki-link
|
- [ ] 04-02-PLAN.md — Virtual directory listing via [[Directory]] wiki-link
|
||||||
@@ -91,4 +91,4 @@ Phases execute in numeric order: 1 → 2 → 3 → 4
|
|||||||
| 1. Safety Foundation | 3/3 | Complete | 2026-02-28 |
|
| 1. Safety Foundation | 3/3 | Complete | 2026-02-28 |
|
||||||
| 2. Vault Core and Rendering | 3/3 | Complete | 2026-02-28 |
|
| 2. Vault Core and Rendering | 3/3 | Complete | 2026-02-28 |
|
||||||
| 3. Navigation and Links | 2/2 | Complete | 2026-02-28 |
|
| 3. Navigation and Links | 2/2 | Complete | 2026-02-28 |
|
||||||
| 4. BBS Polish and Live Content | 1/3 | In progress | - |
|
| 4. BBS Polish and Live Content | 2/3 | In Progress| |
|
||||||
|
|||||||
+16
-13
@@ -5,23 +5,23 @@
|
|||||||
See: .planning/PROJECT.md (updated 2026-02-28)
|
See: .planning/PROJECT.md (updated 2026-02-28)
|
||||||
|
|
||||||
**Core value:** Users can connect via SSH and seamlessly browse a vault of linked markdown documents with retro BBS aesthetics
|
**Core value:** Users can connect via SSH and seamlessly browse a vault of linked markdown documents with retro BBS aesthetics
|
||||||
**Current focus:** Phase 4 IN PROGRESS — Plan 01 done (splash screen, file metadata, all Phase 4 deps), Plans 02-03 remaining
|
**Current focus:** Phase 4 IN PROGRESS — Plans 01-02 done, Plan 03 (live reload) remaining
|
||||||
|
|
||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Phase: 4 of 4 (BBS Polish and Live Content) — IN PROGRESS
|
Phase: 4 of 4 (BBS Polish and Live Content) — IN PROGRESS
|
||||||
Plan: 1 of 3 in current phase (04-01 done, 04-02 next)
|
Plan: 2 of 3 in current phase (04-01, 04-02 done, 04-03 next)
|
||||||
Status: 04-01 complete — splash screen, file metadata in status bar, Phase 4 dependencies added
|
Status: 04-02 complete — [[Directory]] virtual page with tree view, Tab-cycling, history back/forward
|
||||||
Last activity: 2026-03-01 — Plan 01 complete (splash.rs, PageMeta, ansi-to-tui/notify/walkdir deps)
|
Last activity: 2026-03-01 — Plan 02 complete (DirEntry, list_vault_files, navigate_to_directory, build_directory_lines)
|
||||||
|
|
||||||
Progress: [████████░░] 80%
|
Progress: [█████████░] 87%
|
||||||
|
|
||||||
## Performance Metrics
|
## Performance Metrics
|
||||||
|
|
||||||
**Velocity:**
|
**Velocity:**
|
||||||
- Total plans completed: 8
|
- Total plans completed: 9
|
||||||
- Average duration: 2.9 min
|
- Average duration: 3.1 min
|
||||||
- Total execution time: 0.39 hours
|
- Total execution time: 0.44 hours
|
||||||
|
|
||||||
**By Phase:**
|
**By Phase:**
|
||||||
|
|
||||||
@@ -30,10 +30,10 @@ Progress: [████████░░] 80%
|
|||||||
| 01-safety-foundation | 3 | 7 min | 2.3 min |
|
| 01-safety-foundation | 3 | 7 min | 2.3 min |
|
||||||
| 02-vault-core-and-rendering | 3 | 9 min | 3.0 min |
|
| 02-vault-core-and-rendering | 3 | 9 min | 3.0 min |
|
||||||
| 03-navigation-and-links | 2 | 7 min | 3.5 min |
|
| 03-navigation-and-links | 2 | 7 min | 3.5 min |
|
||||||
| 04-bbs-polish-and-live-content | 1 | 4 min | 4.0 min |
|
| 04-bbs-polish-and-live-content | 2 | 12 min | 6.0 min |
|
||||||
|
|
||||||
**Recent Trend:**
|
**Recent Trend:**
|
||||||
- Last 5 plans: 2 min, 2 min, 4 min, 3 min, 4 min
|
- Last 5 plans: 2 min, 4 min, 3 min, 4 min, 8 min
|
||||||
- Trend: Stable
|
- Trend: Stable
|
||||||
|
|
||||||
*Updated after each plan completion*
|
*Updated after each plan completion*
|
||||||
@@ -73,6 +73,9 @@ Recent decisions affecting current work:
|
|||||||
- [Phase 03-02]: navigate_back/forward re-loads from disk (no render cache) per research recommendation
|
- [Phase 03-02]: navigate_back/forward re-loads from disk (no render cache) per research recommendation
|
||||||
- [Phase 03-02]: Draw-time REVERSED uses lines.clone() per frame — stored lines unchanged for resize re-render
|
- [Phase 03-02]: Draw-time REVERSED uses lines.clone() per frame — stored lines unchanged for resize re-render
|
||||||
- [Phase 03-02]: Span overlap detection extended beyond plan spec — catches spans starting before col_offset that extend into link range
|
- [Phase 03-02]: Span overlap detection extended beyond plan spec — catches spans starting before col_offset that extend into link range
|
||||||
|
- [Phase 04]: resolve_wiki_link() Directory sentinel placed before rfind('/') split — prevents 'directory' being misinterpreted as a subpath prefix
|
||||||
|
- [Phase 04]: navigate_back/forward use if/else-if branch for __directory__ not load_document — avoids spurious Missing document state for virtual page
|
||||||
|
- [Phase 04]: handle_resize() returns early for __directory__ — raw_content is None for virtual pages, prevents stale-content confusion
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
@@ -86,6 +89,6 @@ None.
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-02-28
|
Last session: 2026-03-01
|
||||||
Stopped at: Completed 03-02-PLAN.md (Phase 3 complete)
|
Stopped at: Completed 04-02-PLAN.md
|
||||||
Resume file: .planning/phases/04-live-reload/04-01-PLAN.md
|
Resume file: .planning/phases/04-bbs-polish-and-live-content/04-03-PLAN.md
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
---
|
||||||
|
phase: 04-bbs-polish-and-live-content
|
||||||
|
plan: 02
|
||||||
|
subsystem: ui
|
||||||
|
tags: [walkdir, ratatui, rust, directory-listing, virtual-page, tab-cycling, navigation-history]
|
||||||
|
|
||||||
|
# Dependency graph
|
||||||
|
requires:
|
||||||
|
- phase: 04-01
|
||||||
|
provides: "walkdir = 2.5 in Cargo.toml, navigation history (navigate_back/forward), link_records + Tab-cycling, splash prepend pattern"
|
||||||
|
provides:
|
||||||
|
- "resolve_wiki_link() returns PathBuf::from('__directory__') for case-insensitive 'Directory' wiki-link"
|
||||||
|
- "DirEntry struct and list_vault_files() in vault.rs using WalkDir::new().sort_by_file_name()"
|
||||||
|
- "navigate_to_directory() method builds tree view via build_directory_lines() and pushes history entry"
|
||||||
|
- "build_directory_lines() emits yellow-bold directory entries and cyan bracketed file links with LinkRecord"
|
||||||
|
- "navigate_back/forward handle __directory__ sentinel — regenerate listing fresh each visit"
|
||||||
|
- "handle_resize() skips re-render for __directory__ pages (fixed-width text, no markdown)"
|
||||||
|
affects: [04-03-live-reload]
|
||||||
|
|
||||||
|
# Tech tracking
|
||||||
|
tech-stack:
|
||||||
|
added: []
|
||||||
|
patterns:
|
||||||
|
- "Virtual page pattern: current_path == '__directory__' sentinel distinguishes virtual pages from real vault documents"
|
||||||
|
- "Directory builder pattern: build_directory_lines() returns (Vec<Line<'static>>, Vec<LinkRecord>) — same shape as render_markdown output"
|
||||||
|
- "Always-fresh pattern: navigate_back/forward call list_vault_files() again on __directory__ — never stale cache"
|
||||||
|
- "Resize guard pattern: early return in handle_resize() for virtual pages avoids crash on None raw_content"
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created: []
|
||||||
|
modified:
|
||||||
|
- "src/vault.rs — resolve_wiki_link() Directory sentinel, DirEntry struct, list_vault_files() with WalkDir"
|
||||||
|
- "src/app.rs — navigate_to_directory(), build_directory_lines(), follow_selected_link() sentinel routing, navigate_back/forward __directory__ branches, handle_resize() guard"
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "resolve_wiki_link() sentinel check placed BEFORE rfind('/') split — prevents 'directory' being misinterpreted as a filename"
|
||||||
|
- "build_directory_lines() computes line_index as lines.len() before push — matches renderer pattern for Tab-cycling correctness"
|
||||||
|
- "navigate_back/forward use if/else-if chain (not load_document for __directory__) — avoids spurious Missing document state"
|
||||||
|
- "handle_resize() returns early for __directory__ (raw_content is None for virtual pages) — prevents stale-content confusion"
|
||||||
|
- "link_records for directory entries use is_wiki: false with direct vault_path strings — navigate_to() handles them without resolve step"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "Virtual page sentinel: __directory__ string as current_path distinguishes virtual page from real file throughout app"
|
||||||
|
- "Tab-cycling for directory entries: same LinkRecord model as rendered markdown — no special-case in key handling"
|
||||||
|
- "Directory listing always regenerated: list_vault_files() called on every visit (forward/back/direct) — always reflects current vault state"
|
||||||
|
|
||||||
|
requirements-completed: [LIVE-02]
|
||||||
|
|
||||||
|
# Metrics
|
||||||
|
duration: 8min
|
||||||
|
completed: 2026-03-01
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 4 Plan 02: Directory Listing Summary
|
||||||
|
|
||||||
|
**Virtual [[Directory]] page with WalkDir tree view — yellow-bold dirs, cyan bracketed file links, Tab-cycling, and history back/forward all wired through existing link model**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** 8 min
|
||||||
|
- **Started:** 2026-03-01T00:00:00Z
|
||||||
|
- **Completed:** 2026-03-01T00:08:00Z
|
||||||
|
- **Tasks:** 2
|
||||||
|
- **Files modified:** 2
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
|
||||||
|
- `resolve_wiki_link()` intercepts case-insensitive "Directory" before filesystem scan and returns `PathBuf::from("__directory__")` sentinel — zero false positives, works with `[[directory]]`, `[[DIRECTORY]]`, `[[Directory]]`
|
||||||
|
- `DirEntry` struct and `list_vault_files()` added to `vault.rs` using `WalkDir::new().sort_by_file_name()` — alphabetically sorted, skips hidden entries and non-.md files, reports depth for tree indentation
|
||||||
|
- `build_directory_lines()` module-level helper produces `(Vec<Line<'static>>, Vec<LinkRecord>)` matching `render_markdown` output shape — directories as yellow-bold `name/`, files as cyan `[name]` with full LinkRecord for Tab-cycling
|
||||||
|
- `navigate_to_directory()` saves/truncates history, builds listing, sets `current_path = "__directory__"`, pushes HistoryEntry — full history participation
|
||||||
|
- `navigate_back()` and `navigate_forward()` detect `target_path == "__directory__"` and regenerate listing fresh — never stale
|
||||||
|
- `handle_resize()` guards with early return for `current_path == "__directory__"` — prevents crash on `None` raw_content
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
Each task was committed atomically:
|
||||||
|
|
||||||
|
1. **Task 1: Add [[Directory]] interception and vault file listing** - `fe69cf5` (feat)
|
||||||
|
2. **Task 2: Wire directory as virtual page with Tab-cycling navigation** - `600b46a` (feat)
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
|
||||||
|
- `src/vault.rs` - `resolve_wiki_link()` Directory sentinel check; `DirEntry` pub struct; `list_vault_files()` using `walkdir::WalkDir`
|
||||||
|
- `src/app.rs` - `navigate_to_directory()`; `build_directory_lines()`; `follow_selected_link()` `__directory__` routing; `navigate_back/forward` `__directory__` branch; `handle_resize()` early return guard
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
|
||||||
|
- Sentinel placed at the top of `resolve_wiki_link()` before `rfind('/')` — ensures "directory" is never split as a subpath prefix
|
||||||
|
- `build_directory_lines()` records `line_index = lines.len()` before the `lines.push()` call — matches the renderer's pattern exactly, Tab-cycling targets the correct line
|
||||||
|
- `navigate_back/forward` use an `if target_path == "__directory__"` branch rather than passing `"__directory__"` to `load_document()` — avoids a `VaultDocument::Missing` error state for a valid virtual page
|
||||||
|
- Directory entries stored with `is_wiki: false` — `navigate_to()` handles them directly as vault-relative paths without needing `resolve_wiki_link()`
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
None - plan executed exactly as written.
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
None. `walkdir 2.5` was already in `Cargo.toml` from Plan 01. The `DirEntry` struct, `list_vault_files()`, and `build_directory_lines()` all compiled on the first attempt. The `navigate_back/forward` branching was straightforward given the clear sentinel convention.
|
||||||
|
|
||||||
|
## User Setup Required
|
||||||
|
|
||||||
|
None - no external service configuration required. The `[[Directory]]` wiki-link works out of the box in any vault.
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
|
||||||
|
- Phase 4 Plan 03 (live reload via `notify`) can now start — `notify = "6.1"` was added to `Cargo.toml` in Plan 01
|
||||||
|
- Directory listing is always regenerated fresh on each visit — will automatically reflect vault changes even before live reload is wired
|
||||||
|
- All navigation paths handle `__directory__` sentinel consistently — no special cases needed in Plan 03
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 04-bbs-polish-and-live-content*
|
||||||
|
*Completed: 2026-03-01*
|
||||||
Reference in New Issue
Block a user