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:
grokkybara[bot] 2026-07-16 20:27:30 +01:00
commit 8adf9013a0
117 changed files with 16998 additions and 14540 deletions

View file

@ -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));

View file

@ -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 }
}

View file

@ -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,

View file

@ -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]