Conversation
…ention] config Add an @file mention picker to the TUI composer: type @path to get frecency-ranked file completions in a popover. Accepted files become inline chips in the input box; backspace on a chip deletes the whole token. Indexing uses git ls-files with a walkdir fallback, rebuilt in the background with adaptive TTL and a max_files safety cap. Queries go through a CharBag pre-filter plus a regex pass; gitignored directories are scanned lazily when a query targets them. The popover groups results into Recent and Files sections; the selection never rests on a section header and the building-index hint row is never acceptable. Tuning is exposed through the [file_mention] config section (refresh_ttl_secs, max_results, max_files; zero or absent falls back to built-in defaults), documented in README and shown in the /config settings summary. Also fixes a section-header up-skip wrap bug for non-power-of-2 list lengths and uses the cached config() accessor on the per-keystroke refresh path.
|
| match std::fs::read_to_string(path) { | ||
| Ok(content) => { | ||
| let block = if content.len() <= MAX_FILE_SIZE { | ||
| content | ||
| } else { | ||
| let line_count = content.lines().count(); | ||
| let preview: String = content.lines().take(200).collect::<Vec<_>>().join("\n"); | ||
| format!( | ||
| "{}\n\n[... file too large: {} lines, {} bytes, showing first 200 lines]", | ||
| preview, | ||
| line_count, | ||
| content.len(), | ||
| ) | ||
| }; |
There was a problem hiding this comment.
The prompt builder synchronously reads every selected text file in full before checking the 100 KB per-file limit, then applies the 500 KB cumulative budget only after all file contents have been collected. This is a non-blocking concern, but a large selected file can still block the UI and allocate its full contents before either limit takes effect.
Knowledge Base Used: Session storage and context management
Artifacts
- This authored script temporarily adds a narrow test that creates a size-controlled selected text file, invokes the real prompt builder, verifies the complete-size marker, and restores the source; it demonstrates the tested path.
- This completed command capture runs the focused test against a 614,400-byte selected file and shows the exact full input size in the truncation marker despite the 100 KB and 500 KB limits; the takeaway is that the full file was read before limiting.
Ran code and verified through T-Rex
Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/jcode-tui/src/tui/app/file_mention.rs
Line: 1655-1668
Comment:
**File Limits Apply Too Late**
The prompt builder synchronously reads every selected text file in full before checking the 100 KB per-file limit, then applies the 500 KB cumulative budget only after all file contents have been collected. This is a non-blocking concern, but a large selected file can still block the UI and allocate its full contents before either limit takes effect.
**Knowledge Base Used:** [Session storage and context management](https://app.greptile.com/solo-systems/-/custom-context/knowledge-base/1jehuang/jcode/-/docs/session-storage-and-context-management.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Operate on char vectors and collect the prefix from chars instead of using a char count as a byte offset. Also end file-mention mode once the user types a space after the @token, so a stale mention can no longer drive suggestions or intercept Enter.
Ctrl+Z snapshots now carry file_chips, so undoing a backspace that pruned a chip brings the attachment back instead of silently dropping it from the prompt at send time.
Use metadata plus a bounded read for oversized chips so a huge file is never fully loaded just to be truncated. The preview still shows the first 200 lines.
Ranking signals from one repository are noise in another, so the frecency log now lives under state_dir/file_frecency/<hash-of-cwd>/. check_refresh swaps to the new project's store when the cwd changes.
|
Addressed all 5 Greptile findings in follow-up commits (83c4ac7..108b13b):
|
read_to_string_bounded now only keeps the truncated prefix when the byte limit sliced a multi-byte char at the cut. Any invalid UTF-8 before the limit is treated as corruption and surfaces the existing read-failure marker, so the model never sees silently truncated file context.
|
Fixed the follow-up P1 (
Tests added: mid-file invalid byte rejected at the reader level, sliced-char-at-limit prefix kept, and end-to-end |
Closes #570.
Problem
When composing prompts in the TUI there is no way to quickly reference files by name. Users must type full paths by hand, which is slow and error-prone in large codebases. #570 tracks this; maintainer guidance there suggested starting with project-local tracked files and a deterministic recency/frequency score, which is what this PR implements.
What it does
Typing
@in the composer opens a file-completion popover ranked by frecency (frequency + exponential recency decay). Accepting a completion replaces the@querywith the path and records an inline file chip; backspace on a chip deletes the whole path token instead of one character.git ls-files --cached --others --exclude-standardas the primary source, with awalkdirfallback honoring.gitignorefor non-git directories. Rebuilt in the background with adaptive TTL (30s base, 4x for large workspaces) and amax_filessafety cap. Anotify-based watcher marks the index dirty on filesystem changes.fs::read_dironly when a query actually targets them.[file_mention]in~/.jcode/config.toml(refresh_ttl_secs,max_results,max_files; zero or absent values fall back to built-in defaults), documented in README and shown in the/configsettings summary.Edge cases covered by tests
wrapping_sub(1) % lencomputedusize::MAX % len).Tradeoffs / assumptions
Validation
jcode-tuifile_mention/input_ui/suggestions battery: 111 passed.commands_testscompile fix included (master commit ff32973 added ausagefield toModelRoutewithout updating 5 test initializers, breakingcargo test -p jcode; also available standalone onfix/modelroute-usage-test-initif preferred as a separate PR).provider_init_testsenv isolation so provider tests are deterministic across developer machines.cargo check --all-targetsclean; clippy clean for all files touched by this PR; runtime smoke test on a standalone socket passes.