feat: Add progress bar and pretty print for CLI - #261
Conversation
- semble search/find-related gain --pretty, printing human-readable "path:start-end" + code per result instead of raw JSON. Default JSON output (used by agents/MCP) is unchanged. - create_index_from_path takes an optional on_progress(files_done, files_total) callback, threaded through SembleIndex.from_path/ from_git. The CLI wires it to a tqdm bar (green, matching the installer checkmarks and `semble savings` bars) that only appears on a tty and only when there's actually indexing work to do — a cache hit shows nothing. Claude-Session: https://claude.ai/code/session_013GB3H6NiUFKsyAVC3aQNZf
…m in the index loop Claude-Session: https://claude.ai/code/session_01X3vNSF5tx9oyqBz7DzaxZh
Codecov Report✅ All modified and coverable lines are covered by tests.
🚀 New features to boost your workflow:
|
Confidence Score: 3/5This PR is not safe to merge until pretty output neutralizes repository-controlled terminal sequences. The human-facing output mode emits untrusted filenames and source content verbatim to terminals, enabling control-sequence interpretation; file discovery also introduces avoidable whole-tree memory usage. Files Needing Attention: src/semble/cli.py, src/semble/index/create.py
|
| print(f"{r['file_path']}:{r['start_line']}-{r['end_line']}") | ||
| if "content" in r: | ||
| print() | ||
| print(r["content"]) |
There was a problem hiding this comment.
When --pretty is used, repository-controlled file paths and source content are printed without escaping control characters. A local or cloned repository can include ANSI or OSC sequences that the terminal interprets, allowing output spoofing or terminal manipulation. Escape or neutralize terminal control sequences before printing these values.
How this was verified: File names and text read from the indexed repository flow through format_results unchanged and are passed directly to print on the terminal-facing pretty-output path.
| skipped_large: list[str] = [] | ||
|
|
||
| for file_path in walk_files(path, resolved_extensions): | ||
| files = list(walk_files(path, resolved_extensions)) |
There was a problem hiding this comment.
Converting walk_files(...) to a list retains every discovered path and completes the full traversal before indexing or showing progress. On repositories with very large file counts, this increases peak memory use and leaves the CLI apparently idle during discovery. Iterating lazily or using a bounded counting strategy would avoid that practical cost.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
This PR adds a progressbar to the CLI for indexing to make it more visible how long indexing will take. The progressbar disappears after indexing finishes (we could keep it though? Idk). Also added a
prettyargument to make the CLI output nice to read (mainly for demo purposes for a cool followup). We already had tqdm as a transitive dep, now it's just added since we import it directly.Screenshot:
