Architecture
Pipeline for both modes (filter and TUI):
scan → parse → query → search → output/tuiPackages
Section titled “Packages”| Package | Responsibility | Key API |
|---|---|---|
internal/scan | *.md discovery, sorted | WalkMarkdown(Options) ([]string, error) — see Scan |
internal/parse | frontmatter split + YAML + normalizers → Document | ParseFile, ParseContent, SplitFrontmatter |
internal/model | Unified Document contract + SearchBlob | Document, BuildSearchBlob, FlattenScalars — see Frontmatter Model |
internal/query | Tokenizer + Query AST + date-range parser | Parse(input) (*Query, error) — see Query Syntax |
internal/search | Hard-filter (MatchesDoc) + fuzzy Rank + FilterArchived | Rank, MatchesDoc — see Search & Ranking |
internal/tui | BubbleTea picker, FilterFunc hook | Run, NewModel, SetFilter — see TUI |
internal/output | paths/json/vimgrep formatters + Snippet | FormatPaths/JSON/Vimgrep — see CLI |
cmd/mdfu | Flags, runFilter / runTUI wiring | main.go, filter.go |
internal/tui never imports internal/search/internal/query; integration injects tui.SetFilter(buildFilterFunc()) in cmd/mdfu.
Constraints (locked)
Section titled “Constraints (locked)”- Single static Go binary, no daemon, no
cgoby default. - No persistent index (see Backend Evaluation for the evaluated exception path).
- Deps:
gopkg.in/yaml.v3,charmbracelet/bubbletea+bubbles+lipgloss,sahilm/fuzzy, stdlib rest.
Performance budgets
Section titled “Performance budgets”- 5–10k files: cold
scan+parse<500ms, per-keystrokequery+rank<50ms. - Current risk:
search.scoreDocrunsfuzzy.Findper doc per bare word against the wholeSearchBlob—O(docs × words). See Search & Ranking and the Roadmap tasks.