Skip to content

Commit 8ee3663

Browse files
h5kkclaude
andcommitted
windows: extend suppress_child_console sweep to per-turn / refresh hot paths
The previous sweep (ad139a9) covered bash/ambient/selfdev/agent. Sites that fire on every model turn or every side-panel refresh were still flashing console windows on Windows. Apply the same helper to: - src/prompt.rs (3x git probes per system-prompt build): rev-parse --is-inside-work-tree, branch --show-current, status --porcelain. Runs every turn, so this was the dominant flicker source. - src/build/source_state.rs (git_output_bytes helper covers 1 site; current_git_hash, current_git_hash_full, current_git_diff, is_working_tree_dirty, get_commit_message — 5 more sites): side-panel git state refresh, periodic / on file watch. - src/build.rs::dirty_status_paths (build freshness git probe). - src/auth/copilot.rs (gh auth token probe). - src/auth/cursor.rs::read_vscdb_key (sqlite3 probe). - src/cli/commands.rs::detect_tailscale_dns_name (tailscale probe). All call sites already had stdio either piped or one-shot Output, so suppressing the console allocation is purely cosmetic on the Windows detached-server path. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 1d19eab commit 8ee3663

6 files changed

Lines changed: 63 additions & 49 deletions

File tree

src/auth/copilot.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,10 @@ fn load_token_from_gh_cli() -> Option<String> {
443443
return None;
444444
}
445445

446-
let output = Command::new("gh").args(["auth", "token"]).output().ok()?;
446+
let mut cmd = Command::new("gh");
447+
cmd.args(["auth", "token"]);
448+
crate::platform::suppress_child_console(&mut cmd);
449+
let output = cmd.output().ok()?;
447450
if !output.status.success() {
448451
return None;
449452
}

src/auth/cursor.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,12 +234,13 @@ fn cursor_vscdb_paths() -> Vec<PathBuf> {
234234

235235
/// Read a key from a vscdb file using the sqlite3 CLI.
236236
fn read_vscdb_key(db_path: &PathBuf, key: &str) -> Result<String> {
237-
let output = std::process::Command::new("sqlite3")
238-
.arg(db_path)
239-
.arg(format!(
240-
"SELECT value FROM ItemTable WHERE key = '{}';",
241-
key
242-
))
237+
let mut cmd = std::process::Command::new("sqlite3");
238+
cmd.arg(db_path).arg(format!(
239+
"SELECT value FROM ItemTable WHERE key = '{}';",
240+
key
241+
));
242+
crate::platform::suppress_child_console(&mut cmd);
243+
let output = cmd
243244
.output()
244245
.context("Failed to run sqlite3 (is it installed?)")?;
245246

src/build.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -457,10 +457,11 @@ fn validate_binary_version_matches_source_report(
457457
}
458458

459459
fn dirty_status_paths(repo_dir: &Path) -> Result<Vec<(PathBuf, bool)>> {
460-
let output = Command::new("git")
461-
.args(["status", "--porcelain=v1", "-z", "--untracked-files=all"])
462-
.current_dir(repo_dir)
463-
.output()?;
460+
let mut cmd = Command::new("git");
461+
cmd.args(["status", "--porcelain=v1", "-z", "--untracked-files=all"])
462+
.current_dir(repo_dir);
463+
crate::platform::suppress_child_console(&mut cmd);
464+
let output = cmd.output()?;
464465
if !output.status.success() {
465466
anyhow::bail!(
466467
"git status failed while validating dirty build freshness with status {:?}",

src/build/source_state.rs

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ fn hash_path_scope(path: &Path) -> String {
3333
}
3434

3535
fn git_output_bytes(repo_dir: &Path, args: &[&str]) -> Result<Vec<u8>> {
36-
let output = Command::new("git")
37-
.args(args)
38-
.current_dir(repo_dir)
39-
.output()?;
36+
let mut cmd = Command::new("git");
37+
cmd.args(args).current_dir(repo_dir);
38+
crate::platform::suppress_child_console(&mut cmd);
39+
let output = cmd.output()?;
4040
if !output.status.success() {
4141
anyhow::bail!(
4242
"git {} failed with status {:?}",
@@ -155,10 +155,11 @@ pub fn repo_build_version(repo_dir: &Path) -> Result<String> {
155155

156156
/// Get the current git hash
157157
pub fn current_git_hash(repo_dir: &Path) -> Result<String> {
158-
let output = Command::new("git")
159-
.args(["rev-parse", "--short", "HEAD"])
160-
.current_dir(repo_dir)
161-
.output()?;
158+
let mut cmd = Command::new("git");
159+
cmd.args(["rev-parse", "--short", "HEAD"])
160+
.current_dir(repo_dir);
161+
crate::platform::suppress_child_console(&mut cmd);
162+
let output = cmd.output()?;
162163

163164
if !output.status.success() {
164165
anyhow::bail!("Failed to get git hash");
@@ -169,10 +170,10 @@ pub fn current_git_hash(repo_dir: &Path) -> Result<String> {
169170

170171
/// Get the full git hash
171172
pub fn current_git_hash_full(repo_dir: &Path) -> Result<String> {
172-
let output = Command::new("git")
173-
.args(["rev-parse", "HEAD"])
174-
.current_dir(repo_dir)
175-
.output()?;
173+
let mut cmd = Command::new("git");
174+
cmd.args(["rev-parse", "HEAD"]).current_dir(repo_dir);
175+
crate::platform::suppress_child_console(&mut cmd);
176+
let output = cmd.output()?;
176177

177178
if !output.status.success() {
178179
anyhow::bail!("Failed to get git hash");
@@ -183,30 +184,31 @@ pub fn current_git_hash_full(repo_dir: &Path) -> Result<String> {
183184

184185
/// Get the git diff for uncommitted changes
185186
pub fn current_git_diff(repo_dir: &Path) -> Result<String> {
186-
let output = Command::new("git")
187-
.args(["diff", "HEAD"])
188-
.current_dir(repo_dir)
189-
.output()?;
187+
let mut cmd = Command::new("git");
188+
cmd.args(["diff", "HEAD"]).current_dir(repo_dir);
189+
crate::platform::suppress_child_console(&mut cmd);
190+
let output = cmd.output()?;
190191

191192
Ok(String::from_utf8_lossy(&output.stdout).to_string())
192193
}
193194

194195
/// Check if working tree is dirty
195196
pub fn is_working_tree_dirty(repo_dir: &Path) -> Result<bool> {
196-
let output = Command::new("git")
197-
.args(["status", "--porcelain"])
198-
.current_dir(repo_dir)
199-
.output()?;
197+
let mut cmd = Command::new("git");
198+
cmd.args(["status", "--porcelain"]).current_dir(repo_dir);
199+
crate::platform::suppress_child_console(&mut cmd);
200+
let output = cmd.output()?;
200201

201202
Ok(!output.stdout.is_empty())
202203
}
203204

204205
/// Get commit message for a hash
205206
pub fn get_commit_message(repo_dir: &Path, hash: &str) -> Result<String> {
206-
let output = Command::new("git")
207-
.args(["log", "-1", "--format=%s", hash])
208-
.current_dir(repo_dir)
209-
.output()?;
207+
let mut cmd = Command::new("git");
208+
cmd.args(["log", "-1", "--format=%s", hash])
209+
.current_dir(repo_dir);
210+
crate::platform::suppress_child_console(&mut cmd);
211+
let output = cmd.output()?;
210212

211213
Ok(String::from_utf8_lossy(&output.stdout).trim().to_string())
212214
}

src/cli/commands.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -520,10 +520,10 @@ pub fn parse_tailscale_dns_name(status_json: &[u8]) -> Option<String> {
520520
}
521521

522522
pub fn detect_tailscale_dns_name() -> Option<String> {
523-
let output = std::process::Command::new("tailscale")
524-
.args(["status", "--json"])
525-
.output()
526-
.ok()?;
523+
let mut cmd = std::process::Command::new("tailscale");
524+
cmd.args(["status", "--json"]);
525+
crate::platform::suppress_child_console(&mut cmd);
526+
let output = cmd.output().ok()?;
527527

528528
if !output.status.success() {
529529
return None;

src/prompt.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -406,12 +406,15 @@ fn build_env_context() -> Option<String> {
406406
/// Get git branch and status summary
407407
fn get_git_info() -> Option<String> {
408408
// Check if we're in a git repo
409-
let in_repo = Command::new("git")
410-
.args(["rev-parse", "--is-inside-work-tree"])
411-
.output()
412-
.ok()
413-
.map(|o| o.status.success())
414-
.unwrap_or(false);
409+
let in_repo = {
410+
let mut cmd = Command::new("git");
411+
cmd.args(["rev-parse", "--is-inside-work-tree"]);
412+
crate::platform::suppress_child_console(&mut cmd);
413+
cmd.output()
414+
.ok()
415+
.map(|o| o.status.success())
416+
.unwrap_or(false)
417+
};
415418

416419
if !in_repo {
417420
return None;
@@ -420,9 +423,10 @@ fn get_git_info() -> Option<String> {
420423
let mut info = vec!["Git:".to_string()];
421424

422425
// Current branch
423-
if let Ok(output) = Command::new("git")
424-
.args(["branch", "--show-current"])
425-
.output()
426+
let mut branch_cmd = Command::new("git");
427+
branch_cmd.args(["branch", "--show-current"]);
428+
crate::platform::suppress_child_console(&mut branch_cmd);
429+
if let Ok(output) = branch_cmd.output()
426430
&& output.status.success()
427431
{
428432
let branch = String::from_utf8_lossy(&output.stdout).trim().to_string();
@@ -432,7 +436,10 @@ fn get_git_info() -> Option<String> {
432436
}
433437

434438
// Short status (modified files count)
435-
if let Ok(output) = Command::new("git").args(["status", "--porcelain"]).output()
439+
let mut status_cmd = Command::new("git");
440+
status_cmd.args(["status", "--porcelain"]);
441+
crate::platform::suppress_child_console(&mut status_cmd);
442+
if let Ok(output) = status_cmd.output()
436443
&& output.status.success()
437444
{
438445
let status = String::from_utf8_lossy(&output.stdout);

0 commit comments

Comments
 (0)