Synced from monorepo
Changes: - grok-shell: request workspaces:read/write OAuth2 scopes - security: fix SSRF bypass via HTTP redirect in hook runner - fix(grok-build): enterprise STT WSS URL + API-key voice bearer - Harden identity-change purge and sync-marker invariants - sandbox + workspace-server: delete the legacy ready-file arm - Show billing URL when browser cannot open - fix(pager): show folder-trust UI in minimal mode - fix(pager): drain task_backgrounded before no-wait headless exit - grok-agent-sdk: stop SDK-spawned agents from staging self-updates they can never adopt - Split settings_modal into directory module - Delegate VS Code SSH file links - grok-shell: release the workspace session binding when a session is removed - keep skills reachable when their name collides with a client builtin - Preserve semantic link targets
This commit is contained in:
parent
c68e39f604
commit
8adf9013a0
117 changed files with 16998 additions and 14540 deletions
|
|
@ -75,7 +75,7 @@ pub fn scrollback_inline_overlay_forced_off() -> bool {
|
|||
INLINE_OVERLAY_FORCE_OFF.load(Ordering::Relaxed)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
thread_local! {
|
||||
/// Per-test override so tests don't depend on the host terminal or the
|
||||
/// process-wide `GRAPHICS_PROTOCOL` cache.
|
||||
|
|
@ -85,7 +85,7 @@ thread_local! {
|
|||
|
||||
/// Detect and cache the graphics protocol for the current terminal.
|
||||
pub fn detect_graphics_protocol() -> GraphicsProtocol {
|
||||
#[cfg(test)]
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
if let Some(p) = TEST_PROTOCOL_OVERRIDE.with(|c| c.get()) {
|
||||
return p;
|
||||
}
|
||||
|
|
@ -119,12 +119,12 @@ pub fn scrollback_inline_overlay_active() -> bool {
|
|||
scrollback_inline_overlay_active_for_brand(protocol, terminal_context().brand)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
fn test_protocol_override_active() -> bool {
|
||||
TEST_PROTOCOL_OVERRIDE.with(|c| c.get().is_some())
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
#[cfg(not(any(test, feature = "test-support")))]
|
||||
fn test_protocol_override_active() -> bool {
|
||||
false
|
||||
}
|
||||
|
|
@ -145,17 +145,17 @@ fn scrollback_inline_overlay_active_for_brand(
|
|||
|
||||
/// Set a per-thread protocol override for tests. Returns a guard that
|
||||
/// clears it on drop.
|
||||
#[cfg(test)]
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn set_protocol_for_test(p: GraphicsProtocol) -> TestProtocolGuard {
|
||||
TEST_PROTOCOL_OVERRIDE.with(|c| c.set(Some(p)));
|
||||
TestProtocolGuard
|
||||
}
|
||||
|
||||
/// RAII guard that clears the test protocol override on drop.
|
||||
#[cfg(test)]
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub struct TestProtocolGuard;
|
||||
|
||||
#[cfg(test)]
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
impl Drop for TestProtocolGuard {
|
||||
fn drop(&mut self) {
|
||||
TEST_PROTOCOL_OVERRIDE.with(|c| c.set(None));
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ impl ModifierDelivery {
|
|||
/// Construct a delivery from explicit fates. `#[non_exhaustive]` blocks
|
||||
/// struct-literal construction from other crates, so downstream test
|
||||
/// builds use this constructor.
|
||||
#[cfg(test)]
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
pub fn new_for_test(cmd: ModifierFate, opt: ModifierFate) -> Self {
|
||||
Self { cmd, opt }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -282,6 +282,8 @@ pub struct TerminalContext {
|
|||
pub tmux_meta: TmuxClientMeta,
|
||||
/// Whether the session is inside a remote SSH connection.
|
||||
pub is_ssh: bool,
|
||||
/// Positive evidence that SSH is hosted by the official VS Code remote server.
|
||||
pub is_official_vscode_remote: bool,
|
||||
/// The raw `TERM` environment variable (e.g. `xterm-256color`, `screen`).
|
||||
pub term_var: Option<String>,
|
||||
/// The tmux server version (e.g. `"tmux 3.4"`), populated only when
|
||||
|
|
@ -666,6 +668,16 @@ fn env_get<'a>(env: &'a HashMap<String, String>, key: &str) -> Option<&'a str> {
|
|||
env.get(key).map(|v| v.as_str()).filter(|v| !v.is_empty())
|
||||
}
|
||||
|
||||
fn is_official_vscode_remote_askpass(path: &str) -> bool {
|
||||
std::path::Path::new(path).components().any(|component| {
|
||||
matches!(
|
||||
component,
|
||||
std::path::Component::Normal(name)
|
||||
if name == ".vscode-server" || name == ".vscode-server-insiders"
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Detect the terminal brand from an injected environment map.
|
||||
///
|
||||
/// This is the pure equivalent of the original `detect_terminal_info`.
|
||||
|
|
@ -935,6 +947,8 @@ pub fn build_terminal_context_from_env(env: &HashMap<String, String>) -> Termina
|
|||
let is_ssh = env_get(env, "SSH_CONNECTION").is_some()
|
||||
|| env_get(env, "SSH_TTY").is_some()
|
||||
|| env_get(env, "SSH_CLIENT").is_some();
|
||||
let is_official_vscode_remote = is_ssh
|
||||
&& env_get(env, "VSCODE_GIT_ASKPASS_MAIN").is_some_and(is_official_vscode_remote_askpass);
|
||||
let term_var = env_get(env, "TERM").map(|s| s.to_owned());
|
||||
let vte_version = env_get(env, "VTE_VERSION").map(|s| s.to_owned());
|
||||
// SSH strips TERM_PROGRAM_VERSION; iTerm2 LC_TERMINAL_VERSION survives.
|
||||
|
|
@ -950,6 +964,7 @@ pub fn build_terminal_context_from_env(env: &HashMap<String, String>) -> Termina
|
|||
embedded_editor,
|
||||
tmux_meta,
|
||||
is_ssh,
|
||||
is_official_vscode_remote,
|
||||
term_var,
|
||||
tmux_version: None,
|
||||
vte_version,
|
||||
|
|
|
|||
|
|
@ -1054,6 +1054,52 @@ fn brand_vscode_from_askpass_without_term_program() {
|
|||
assert_eq!(detect_terminal_brand_from_env(&env), TerminalName::VsCode);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn context_official_vscode_remote_from_askpass_and_ssh() {
|
||||
for server_dir in [".vscode-server", ".vscode-server-insiders"] {
|
||||
let askpass = format!("/home/user/{server_dir}/bin/abc/askpass");
|
||||
let env = env_from(&[
|
||||
("VSCODE_GIT_ASKPASS_MAIN", &askpass),
|
||||
("SSH_CONNECTION", "192.0.2.1 50000 192.0.2.2 22"),
|
||||
]);
|
||||
let ctx = build_terminal_context_from_env(&env);
|
||||
assert_eq!(ctx.brand, TerminalName::VsCode);
|
||||
assert!(ctx.is_ssh);
|
||||
assert!(ctx.is_official_vscode_remote, "{server_dir}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn context_unofficial_vscode_remote_markers_are_not_official() {
|
||||
for askpass in [
|
||||
"/home/user/.vscode-server-oss/bin/abc/askpass",
|
||||
"/home/user/.vscodium-server/bin/abc/askpass",
|
||||
"/home/user/.code-oss-server/bin/abc/askpass",
|
||||
"/home/user/cache/.vscode-server-oss/.vscode-serverish/askpass",
|
||||
"/usr/local/bin/askpass-main.js",
|
||||
] {
|
||||
let env = env_from(&[
|
||||
("VSCODE_GIT_ASKPASS_MAIN", askpass),
|
||||
("SSH_CONNECTION", "192.0.2.1 50000 192.0.2.2 22"),
|
||||
]);
|
||||
let ctx = build_terminal_context_from_env(&env);
|
||||
assert_eq!(ctx.brand, TerminalName::VsCode);
|
||||
assert!(ctx.is_ssh);
|
||||
assert!(!ctx.is_official_vscode_remote, "{askpass}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn official_vscode_server_marker_without_ssh_is_not_remote() {
|
||||
let env = env_from(&[(
|
||||
"VSCODE_GIT_ASKPASS_MAIN",
|
||||
"/home/user/.vscode-server/bin/abc/askpass",
|
||||
)]);
|
||||
let ctx = build_terminal_context_from_env(&env);
|
||||
assert!(!ctx.is_ssh);
|
||||
assert!(!ctx.is_official_vscode_remote);
|
||||
}
|
||||
|
||||
// -- Zellij detection from ZELLIJ_VERSION (no ZELLIJ or SESSION_NAME) -----
|
||||
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Reference in a new issue