fix: sync shell history with standard history files#9855
fix: sync shell history with standard history files#9855mitre88 wants to merge 1 commit intowarpdotdev:masterfrom
Conversation
This change implements bidirectional sync between Warp's command history and standard shell history files (~/.bash_history, ~/.zsh_history, etc.). Changes: - Add read_shell_history() function to read from standard shell history files - Add write_command_to_shell_history() function to append commands to shell history - Add ensure_shell_history_synced() to merge shell history on session init - Add automatic write of executed commands to shell history This fixes issue warpdotdev#3422 where history from other terminals/sessions was not synced to Warp's history and vice versa. Key features: - Reads shell history files on startup and merges unique commands - Writes executed commands to shell history for cross-terminal sharing - Deduplicates against existing Warp history - Uses proper error handling (ShellHistorySyncError) instead of bare except - Uses context managers for file operations
|
Thank you for your pull request and welcome to our community. We could not parse the GitHub identity of the following contributors: Dr. Alex Mitre.
|
|
I'm starting a first review of this pull request. You can view the conversation on Warp. I completed the review and no human review was requested for this pull request. Comment Powered by Oz |
There was a problem hiding this comment.
Overview
This PR adds shell-history file import/export helpers and hooks command execution to append commands to standard shell history files.
Concerns
- Shell-history import is not wired into any call path in the diff, so the claimed shell-to-Warp sync does not run.
- Import parsing reads raw lines instead of the existing per-shell history parsers, which corrupts zsh, fish, and bash timestamped history.
- Fish export writes plain text lines that fish will not treat as history entries.
Security
- Command export writes every session's commands to the host user's local history file based only on shell type, which can leak remote, container, WSL, or other non-host session commands into local history.
Verdict
Found: 0 critical, 4 important, 0 suggestions
Request changes
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
| std::sync::Mutex::new(HashSet::new()); | ||
| } | ||
|
|
||
| pub fn ensure_shell_history_synced(session_id: SessionId, shell_type: ShellType, ctx: &mut AppContext) { |
There was a problem hiding this comment.
ensure_shell_history_synced is never called in this PR, so shell-history → Warp sync never runs; invoke it during session initialization before claiming bidirectional sync.
| let reader = BufReader::new(file); | ||
| let mut seen: HashSet<String> = HashSet::new(); | ||
|
|
||
| for line in reader.lines() { |
There was a problem hiding this comment.
ShellType::parse_history, so zsh extended-history, fish YAML, and bash timestamp lines are imported as bogus commands; read the file bytes and parse with the existing per-shell parser before filtering.
| ShellType::Zsh => { | ||
| format!(": {}:0;{}\n", chrono::Utc::now().timestamp(), command) | ||
| } | ||
| ShellType::Bash | ShellType::Fish | ShellType::PowerShell => { |
There was a problem hiding this comment.
command\n makes entries invisible to fish. Emit fish's - cmd: ... format with the same escaping that parse_history expects.
| let command = event.command.to_string(); | ||
| ctx.background_executor() | ||
| .spawn(async move { | ||
| if let Err(e) = write_command_to_shell_history(shell_type, &command) { |
There was a problem hiding this comment.
There was a problem hiding this comment.
Overview
This PR adds shell-history file import/export helpers and hooks command execution to append commands to standard shell history files.
Concerns
- Shell-history import is not wired into any call path in the diff, so the claimed shell-to-Warp sync does not run.
- Import parsing reads raw lines instead of the existing per-shell history parsers, which corrupts zsh, fish, and bash timestamped history.
- Fish export writes plain text lines that fish will not treat as history entries.
Security
- Command export writes every session's commands to the host user's local history file based only on shell type, which can leak remote, container, WSL, or other non-host session commands into local history.
Verdict
Found: 0 critical, 4 important, 0 suggestions
Request changes
Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).
Powered by Oz
| std::sync::Mutex::new(HashSet::new()); | ||
| } | ||
|
|
||
| pub fn ensure_shell_history_synced(session_id: SessionId, shell_type: ShellType, ctx: &mut AppContext) { |
There was a problem hiding this comment.
ensure_shell_history_synced is never called in this PR, so shell-history → Warp sync never runs; invoke it during session initialization before claiming bidirectional sync.
| let reader = BufReader::new(file); | ||
| let mut seen: HashSet<String> = HashSet::new(); | ||
|
|
||
| for line in reader.lines() { |
There was a problem hiding this comment.
ShellType::parse_history, so zsh extended-history, fish YAML, and bash timestamp lines are imported as bogus commands; read the file bytes and parse with the existing per-shell parser before filtering.
| ShellType::Zsh => { | ||
| format!(": {}:0;{}\n", chrono::Utc::now().timestamp(), command) | ||
| } | ||
| ShellType::Bash | ShellType::Fish | ShellType::PowerShell => { |
There was a problem hiding this comment.
command\n makes entries invisible to fish. Emit fish's - cmd: ... format with the same escaping that parse_history expects.
| let command = event.command.to_string(); | ||
| ctx.background_executor() | ||
| .spawn(async move { | ||
| if let Err(e) = write_command_to_shell_history(shell_type, &command) { |
There was a problem hiding this comment.
Implements bidirectional sync between Warp command history and standard shell history files. Fixes issue #3422.