7.2 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | |||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 02-vault-core-and-rendering | 01 | execute | 1 |
|
true |
|
|
Purpose: Establish the foundation libraries and I/O layer that the markdown renderer (Plan 02) and app integration (Plan 03) build upon.
Output: Three files modified/created; cargo build succeeds with all new dependencies.
<execution_context> @/Users/ruohki/.claude/get-shit-done/workflows/execute-plan.md @/Users/ruohki/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/02-vault-core-and-rendering/02-RESEARCH.md @.planning/phases/02-vault-core-and-rendering/02-CONTEXT.md @src/config.rs @Cargo.toml Task 1: Add dependencies and create vault file-loading module Cargo.toml, src/vault.rs **Cargo.toml:** Add three new dependencies alongside the existing ones: ```toml pulldown-cmark = "0.13.1" syntect = { version = "5.3", default-features = false, features = ["default-fancy"] } syntect-tui = "3.0" ```Note: default-features = false, features = ["default-fancy"] avoids the Oniguruma C library — pure Rust regex engine for clean SSH server builds.
src/vault.rs: Create a new module with:
-
VaultDocumentenum with three variants:Loaded { path: PathBuf, content: String }— file read successfullyMissing { path: PathBuf }— file does not exist (io::ErrorKind::NotFound)ReadError { path: PathBuf, reason: String }— other I/O error
-
load_document(vault_path: &Path, relative: &str) -> VaultDocument:- Join
vault_pathwithrelativeto get the full path - Use
std::fs::read_to_string()with proper match on the Result - Map
ErrorKind::NotFoundtoVaultDocument::Missing - Map other errors to
VaultDocument::ReadError - Return
VaultDocument::Loadedon success
- Join
The function takes vault_path (from Config) and a relative filename (e.g., "index.md").
Do NOT register the module in main.rs yet — Plan 03 handles wiring.
cargo check passes with no errors (new deps resolve, vault.rs compiles). Run cargo check 2>&1 and confirm exit code 0.
Cargo.toml has pulldown-cmark 0.13.1, syntect 5.3 with default-fancy, and syntect-tui 3.0. vault.rs exists with VaultDocument enum and load_document function. cargo check succeeds.
-
Module-level OnceLock statics for one-time initialization:
static SYNTAX_SET: OnceLock<SyntaxSet> = OnceLock::new(); static THEME_SET: OnceLock<ThemeSet> = OnceLock::new(); -
init_highlighter()— call once from main.rs before App::new():SYNTAX_SET.get_or_init(SyntaxSet::load_defaults_newlines);THEME_SET.get_or_init(ThemeSet::load_defaults);
-
syntax_set() -> &'static SyntaxSetandtheme_set() -> &'static ThemeSetaccessor functions that call.get().expect(...). -
syntect_color_to_cga(c: syntect::highlighting::Color) -> ratatui::style::Color— RGB-to-CGA Euclidean distance mapper using the 16 CGA palette entries exactly as documented in the research (Pattern 8). The CGA palette entries:- Black(0,0,0), Red(170,0,0), Green(0,170,0), Yellow(170,170,0), Blue(0,0,170), Magenta(170,0,170), Cyan(0,170,170), Gray(170,170,170)
- DarkGray(85,85,85), LightRed(255,85,85), LightGreen(85,255,85), LightYellow(255,255,85), LightBlue(85,85,255), LightMagenta(255,85,255), LightCyan(85,255,255), White(255,255,255)
-
highlight_code(code: &str, lang: &str) -> Vec<Line<'static>>— the public API for code block highlighting:- Look up syntax by token first, then by name, fall back to plain text
- Use
HighlightLines::new(syntax, &theme_set().themes["base16-ocean.dark"]) - For each line in
code.lines(): callhighlight_line(), map each(Style, &str)tuple to aSpan::styled(text.to_string(), Style::default().fg(syntect_color_to_cga(style.foreground))), collect intoLine::from(spans) - Return
Vec<Line<'static>>(all owned strings, no lifetime leakage)
Do NOT register the module in main.rs yet — Plan 03 handles wiring. But do ensure the file compiles in isolation (no unresolved imports that depend on other new modules).
cargo check passes. Verify highlighter.rs compiles by temporarily adding mod highlighter; to main.rs, running cargo check, then removing it. Or simply verify the file has no syntax errors by checking cargo check output.
highlighter.rs exists with init_highlighter(), syntax_set(), theme_set(), syntect_color_to_cga(), and highlight_code() functions. All use OnceLock for one-time init. Output is Vec<Line<'static>> with CGA 16-color palette.
<success_criteria>
cargo buildcompiles cleanly with pulldown-cmark 0.13.1, syntect 5.3, and syntect-tui 3.0- vault.rs provides file loading with structured error states (Loaded/Missing/ReadError)
- highlighter.rs provides one-shot syntect initialization and CGA-mapped syntax highlighting
- Both new modules produce
'staticlifetime outputs (no borrowed data leaking) </success_criteria>