docs: update repository map and project metadata

Update the repository map with the latest project metadata, including
version bumps, updated dependency versions, and technical notes on formula
drilling, formula recomputation, and minibuffer clearing.

Co-Authored-By: fiddlerwoaroof/git-smart-commit (gemma-4-31B-it-UD-Q4_K_XL.gguf)
This commit is contained in:
Edward Langley
2026-04-14 00:49:32 -07:00
parent 35e2626a7d
commit 5a7ba5fb30

View File

@ -1,7 +1,8 @@
# Repository Map (LLM Reference) # Repository Map (LLM Reference)
Terminal pivot-table modeling app. Rust, Ratatui TUI, command/effect architecture. Terminal pivot-table modeling app. Rust, Ratatui TUI, command/effect architecture.
Crate `improvise` v0.1.0, Apache-2.0, edition 2021. Crate `improvise` v0.1.0-rc2, Apache-2.0, edition 2024.
Library + binary crate: `src/lib.rs` exports public modules, `src/main.rs` is the CLI entry.
--- ---
@ -94,8 +95,10 @@ pub struct Model {
// evaluate(&self, key: &CellKey) -> Option<CellValue> [formulas + raw data] // evaluate(&self, key: &CellKey) -> Option<CellValue> [formulas + raw data]
// evaluate_aggregated(&self, key, none_cats) -> Option<CellValue> [sums over hidden dims] // evaluate_aggregated(&self, key, none_cats) -> Option<CellValue> [sums over hidden dims]
// recompute_formulas(&mut self, none_cats) [fixed-point formula cache] // recompute_formulas(&mut self, none_cats) [fixed-point formula cache]
// add_formula(&mut self, formula: Formula) [replaces same target+category, adds item] // add_formula(&mut self, formula: Formula) [replaces same target+category]
// remove_formula(&mut self, target, category) // remove_formula(&mut self, target, category)
// measure_item_names(&self) -> Vec<String> [_Measure items + formula targets]
// effective_item_names(&self, cat) -> Vec<String> [_Measure dynamic, others ordered_item_names]
// category_names(&self) -> Vec<&str> [includes virtual] // category_names(&self) -> Vec<&str> [includes virtual]
// regular_category_names(&self) -> Vec<&str> [excludes _Index, _Dim, _Measure] // regular_category_names(&self) -> Vec<&str> [excludes _Index, _Dim, _Measure]
@ -262,8 +265,10 @@ pub enum ModeKey {
SearchMode, ImportWizard, SearchMode, ImportWizard,
} }
// Keymap::with_parent(parent: Arc<Keymap>) -> Self [Emacs-style inheritance]
// Keymap::lookup(&self, key, mods) -> Option<&Binding> // Keymap::lookup(&self, key, mods) -> Option<&Binding>
// Fallback chain: exact(key,mods) → Char with NONE mods → AnyChar → Any // Fallback chain: exact(key,mods) → Char with NONE mods → AnyChar → Any → parent
// Minibuffer modes: Enter and Esc use Binding::Sequence to include clear-buffer
// KeymapSet::default_keymaps() -> Self [builds all 14 mode keymaps] // KeymapSet::default_keymaps() -> Self [builds all 14 mode keymaps]
// KeymapSet::dispatch(&self, ctx, key, mods) -> Option<Vec<Box<dyn Effect>>> // KeymapSet::dispatch(&self, ctx, key, mods) -> Option<Vec<Box<dyn Effect>>>
@ -293,7 +298,8 @@ collapsed: |Time Period|/|2024|
format: ,.2f format: ,.2f
## Formulas ## Formulas
- Profit = Revenue - Cost [Measure] ← [TargetCategory] - Profit = Revenue - Cost ← defaults to [_Measure]
- Tax = Revenue * 0.1 [CustomCat] ← explicit [TargetCategory] for non-_Measure
## Category: Region ## Category: Region
- North, South, East, West ← bare items, comma-separated - North, South, East, West ← bare items, comma-separated
@ -323,7 +329,7 @@ The parser accepts sections in any order.
### Key design choices ### Key design choices
- Version line (`v2025-04-09`) enables future format changes. - Version line is exact match (`v2025-04-09`) — grammar enforces valid versions only.
- `Initial View:` is a top-level header, not embedded in view sections. - `Initial View:` is a top-level header, not embedded in view sections.
- Text cell values are always pipe-quoted to distinguish from numbers. - Text cell values are always pipe-quoted to distinguish from numbers.
- Bare items are comma-separated on one line; grouped items get one line each. - Bare items are comma-separated on one line; grouped items get one line each.
@ -349,7 +355,7 @@ Import flags: `--category`, `--measure`, `--time`, `--skip`, `--extract`, `--axi
| Crate | Purpose | | Crate | Purpose |
|-------|---------| |-------|---------|
| ratatui 0.29 | TUI framework | | ratatui 0.30 | TUI framework |
| crossterm 0.28 | Terminal backend | | crossterm 0.28 | Terminal backend |
| clap 4.6 (derive) | CLI parsing | | clap 4.6 (derive) | CLI parsing |
| serde + serde_json | Serialization | | serde + serde_json | Serialization |
@ -442,11 +448,18 @@ command/cmd/ Cmd trait, CmdContext, CmdRegistry, 40+ comma
``` ```
400 / 0t draw.rs TUI event loop (run_tui), frame composition 400 / 0t draw.rs TUI event loop (run_tui), frame composition
391 / 0t main.rs CLI entry (clap): open, import, cmd, script 391 / 0t main.rs CLI entry (clap): open, import, cmd, script
10 / 0t lib.rs Public module exports (enables examples)
228 / 29t format.rs Number display formatting (view-only rounding) 228 / 29t format.rs Number display formatting (view-only rounding)
124 / 0t persistence/improv.pest PEG grammar — single source of truth for .improv format 124 / 0t persistence/improv.pest PEG grammar — single source of truth for .improv format
2291 / 83t persistence/mod.rs .improv save/load (pest parser + format + gzip + legacy JSON) 2291 / 83t persistence/mod.rs .improv save/load (pest parser + format + gzip + legacy JSON)
``` ```
### Examples
```
examples/gen-grammar.rs Grammar-walking random file generator (pest_meta)
examples/pretty-print.rs Parse stdin, print formatted .improv to stdout
```
### Context docs ### Context docs
``` ```
context/design-principles.md Architectural principles context/design-principles.md Architectural principles
@ -455,7 +468,7 @@ context/repo-map.md This file
docs/design-notes.md Product vision & non-goals (salvaged from former SPEC.md) docs/design-notes.md Product vision & non-goals (salvaged from former SPEC.md)
``` ```
**Total: ~21,400 lines, 568 tests.** **Total: ~22,000 lines, 572 tests.**
--- ---
@ -519,7 +532,7 @@ examples).
1. **Commands never mutate.** They receive `&CmdContext` (read-only) and return `Vec<Box<dyn Effect>>`. 1. **Commands never mutate.** They receive `&CmdContext` (read-only) and return `Vec<Box<dyn Effect>>`.
2. **CellKey is always sorted.** Use `CellKey::new()` — never construct the inner Vec directly. 2. **CellKey is always sorted.** Use `CellKey::new()` — never construct the inner Vec directly.
3. **`category_mut()` for adding items.** `Model` has no `add_item` method; get the category first: `m.category_mut("Region").unwrap().add_item("East")`. 3. **`category_mut()` for adding items.** `Model` has no `add_item` method; get the category first: `m.category_mut("Region").unwrap().add_item("East")`.
4. **Virtual categories** `_Index`, `_Dim`, and `_Measure` always exist. `is_empty_model()` checks whether any *non-virtual* categories exist. `_Measure` holds numeric data fields and formula targets; `add_formula` auto-adds the target item. 4. **Virtual categories** `_Index`, `_Dim`, and `_Measure` always exist. `is_empty_model()` checks whether any *non-virtual* categories exist. `_Measure` items come from two sources: explicit data items (in category) + formula targets (dynamically via `measure_item_names()`). `add_formula` does NOT add items to `_Measure` — use `effective_item_names("_Measure")` to get the full list. `_Index` and `_Dim` are never persisted to `.improv` files; `_Measure` only persists non-formula items.
5. **Display rounding is view-only.** `format_f64` (half-away-from-zero) is only called in rendering. Formula eval uses full f64. 5. **Display rounding is view-only.** `format_f64` (half-away-from-zero) is only called in rendering. Formula eval uses full f64.
5b. **Formula evaluation is fixed-point.** `recompute_formulas(none_cats)` iterates formula evaluation until values stabilize, using a cache. `evaluate_aggregated` checks the cache for formula results. Circular refs produce `CellValue::Error("circular")`. 5b. **Formula evaluation is fixed-point.** `recompute_formulas(none_cats)` iterates formula evaluation until values stabilize, using a cache. `evaluate_aggregated` checks the cache for formula results. Circular refs produce `CellValue::Error("circular")`.
6. **Keybindings are per-mode.** `ModeKey::from_app_mode()` resolves the current mode, then the corresponding `Keymap` is looked up. Normal + `search_mode=true` maps to `SearchMode`. 6. **Keybindings are per-mode.** `ModeKey::from_app_mode()` resolves the current mode, then the corresponding `Keymap` is looked up. Normal + `search_mode=true` maps to `SearchMode`.
@ -527,3 +540,6 @@ examples).
8. **`.improv` format is defined by a PEG grammar** (`persistence/improv.pest`). Parsed by pest. Names use CL-style `|...|` pipe quoting when they aren't valid bare identifiers. JSON is legacy only. 8. **`.improv` format is defined by a PEG grammar** (`persistence/improv.pest`). Parsed by pest. Names use CL-style `|...|` pipe quoting when they aren't valid bare identifiers. JSON is legacy only.
9. **`IndexMap`** is used for categories and views to preserve insertion order. 9. **`IndexMap`** is used for categories and views to preserve insertion order.
10. **`MAX_CATEGORIES = 12`** applies only to `CategoryKind::Regular`. Virtual/Label categories are exempt. 10. **`MAX_CATEGORIES = 12`** applies only to `CategoryKind::Regular`. Virtual/Label categories are exempt.
11. **Drill into formula cells** strips the `_Measure` coordinate from the drill key when it names a formula target, so `matching_cells` finds the raw data records that feed the formula instead of returning empty.
12. **`App::new` calls `recompute_formulas`** before building the initial layout, so formula values appear on the first rendered frame.
13. **Minibuffer buffer clearing** is handled by `Binding::Sequence` in keymaps: Enter and Esc sequences include `clear-buffer` to reset the text buffer. The `clear-buffer` command is registered in the registry.