mirror of
https://github.com/herdrdev/herdr.git
synced 2026-09-22 00:01:06 +00:00
fix: synchronize plugin pane pwd (#2985)
* fix: synchronize plugin pane pwd refs #2984 * refactor: isolate plugin pwd platform policy refs #2984 * docs: fix changelog conflict resolution --------- Co-authored-by: akbash-bot <300245827+akbash-bot@users.noreply.github.com> Co-authored-by: Can Celik <ogulcancelik@gmail.com>
This commit is contained in:
co-authored by
akbash-bot
Can Celik
parent
1b56601630
commit
7d35ebe7c4
@@ -4,6 +4,7 @@
|
||||
|
||||
### Fixed
|
||||
- Tab bar status commands now remove ESC-prefixed terminal control sequences instead of displaying their sequence bodies as text. (#3001)
|
||||
- Unix plugin pane commands now default `PWD` to their resolved working directory, so direct popup tools open at explicit `--cwd` paths while preserving caller-provided `PWD` values. (#2984)
|
||||
|
||||
## [0.8.2] - 2026-08-19
|
||||
|
||||
|
||||
@@ -16,17 +16,17 @@ impl App {
|
||||
pane: PluginManifestPane,
|
||||
) -> String {
|
||||
let context = self.current_plugin_context("plugin-pane");
|
||||
let cwd = self.plugin_pane_cwd(plugin, params.cwd);
|
||||
let extra_env =
|
||||
match self.plugin_pane_launch_env(plugin, &pane.id, params.env.clone(), &context) {
|
||||
match self.plugin_pane_launch_env(plugin, &pane.id, &cwd, params.env, &context) {
|
||||
Ok(env) => env,
|
||||
Err((code, message)) => return encode_error(id, &code, message),
|
||||
};
|
||||
let cwd = Some(self.plugin_pane_cwd(plugin, params.cwd));
|
||||
let width = params.width.or(pane.width);
|
||||
let height = params.height.or(pane.height);
|
||||
if let Err(err) = self.spawn_popup_argv_command(
|
||||
&pane.command,
|
||||
cwd,
|
||||
Some(cwd),
|
||||
extra_env,
|
||||
crate::app::popup::PopupGeometry { width, height },
|
||||
) {
|
||||
@@ -49,17 +49,21 @@ impl App {
|
||||
pane: PluginManifestPane,
|
||||
) -> String {
|
||||
let context = self.current_plugin_context("plugin-pane");
|
||||
let cwd = self.plugin_pane_cwd(plugin, params.cwd);
|
||||
let extra_env =
|
||||
match self.plugin_pane_launch_env(plugin, &pane.id, params.env.clone(), &context) {
|
||||
match self.plugin_pane_launch_env(plugin, &pane.id, &cwd, params.env, &context) {
|
||||
Ok(env) => env,
|
||||
Err((code, message)) => return encode_error(id, &code, message),
|
||||
};
|
||||
let cwd = Some(self.plugin_pane_cwd(plugin, params.cwd));
|
||||
let (ws_idx, new_pane) =
|
||||
match self.spawn_overlay_argv_command(&pane.command, cwd, extra_env, Vec::new()) {
|
||||
Ok(result) => result,
|
||||
Err(err) => return encode_error(id, "plugin_pane_open_failed", err.to_string()),
|
||||
};
|
||||
let (ws_idx, new_pane) = match self.spawn_overlay_argv_command(
|
||||
&pane.command,
|
||||
Some(cwd),
|
||||
extra_env,
|
||||
Vec::new(),
|
||||
) {
|
||||
Ok(result) => result,
|
||||
Err(err) => return encode_error(id, "plugin_pane_open_failed", err.to_string()),
|
||||
};
|
||||
let layout_tab_idx = self
|
||||
.overlay_panes
|
||||
.get(&new_pane.pane_id)
|
||||
@@ -98,8 +102,9 @@ impl App {
|
||||
);
|
||||
};
|
||||
let context = self.plugin_context_for_pane(ws_idx, target_pane, "plugin-pane");
|
||||
let cwd = self.plugin_pane_cwd(plugin, params.cwd);
|
||||
let extra_env =
|
||||
match self.plugin_pane_launch_env(plugin, &pane.id, params.env.clone(), &context) {
|
||||
match self.plugin_pane_launch_env(plugin, &pane.id, &cwd, params.env, &context) {
|
||||
Ok(env) => env,
|
||||
Err((code, message)) => return encode_error(id, &code, message),
|
||||
};
|
||||
@@ -110,7 +115,6 @@ impl App {
|
||||
crate::api::schema::SplitDirection::Right => Direction::Horizontal,
|
||||
crate::api::schema::SplitDirection::Down => Direction::Vertical,
|
||||
};
|
||||
let cwd = Some(self.plugin_pane_cwd(plugin, params.cwd));
|
||||
let (rows, cols) = self.state.estimate_pane_size();
|
||||
let previous_focus = self.state.current_pane_focus_target();
|
||||
let Some(ws) = self.state.workspaces.get_mut(ws_idx) else {
|
||||
@@ -121,7 +125,7 @@ impl App {
|
||||
direction,
|
||||
rows.max(4),
|
||||
cols.max(10),
|
||||
cwd,
|
||||
Some(cwd),
|
||||
&pane.command,
|
||||
extra_env,
|
||||
self.state.pane_scrollback_limit_bytes,
|
||||
@@ -187,7 +191,7 @@ impl App {
|
||||
let cwd = self.plugin_pane_cwd(plugin, params.cwd);
|
||||
let context = self.plugin_context_for_workspace(ws_idx, "plugin-pane");
|
||||
let extra_env =
|
||||
match self.plugin_pane_launch_env(plugin, &pane.id, params.env.clone(), &context) {
|
||||
match self.plugin_pane_launch_env(plugin, &pane.id, &cwd, params.env, &context) {
|
||||
Ok(env) => env,
|
||||
Err((code, message)) => return encode_error(id, &code, message),
|
||||
};
|
||||
@@ -233,10 +237,12 @@ impl App {
|
||||
&self,
|
||||
plugin: &InstalledPluginInfo,
|
||||
entrypoint: &str,
|
||||
cwd: &std::path::Path,
|
||||
env: std::collections::HashMap<String, String>,
|
||||
context: &PluginInvocationContext,
|
||||
) -> Result<Vec<(String, String)>, (String, String)> {
|
||||
let mut env = super::super::env::normalize_launch_env(env)?;
|
||||
crate::platform::set_default_plugin_pane_pwd(&mut env, cwd);
|
||||
let context_json = serde_json::to_string(&context)
|
||||
.map_err(|err| ("invalid_plugin_context".to_string(), err.to_string()))?;
|
||||
super::env::ensure_plugin_user_dirs(plugin)
|
||||
|
||||
@@ -3,6 +3,16 @@ use std::process::Command;
|
||||
|
||||
use super::{ClipboardImage, ForegroundJob, Signal};
|
||||
|
||||
#[cfg(unix)]
|
||||
pub(crate) use super::unix_common::set_default_plugin_pane_pwd;
|
||||
|
||||
#[cfg(not(unix))]
|
||||
pub(crate) fn set_default_plugin_pane_pwd(
|
||||
_env: &mut Vec<(String, String)>,
|
||||
_cwd: &std::path::Path,
|
||||
) {
|
||||
}
|
||||
|
||||
pub(crate) fn remote_ssh_config_paths() -> super::RemoteSshConfigPaths {
|
||||
super::RemoteSshConfigPaths {
|
||||
user_config: std::env::var_os("HOME")
|
||||
|
||||
@@ -16,7 +16,8 @@ pub(crate) use super::unix_common::{
|
||||
configure_status_command, create_remote_private_dir, create_remote_ssh_config_dir,
|
||||
create_remote_ssh_config_file, hostname, local_datetime, remote_bridge_endpoint_path,
|
||||
remote_private_temp_base, remote_reattach_argument, remote_reattach_program,
|
||||
remote_ssh_config_paths, status_commands_supported, StatusCommandGuard,
|
||||
remote_ssh_config_paths, set_default_plugin_pane_pwd, status_commands_supported,
|
||||
StatusCommandGuard,
|
||||
};
|
||||
|
||||
const WSL_MARKER_ENV_VARS: &[&str] = &["WSL_DISTRO_NAME", "WSL_INTEROP"];
|
||||
|
||||
@@ -16,7 +16,8 @@ pub(crate) use super::unix_common::{
|
||||
configure_status_command, create_remote_private_dir, create_remote_ssh_config_dir,
|
||||
create_remote_ssh_config_file, hostname, local_datetime, remote_bridge_endpoint_path,
|
||||
remote_private_temp_base, remote_reattach_argument, remote_reattach_program,
|
||||
remote_ssh_config_paths, status_commands_supported, StatusCommandGuard,
|
||||
remote_ssh_config_paths, set_default_plugin_pane_pwd, status_commands_supported,
|
||||
StatusCommandGuard,
|
||||
};
|
||||
|
||||
const PROC_PGRP_ONLY: u32 = 2;
|
||||
|
||||
@@ -228,10 +228,28 @@ fn datetime_from_tm(value: &libc::tm) -> Option<time::PrimitiveDateTime> {
|
||||
Some(time::PrimitiveDateTime::new(date, time))
|
||||
}
|
||||
|
||||
pub(crate) fn set_default_plugin_pane_pwd(env: &mut Vec<(String, String)>, cwd: &std::path::Path) {
|
||||
if !env.iter().any(|(key, _)| key == "PWD") {
|
||||
env.push(("PWD".to_string(), cwd.display().to_string()));
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn plugin_pane_pwd_defaults_to_cwd_without_overriding_explicit_env() {
|
||||
let cwd = Path::new("/plugin-cwd");
|
||||
let mut derived = vec![("OTHER".to_string(), "value".to_string())];
|
||||
set_default_plugin_pane_pwd(&mut derived, cwd);
|
||||
assert!(derived.contains(&("PWD".to_string(), "/plugin-cwd".to_string())));
|
||||
|
||||
let mut explicit = vec![("PWD".to_string(), "/caller-pwd".to_string())];
|
||||
set_default_plugin_pane_pwd(&mut explicit, cwd);
|
||||
assert_eq!(explicit, [("PWD".to_string(), "/caller-pwd".to_string())]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn remote_ssh_config_dir_rejects_overlong_control_socket_name() {
|
||||
let err = create_remote_ssh_config_dir(&"x".repeat(200)).unwrap_err();
|
||||
|
||||
@@ -15,6 +15,12 @@ use std::{
|
||||
|
||||
mod clipboard_image;
|
||||
|
||||
pub(crate) fn set_default_plugin_pane_pwd(
|
||||
_env: &mut Vec<(String, String)>,
|
||||
_cwd: &std::path::Path,
|
||||
) {
|
||||
}
|
||||
|
||||
use windows_sys::{
|
||||
Wdk::System::Threading::{NtQueryInformationProcess, ProcessBasicInformation},
|
||||
Win32::{
|
||||
|
||||
Reference in New Issue
Block a user