Synced from monorepo
Synced from monorepo Changes: - Shell: accept target response id on rewind execute - Shell: stamp response id on chat user message chunks - Worktree: optional rebuild and stale git registration cleanup in auto-GC - Worktree: kind-aware auto-GC TTLs and config knobs - Worktree: macOS process CWD scan and Unix PID liveness for GC guards - Worktree: automatic throttled GC on startup (Linux age-based; non-Linux dead-only) - Pager: add `[ui].combine_queued_prompts` to batch queued follow-ups - Shell: stop overwriting user skills - Tools: read markdown in `skills/` directories untruncated - `/usage` shows per-session token and dollar usage in the TUI - Security: prompt on environment-dumping `ps` variants - Security: always-safe `kubectl` no longer runs arbitrary kubeconfig credential plugins without permission - Tools: make scheduler deletion durable - Shell: add relocation storage primitives - Shell: give side model calls their own conversation ids - Fix five workflow-runtime bugs (budget, pause, cancel, reconnect) - Security: peel `env -S` / `--split-string` operands in the Bash permission gate (managed deny/ask) - Pager: expose doctor in the TUI - Security: block unauthorized RCE via abused safe commands - Pager idle watcher cue: "1 subagent still running" instead of "watching · 1 subagent" - Security: block `rg --pre` arbitrary code execution in auto-mode - Voice: diagnose silent-mic failures (macOS permission) and add doctor/terminal-setup Voice section - App builder deployer: `allow_forking` and `show_built_with_grok` - Pager: stop stacking duplicate "Worked for" markers on parked turns - Shell: support `max` as a distinct reasoning effort tier - Tools: serialize background `/loop` fires on the whole work unit - Shell: add working-directory relocation state primitives - Proto: `ClientToolResult` and `ChatConfig` client-side tools - Shell: model providers - Chat: select App Builder product on the Build path - Shell: attach author identity to feedback when the deployment opts in - Doctor: fix for SSH wrap setup - Workflow authoring skills: create-workflow and import-claude-workflow docs - Add read-only grok doctor - Sandbox: apply Landlock without a controlling TTY - Pager: recover image paste over grok wrap on headless remotes - Pager: make actions screen-mode aware - Shell: resume sessions when the working directory moves - Pager: centralize terminal diagnostics - Workspace: gate inline shell file access - Pager: centralize terminal probes - Pager: edit minimal prompts in an external editor - Pager: standardize backgrounding on Ctrl+B - Shell: recap rides the parent turn's prompt cache - Tools: add scheduler lifecycle version clock Source-Revision: 0f4d7c91b8b2b408333f6de1e8a76cb8eaa71899
This commit is contained in:
parent
a881e6703f
commit
3af4d5d398
556 changed files with 56609 additions and 21892 deletions
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "xai-grok-pager-bin"
|
||||
version = "0.2.106"
|
||||
version = "0.2.109"
|
||||
edition.workspace = true
|
||||
license = "Apache-2.0"
|
||||
authors = ["xAI"]
|
||||
|
|
|
|||
|
|
@ -1604,7 +1604,46 @@ fn install_heap_profile_hooks() {
|
|||
prof_available: jemalloc_prof_available,
|
||||
});
|
||||
}
|
||||
fn version_text(channel_label: &str) -> String {
|
||||
format!(
|
||||
"grok {}\n",
|
||||
xai_grok_version::display_version_with_commit(env!("VERSION_WITH_COMMIT"), channel_label,)
|
||||
)
|
||||
}
|
||||
fn write_version(writer: &mut impl std::io::Write, channel_label: &str) -> std::io::Result<()> {
|
||||
writer.write_all(version_text(channel_label).as_bytes())
|
||||
}
|
||||
fn dispatch_version_if_requested(args: &PagerArgs) -> bool {
|
||||
if !args.version {
|
||||
return false;
|
||||
}
|
||||
if let Err(error) = write_version(
|
||||
&mut std::io::stdout().lock(),
|
||||
xai_grok_update::channel_label(),
|
||||
) {
|
||||
eprintln!("Error: {error}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
true
|
||||
}
|
||||
fn dispatch_doctor_if_requested(args: &PagerArgs) -> bool {
|
||||
let Some(Command::Doctor(doctor_args)) = &args.command else {
|
||||
return false;
|
||||
};
|
||||
if let Err(error) = xai_grok_pager::doctor_cmd::run(doctor_args.clone()) {
|
||||
eprintln!("Error: {error:#}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
true
|
||||
}
|
||||
fn main() {
|
||||
if let Some(code) = xai_grok_pager::app::mermaid_worker::maybe_run_render_subprocess() {
|
||||
std::process::exit(code);
|
||||
}
|
||||
let args = PagerArgs::parse_cli();
|
||||
if dispatch_version_if_requested(&args) || dispatch_doctor_if_requested(&args) {
|
||||
return;
|
||||
}
|
||||
xai_grok_pager_minimal::install();
|
||||
#[cfg(all(feature = "jemalloc", unix))]
|
||||
xai_grok_pager::memory_release::install_release_hook(purge_jemalloc_retained_pages);
|
||||
|
|
@ -1615,9 +1654,6 @@ fn main() {
|
|||
}
|
||||
#[cfg(all(feature = "jemalloc", unix))]
|
||||
install_heap_profile_hooks();
|
||||
if let Some(code) = xai_grok_pager::app::mermaid_worker::maybe_run_render_subprocess() {
|
||||
std::process::exit(code);
|
||||
}
|
||||
xai_grok_pager::memory_trace::start(
|
||||
xai_grok_shell::util::grok_home::grok_home().join("memtrace"),
|
||||
);
|
||||
|
|
@ -1669,7 +1705,7 @@ fn main() {
|
|||
.enable_all()
|
||||
.build()
|
||||
.unwrap_or_else(|e| panic!("failed to start tokio runtime: {e}"));
|
||||
let result = run_and_shutdown(runtime, async_main(), RUNTIME_SHUTDOWN_GRACE);
|
||||
let result = run_and_shutdown(runtime, async_main(args), RUNTIME_SHUTDOWN_GRACE);
|
||||
xai_grok_telemetry::debug_log::flush();
|
||||
if let Err(e) = result {
|
||||
xai_tty_utils::restore_native_stderr();
|
||||
|
|
@ -1678,9 +1714,9 @@ fn main() {
|
|||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
async fn async_main() -> Result<()> {
|
||||
async fn async_main(args: PagerArgs) -> Result<()> {
|
||||
let _ = rustls::crypto::ring::default_provider().install_default();
|
||||
let mut args = PagerArgs::parse_and_apply_cwd()?;
|
||||
let mut args = args.apply_cwd()?;
|
||||
if let Some(ref mode) = args.compaction_mode {
|
||||
unsafe { std::env::set_var("GROK_COMPACTION_MODE", mode) };
|
||||
}
|
||||
|
|
@ -1755,13 +1791,10 @@ async fn async_main() -> Result<()> {
|
|||
);
|
||||
println!("{}", serde_json::to_string(&payload)?);
|
||||
} else {
|
||||
println!(
|
||||
"grok {}",
|
||||
xai_grok_version::display_version_with_commit(
|
||||
env!("VERSION_WITH_COMMIT"),
|
||||
xai_grok_update::channel_label(),
|
||||
)
|
||||
);
|
||||
write_version(
|
||||
&mut std::io::stdout().lock(),
|
||||
xai_grok_update::channel_label(),
|
||||
)?;
|
||||
}
|
||||
return Ok(());
|
||||
}
|
||||
|
|
@ -1788,6 +1821,9 @@ async fn async_main() -> Result<()> {
|
|||
)
|
||||
.await;
|
||||
}
|
||||
Command::Doctor(_) => {
|
||||
unreachable!("doctor was consumed before runtime startup")
|
||||
}
|
||||
Command::Inspect { json } => {
|
||||
let cwd = std::env::current_dir().unwrap_or_default();
|
||||
xai_grok_shell::inspect::inspect(&cwd, json).await?;
|
||||
|
|
@ -1952,16 +1988,10 @@ async fn async_main() -> Result<()> {
|
|||
.as_deref()
|
||||
.map(xai_grok_pager::headless::parse_json_schema)
|
||||
.transpose()?;
|
||||
if json_schema.is_some() {
|
||||
if args.output_format == xai_grok_pager::headless::OutputFormat::Plain {
|
||||
args.output_format = xai_grok_pager::headless::OutputFormat::Json;
|
||||
}
|
||||
if args.self_verify {
|
||||
anyhow::bail!(
|
||||
"--json-schema and --self-verify cannot be used together: \
|
||||
verification output would corrupt the structured response"
|
||||
);
|
||||
}
|
||||
if json_schema.is_some()
|
||||
&& args.output_format == xai_grok_pager::headless::OutputFormat::Plain
|
||||
{
|
||||
args.output_format = xai_grok_pager::headless::OutputFormat::Json;
|
||||
}
|
||||
return xai_grok_pager::headless::run_single_turn(
|
||||
prompt,
|
||||
|
|
@ -1991,8 +2021,6 @@ async fn async_main() -> Result<()> {
|
|||
max_turns: args.max_turns,
|
||||
permission_mode_flag: args.permission_mode_flag.clone(),
|
||||
reasoning_effort: args.reasoning_effort.clone(),
|
||||
self_verify: args.self_verify,
|
||||
best_of_n: args.best_of_n,
|
||||
wait_for_background: !args.no_wait_for_background,
|
||||
background_wait_timeout: std::time::Duration::from_secs(
|
||||
args.background_wait_timeout_secs,
|
||||
|
|
@ -2278,6 +2306,36 @@ async fn signal_leaders_to_relaunch(installed_version: &str) {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn version_output_writer_preserves_channel_aware_contract() {
|
||||
for (label, expected_suffix) in [
|
||||
(" [alpha]", " [alpha]\n"),
|
||||
(" [stable]", " [stable]\n"),
|
||||
("", ")\n"),
|
||||
] {
|
||||
let mut output = Vec::new();
|
||||
write_version(&mut output, label).unwrap();
|
||||
let output = String::from_utf8(output).unwrap();
|
||||
assert!(output.starts_with("grok "));
|
||||
assert!(output.contains(env!("VERSION_WITH_COMMIT")));
|
||||
assert!(output.ends_with(expected_suffix), "{output:?}");
|
||||
}
|
||||
}
|
||||
#[test]
|
||||
fn version_flags_and_doctor_are_distinct_early_intents() {
|
||||
let version = PagerArgs::try_parse_from(["grok", "--version"]).unwrap();
|
||||
assert!(version.version);
|
||||
assert!(version.command.is_none());
|
||||
let short = PagerArgs::try_parse_from(["grok", "-v"]).unwrap();
|
||||
assert!(short.version);
|
||||
assert!(short.command.is_none());
|
||||
let subcommand = PagerArgs::try_parse_from(["grok", "version"]).unwrap();
|
||||
assert!(!subcommand.version);
|
||||
assert!(matches!(
|
||||
subcommand.command,
|
||||
Some(Command::Version { json: false })
|
||||
));
|
||||
}
|
||||
#[cfg(all(feature = "jemalloc", unix))]
|
||||
struct TempHeapDump(std::path::PathBuf);
|
||||
#[cfg(all(feature = "jemalloc", unix))]
|
||||
|
|
|
|||
Loading…
Reference in a new issue