mirror of
https://github.com/stablyai/orca.git
synced 2026-10-07 08:02:21 +00:00
fix(remote): resolve the spawn cwd, the node manager dir, the vault host and the scrollback seed (#17952)
* fix(remote): resolve workspace cwd, mise Node, host scope, and TUI scrollback honestly #15296 relay: a folder workspace id (`folder:<uuid>`) carries no path, so the worktree-id split yielded nothing and $HOME silently won. Resolve the spawn cwd through worktreeId -> ORCA_WORKSPACE_ROOT -> host default, and refuse an agent spawn outright when a folder workspace names a root this host cannot resolve. #11733 ssh: generalize the NVM dotfile scrape into `orca_dotfile_dirs` and drive mise off `MISE_DATA_DIR` / `XDG_DATA_HOME` instead of a hardcoded `$HOME/.local/share/mise`. #13713 ai-vault: an unresolvable workspace host is `unverifiable`, not local. Widen the default scope to every host rather than scanning the client's own history and reporting "No agent sessions found". #6106 terminal: hydration asked the renderer for `scrollback: 0` while an alt-screen TUI was up, which drops the normal buffer's shell history rather than the TUI bytes. Drop the flag; readers already split the two buffers apart. * fix(remote): stop the relay answering host questions for a guest execution host Three findings from review of the spawn-cwd resolver, all the same shape: a path question answered against the wrong host, or with the wrong key. - resolveRelaySpawnCwd refused an agent launch whenever a folder workspace named a root that did not stat on the relay. But relayHostDirectoryExists stats the relay's *own* filesystem, and the relay supports WSL shells, so a folder workspace on a Windows relay launching into WSL now threw where it previously spawned -- contradicting the function's own doc comment, which says an absent path for that exact host pair is a miss, not a refusal. Thread the shell's execution host in and demote the refusal to a miss when the spawn does not run on the relay's filesystem. - requireRelaySpawnCwd's doc claims both call sites route through one resolver so the fence can never be keyed on a directory the spawn won't use, but the fence key was still computed with the non-stripping splitWorktreeId while the cwd used splitWorktreeIdForFilesystem. For a `::workspace:<uuid>` id those disagree by construction, in adjacent lines: the removal fence guarded a path no spawn ever enters. Same defect in shutdownForWorktreePath and the revive path; all three now use the filesystem split. - The remote Node probe expanded `$HOME` and `~/` prefixes out of a dotfile assignment but not `$XDG_DATA_HOME`, so `MISE_DATA_DIR=$XDG_DATA_HOME/...` was used as a literal directory name. Add the case arm, defaulting to the POSIX `$HOME/.local/share` the seed value already uses -- sshd's exec channel usually has no XDG_DATA_HOME at all.
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
// POSIX `sh` probe listing every plausible remote Node binary, one per line.
|
||||
// Kept out of the resolver so the shell text can grow without pushing that file
|
||||
// past its line budget.
|
||||
|
||||
// Why the dotfile scrape: sshd's exec channel runs without the user's profile, so
|
||||
// MISE_DATA_DIR / NVM_DIR set in ~/.zshrc are not in this environment. Reading the
|
||||
// assignment out of the dotfiles is the only way to see a relocated data dir.
|
||||
export const REMOTE_NODE_PATH_PROBE_SCRIPT = `
|
||||
command -v node 2>/dev/null
|
||||
orca_dotfile_dirs() {
|
||||
orca_var_name=$1
|
||||
orca_dirs=$2
|
||||
for orca_file in "$HOME/.profile" "$HOME/.bash_profile" "$HOME/.bashrc" "$HOME/.zprofile" "$HOME/.zshrc"
|
||||
do
|
||||
[ -r "$orca_file" ] || continue
|
||||
orca_dir_from_file=$(sed -n "s/^[[:space:]]*export[[:space:]][[:space:]]*$orca_var_name[[:space:]]*=[[:space:]]*//p; s/^[[:space:]]*$orca_var_name[[:space:]]*=[[:space:]]*//p" "$orca_file" | tail -n 1)
|
||||
case "$orca_dir_from_file" in
|
||||
\\"*\\") orca_dir_from_file=\${orca_dir_from_file#\\"}; orca_dir_from_file=\${orca_dir_from_file%%\\"*} ;;
|
||||
\\'*\\') orca_dir_from_file=\${orca_dir_from_file#\\'}; orca_dir_from_file=\${orca_dir_from_file%%\\'*} ;;
|
||||
*) orca_dir_from_file=\${orca_dir_from_file%%[[:space:]]*} ;;
|
||||
esac
|
||||
case "$orca_dir_from_file" in
|
||||
'$XDG_DATA_HOME'*) orca_dir_from_file="\${XDG_DATA_HOME:-$HOME/.local/share}\${orca_dir_from_file#'$XDG_DATA_HOME'}" ;;
|
||||
'$HOME'*) orca_dir_from_file="$HOME\${orca_dir_from_file#'$HOME'}" ;;
|
||||
"~/"*) orca_dir_from_file="$HOME/\${orca_dir_from_file#\\~/}" ;;
|
||||
esac
|
||||
[ -n "$orca_dir_from_file" ] && orca_dirs="$orca_dirs
|
||||
$orca_dir_from_file"
|
||||
done
|
||||
printf '%s\\n' "$orca_dirs"
|
||||
}
|
||||
nvm_dirs=\${NVM_DIR:-"$HOME/.nvm"}
|
||||
nvm_dirs=$(orca_dotfile_dirs NVM_DIR "$nvm_dirs")
|
||||
printf '%s\\n' "$nvm_dirs" | while IFS= read -r nvm_dir
|
||||
do
|
||||
[ -n "$nvm_dir" ] || continue
|
||||
for candidate in "$nvm_dir"/versions/node/*/bin/node
|
||||
do
|
||||
[ -x "$candidate" ] && printf '%s\\n' "$candidate"
|
||||
done
|
||||
done
|
||||
mise_dirs=\${MISE_DATA_DIR:-\${XDG_DATA_HOME:-$HOME/.local/share}/mise}
|
||||
mise_dirs=$(orca_dotfile_dirs MISE_DATA_DIR "$mise_dirs")
|
||||
printf '%s\\n' "$mise_dirs" | while IFS= read -r mise_dir
|
||||
do
|
||||
[ -n "$mise_dir" ] || continue
|
||||
[ -x "$mise_dir/shims/node" ] && printf '%s\\n' "$mise_dir/shims/node"
|
||||
for candidate in "$mise_dir"/installs/node/*/bin/node
|
||||
do
|
||||
[ -x "$candidate" ] && printf '%s\\n' "$candidate"
|
||||
done
|
||||
done
|
||||
for candidate in \\
|
||||
/usr/local/bin/node \\
|
||||
/opt/homebrew/bin/node \\
|
||||
"$HOME/.local/bin/node" \\
|
||||
"$HOME/.fnm/aliases/default/bin/node" \\
|
||||
"$HOME/.fnm/node-versions"/*/installation/bin/node \\
|
||||
"$HOME/.local/share/fnm/node-versions"/*/installation/bin/node \\
|
||||
"$HOME/.local/share/mise/shims/node" \\
|
||||
"$HOME/.local/share/mise/installs/node"/*/bin/node \\
|
||||
"$HOME/.asdf/shims/node" \\
|
||||
"$HOME/.asdf/installs/nodejs"/*/bin/node \\
|
||||
"$HOME/.volta/bin/node" \\
|
||||
/usr/local/n/versions/node/*/bin/node
|
||||
do
|
||||
[ -x "$candidate" ] && printf '%s\\n' "$candidate"
|
||||
done
|
||||
true
|
||||
`
|
||||
Reference in New Issue
Block a user