84 Commits

Author SHA1 Message Date
dailz
4ec3eb7cee fix(core): cap incremental scan in get_line() to prevent O(N) blocking
Add SCAN_AHEAD_LIMIT (10000 lines) to get_line() in Sampling state. Without this, jumping to end-of-file (G) during progressive loading would scan the entire file byte-by-byte on the main thread, blocking the UI and consuming excessive memory. Lines beyond the scanned region + limit now return None, which the TUI renders as empty.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-14 09:58:20 +08:00
dailz
05491304bf fix(tui): allow free scrolling during progressive loading
total_lines() was returning sampled_line_count() (only ~300 lines from the initial 64KB scan) during the Loading state, capping the scroll range. Use estimated_lines instead so the user can scroll to any position while indexing runs in the background. get_line() already supports incremental forward scanning on demand.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-14 09:36:03 +08:00
dailz
a03af7e74e feat(core): implement FileWatcher for live file tailing
Complete FileWatcher implementation using notify 8.x crate with get_inode() for cross-platform file identity. Support append detection for incremental index updates and truncate detection for full reloads.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-14 09:07:27 +08:00
dailz
bab3d9078a feat(tui): replace O(N) scanning with progressive loading and VisualHeightIndex
Replace synchronous file loading with AppLoadingState state machine (Empty/Loading/Ready/Error) for instant interactivity. Add ViewportCache for on-demand viewport computation, replacing global wrap/level caches. Integrate background indexer polling and file watcher events into the TUI event loop. Add loading UI with progress percentage, estimated line numbers with ~ prefix, and error state display. Eliminate all O(N) linear scans using VisualHeightIndex binary search.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-14 09:07:18 +08:00
dailz
f9f451e0d6 feat(core): implement ProgressiveFileReader with background indexer
Add ProgressiveFileReader state machine (Sampling/Ready/Error) with scanned_newlines cache for O(1) line lookups. Implement spawn_indexer() for background mmap-based indexing with cancellation and progress reporting. Add VisualHeightIndex with prefix-sum + binary search for O(log N) visual height queries. Register all new io submodules and extend FileReader with reload(), save_cache(), and accessor methods.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-14 09:07:09 +08:00
dailz
210eecfa66 feat(core): extract wrap utilities and extend LineIndex for progressive loading
Move wrap_line_chars and format_json_line from app.rs to core/io/wrap.rs with MAX_WRAP_INPUT_LEN guard. Add serde derives, pub getters, and extend_from_bytes() to LineIndex for incremental index building.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-14 09:06:52 +08:00
dailz
cfbe4900a5 feat(core): add LineSampler for fast line count estimation
Implement head/tail 64KB sampling to estimate total line count without scanning the entire file. Also provide read_first_lines() for reading the first N lines for immediate display during progressive loading.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-14 09:06:42 +08:00
dailz
2260d60302 feat(core): add disk index cache infrastructure
Add xxhash-rust and bincode workspace dependencies for fast hashing and serialization. Implement cache_util for cache directory/path resolution with versioning, and IndexCache for saving/loading line indices to disk with file-hash validation.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-14 09:06:36 +08:00
dailz
62a176441e feat(core): refactor FileReader to use mmap with low-RSS index building
Replace Vec<u8> with memmap2::Mmap for file content. Build line index via BufReader streaming (from_reader) instead of scanning mmap'd data, keeping RSS at ~3MB for 5GB files instead of ~5GB.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-12 20:50:58 +08:00
dailz
25a17779ff feat(core): implement sparse LineIndex with BufReader streaming
Rewrite LineIndex to use sparse sampling (every 256 lines) instead of per-line offsets. Add from_reader() for low-RSS streaming index construction via BufReader fill_buf()/consume(), reducing 5GB file RSS from 5122MB to 3.4MB.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-12 20:50:14 +08:00
dailz
02d7323a8b feat(core): add Mmap error variant and memmap2 dependency
Add CoreError::Mmap(String) error variant for mmap operations and memmap2 = "0.9" as workspace dependency.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-12 20:49:27 +08:00
dailz
2ac3eb99c7 feat(tui): add Span-based rendering with level colors and settings panel
Replace Line::styled with Span-based rendering: gutter (DarkGray fg) + content (level-based fg color). Add centered settings popup (S key) with j/k navigation, arrow key color cycling, number key shortcuts, Enter to save, Esc to cancel.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-12 10:52:45 +08:00
dailz
c6e83cb8c2 feat(tui): add AppMode, level_cache and config integration
Add AppMode enum (Normal/Settings), level_cache field populated in recompute_wrap_cache via detect_level(), color_config loaded from TOML in main.rs. Refactor handle_key for mode dispatch with S key to enter settings.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-12 10:52:03 +08:00
dailz
ef4c2e7383 feat(tui): add color mapping module
Add color.rs with parse_color (string to ratatui::Color), level_fg (LogLevel to color via ColorConfig), and AVAILABLE_COLORS constant for the settings panel.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-12 10:51:26 +08:00
dailz
c914912389 feat(core): add detect_level() for plain text logs
Add level detection that tries JSON parsing first (trusts level field), then falls back to keyword scanning with word-boundary checks. Supports SEVERE, FATAL, ERROR, WARN, INFO, DEBUG, TRACE and their abbreviations.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-12 10:50:59 +08:00
dailz
105e428a43 feat(core): add ColorConfig struct with TOML support
Replace empty AppConfig stub with ColorConfig struct that stores level-to-color mappings as strings. Supports loading/saving from XDG config directory via TOML, with graceful degradation on missing/invalid files.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-12 10:50:39 +08:00
dailz
67a118a8c8 docs(core): add Chinese comments to types module
Add detailed Chinese comments explaining Rust derive macros, FromStr/Display traits, serde serialization, and core data types.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-11 16:30:20 +08:00
dailz
9082726e47 docs(core): add Chinese comments to error module
Add detailed Chinese comments explaining thiserror derive macros, From trait conversions, and Result type alias.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-11 16:26:24 +08:00
dailz
c04cc72b55 docs(core): add Chinese comments to parser module
Add detailed Chinese comments explaining Rust syntax, serde_json usage, and JSON log parsing logic.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-11 16:20:44 +08:00
dailz
e3f11d2165 docs(core): add Chinese comments to io module
Add detailed Chinese comments explaining Rust syntax and concepts for readers unfamiliar with the language.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-11 16:17:06 +08:00
dailz
1c9367f1f9 feat(tui): update status bar with Tab format hint
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-11 11:38:42 +08:00
dailz
280c3f5014 feat(tui): add Tab key to toggle JSON pretty-print
Press Tab to switch JSON log lines between raw single-line and indented
multi-line format (2-space indent, like jq output). Only JSON Object lines
are affected; plain text lines stay unchanged.

- Add json_format bool field to App, toggled by Tab
- Add format_json_line() standalone function with serde_json::to_string_pretty
- Integrate into recompute_wrap_cache with \n-split sub-line wrapping
- Center viewport on cursor after cache rebuild to prevent jump on toggle
- Add 12 unit tests covering format, toggle, and edge cases

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-11 11:38:30 +08:00
dailz
8a664c02c8 fix(tui): use char-level wrapping instead of word-level for log lines 2026-04-11 09:02:01 +08:00
dailz
3c042e20a1 fix(tui): show [0/0] instead of [1/0] for empty files 2026-04-11 08:52:22 +08:00
dailz
6820246997 feat(tui): rewrite UI with line numbers, soft wrap, and scrolling 2026-04-10 23:38:06 +08:00
dailz
555ffc0836 feat(tui): expand App state with file loading and scroll 2026-04-10 23:28:23 +08:00
dailz
37bebc1a26 feat(core): implement JSON log parser 2026-04-10 23:08:26 +08:00
dailz
f173adc018 feat(core): implement FileReader with memchr line indexing 2026-04-10 23:01:03 +08:00
dailz
73322138c1 feat(tui): ratatui skeleton with layout
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-10 21:20:14 +08:00
dailz
09e7f995fb feat(gui): egui skeleton with dark theme
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-10 21:19:34 +08:00
dailz
53250e5903 feat(core): declare module structure
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-10 21:19:01 +08:00
dailz
843b3db081 feat(core): define error types with thiserror
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-10 21:18:20 +08:00
dailz
8e977af52c feat(core): define core types with tests
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-10 21:17:57 +08:00
dailz
0ee82cbccd feat(init): scaffold cargo workspace and CI
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-10 21:17:22 +08:00