Synced from monorepo
Changes: - Classify clipboard delivery confidence - Add durable session update append - Scope the xAI session bearer to first-party memory embedding endpoints - Persist subagent outputs to disk and bound long-lived agent state - Add MiniSweAgent:bash for mini-swe-agent parity - Revert taking local sessions off the persistent shell - Contextual tip recommending grok wrap on SSH sessions - Voice STT bearer from model BYOK env_key/api_key - Define exact website policies for sandbox - Gate unsafe shell environments - Shared pin hoist; single require_sha gate for marketplace plugins - Server-signed is-managed claim (closes sidecar-removal downgrade) - Optional require_sha pin for remote plugin installs - Show session title and last exchange in the exit resume hint - Gate shell output redirects - Warn when fail_closed is present but not a boolean - Add canonical text editing core (ratatui-textarea) - Keep execution state out of goal scratch - Add acknowledged persistence primitives - Inherit child network restrictions in sandbox - Fail closed when hook matchers fail to recompile - Add MCP setup preferences for plugin MCPs - Gate sourced shell scripts - Gate file-typed project hooks - grok wrap: restore terminal modes on child death - Harden owner-only permissions on auth and MCP credentials - Create crash dump files with owner-only permissions - Write the agent_id cache owner-only (0600) - SessionMetrics mode skips Mixpanel profile sync - Dashboard: slim live-tail peek - Yank full queued prompt text, not (+N lines) - Defeat clock-rollback on the signed managed-config cache - Stop early session/cancel from overtaking the prompt and wedging the turn slot - Self-heal a diverged agent entrypoint on startup - Add matched inference expectations in test-support - Add AuthSingleFlight cancel/successor gap tests - Remove consumer from external OTEL allowlist and pin scrub coverage - Enable /copy in minimal mode - Surface capacity and API-key detail on 429 errors - Single-flight interactive auth - Fix PageUp/PageDown skipping lines behind sticky prompt header
This commit is contained in:
parent
8adf9013a0
commit
98c3b2438a
225 changed files with 18836 additions and 7156 deletions
|
|
@ -226,12 +226,13 @@ pub trait SlashCommand: Send + Sync {
|
|||
/// mode (`grok --minimal`).
|
||||
///
|
||||
/// Minimal mode deletes the interactive fullscreen scrollback pane, the
|
||||
/// in-app mouse selection/copy path, and the agent dashboard, handing
|
||||
/// scroll / search / selection back to the terminal (K7). Commands that
|
||||
/// drive those deleted surfaces — `/find`, `/copy`, `/dashboard` — have
|
||||
/// nothing to act on, so the central dispatch gate refuses them with a
|
||||
/// "/<x> is not available in minimal mode" message (committed as a system
|
||||
/// block).
|
||||
/// in-app mouse selection path, and the agent dashboard, handing scroll /
|
||||
/// search / selection back to the terminal (K7). Commands that drive those
|
||||
/// deleted surfaces — `/find`, `/dashboard` — have nothing to act on, so
|
||||
/// the central dispatch gate refuses them with a "/<x> is not available in
|
||||
/// minimal mode" message (committed as a system block). Clipboard helpers
|
||||
/// like `/copy` stay available: they read scrollback state and do not need
|
||||
/// the fullscreen pane.
|
||||
///
|
||||
/// Defaults to `true` — a **denylist, not an allowlist**: the many
|
||||
/// mode-agnostic commands keep working and new commands are available in
|
||||
|
|
|
|||
|
|
@ -31,12 +31,6 @@ impl SlashCommand for CopyCommand {
|
|||
Some("[N]")
|
||||
}
|
||||
|
||||
/// Minimal mode has no in-app copy path — native terminal selection
|
||||
/// replaces it (K7/§6.13). Gated off with a message.
|
||||
fn available_in_minimal(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn run(&self, _ctx: &mut CommandExecCtx, args: &str) -> CommandResult {
|
||||
let trimmed = args.trim();
|
||||
let n = if trimmed.is_empty() {
|
||||
|
|
@ -152,8 +146,10 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn not_available_in_minimal() {
|
||||
// Native terminal selection replaces the in-app copy path in minimal.
|
||||
assert!(!CopyCommand.available_in_minimal());
|
||||
fn available_in_minimal_by_default() {
|
||||
// Clipboard copy from scrollback does not need the fullscreen pane —
|
||||
// same path as `/export` and useful when native selection is awkward
|
||||
// for multi-page assistant messages.
|
||||
assert!(CopyCommand.available_in_minimal());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,8 +59,23 @@ impl SlashCommand for TerminalSetupCommand {
|
|||
ctx.is_tmux_backed(),
|
||||
&ctx.tmux_config_path(),
|
||||
));
|
||||
// SSH wrap recommendation — rendered as its own section below, NOT an
|
||||
// issue row: nothing is misconfigured, so it must not put "N issue(s)"
|
||||
// on every healthy SSH session. On-demand diagnostics also ignore the
|
||||
// `[ui.contextual_hints].ssh_wrap` tip opt-out: that gate (both its
|
||||
// user and remote tiers) governs the unprompted session-load tip,
|
||||
// while here the user explicitly asked for setup guidance, and an
|
||||
// environment report that omits a known improvement would be
|
||||
// incomplete.
|
||||
let ssh_wrap_recommendation = crate::diagnostics::ssh_wrap_hint(
|
||||
ctx.is_ssh,
|
||||
crate::clipboard::osc52_sink_active(),
|
||||
ctx.is_official_vscode_remote,
|
||||
);
|
||||
let route = crate::clipboard::clipboard_route();
|
||||
let is_ssh = xai_grok_shell::util::clipboard::is_remote_session();
|
||||
let container_no_display =
|
||||
xai_grok_shell::util::clipboard::is_containerized_without_display();
|
||||
|
||||
let mut out = String::new();
|
||||
|
||||
|
|
@ -123,30 +138,34 @@ impl SlashCommand for TerminalSetupCommand {
|
|||
}
|
||||
|
||||
// -- Clipboard --
|
||||
out.push_str("\nClipboard routes\n");
|
||||
out.push_str(&format!(
|
||||
" native {} (tool: {})\n",
|
||||
if route.native { "active" } else { "off" },
|
||||
xai_grok_shell::util::clipboard::native_tool_name(),
|
||||
));
|
||||
out.push_str(&format!(
|
||||
" tmux buffer {}\n",
|
||||
if route.tmux_buffer { "active" } else { "off" }
|
||||
));
|
||||
out.push_str(&format!(
|
||||
" osc 52 {}\n",
|
||||
if route.osc52 { "active" } else { "off" }
|
||||
));
|
||||
out.push_str(&format!(
|
||||
" data-control {}\n",
|
||||
crate::clipboard::wayland_data_control_label()
|
||||
));
|
||||
let display_server = crate::host::DisplayServer::current();
|
||||
let is_wayland = display_server == crate::host::DisplayServer::Wayland;
|
||||
let clipboard_diagnostics = crate::diagnostics::format_clipboard_diagnostics(
|
||||
crate::diagnostics::ClipboardDiagnosticsInput {
|
||||
route_native: route.native,
|
||||
route_tmux: route.tmux_buffer,
|
||||
route_osc52: route.osc52,
|
||||
native_tool: xai_grok_shell::util::clipboard::native_tool_name(),
|
||||
brand: ctx.brand,
|
||||
host_os: crate::host::HostOs::current(),
|
||||
display_server,
|
||||
is_ssh,
|
||||
container_no_display,
|
||||
osc52_sink: crate::clipboard::osc52_sink_active(),
|
||||
wayland_data_control: is_wayland
|
||||
&& xai_grok_shell::util::clipboard::wayland_data_control_supported(),
|
||||
wl_copy_available: is_wayland
|
||||
&& xai_grok_shell::util::clipboard::native_tool_name() == "wl-copy",
|
||||
},
|
||||
);
|
||||
out.push('\n');
|
||||
out.push_str(&clipboard_diagnostics.text);
|
||||
|
||||
// -- Diagnostics --
|
||||
if warnings.is_empty() {
|
||||
if warnings.is_empty() && !clipboard_diagnostics.has_issue {
|
||||
out.push_str("\nNo issues found.\n");
|
||||
} else {
|
||||
out.push_str(&format!("\n{} issue(s)\n", warnings.len()));
|
||||
} else if !warnings.is_empty() {
|
||||
out.push_str(&format!("\n{} additional issue(s)\n", warnings.len()));
|
||||
for w in &warnings {
|
||||
out.push_str(&format!("\n [!] {}\n", w.message));
|
||||
match (w.fix.as_deref(), w.config_path.as_deref()) {
|
||||
|
|
@ -164,6 +183,17 @@ impl SlashCommand for TerminalSetupCommand {
|
|||
}
|
||||
}
|
||||
|
||||
// -- Recommendation --
|
||||
if let Some(rec) = ssh_wrap_recommendation {
|
||||
out.push_str(&format!("\nRecommendation\n\n {}\n", rec.message));
|
||||
if let Some(fix) = rec.fix.as_deref() {
|
||||
out.push_str(&format!(" Run: `{}`\n", fix));
|
||||
}
|
||||
if let Some(note) = rec.note.as_deref() {
|
||||
out.push_str(&format!(" Note: {}\n", note));
|
||||
}
|
||||
}
|
||||
|
||||
CommandResult::Message(out)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue