Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions crates/hk-core/src/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ use crate::{adapter, deployer, sanitize, scanner};
use std::path::{Path, PathBuf};
use std::process::Command;

/// Create a `Command` that does NOT flash a console window on Windows.
#[cfg(target_os = "windows")]
fn silent_command(program: &str) -> Command {
use std::os::windows::process::CommandExt;
let mut cmd = Command::new(program);
cmd.creation_flags(0x08000000); // CREATE_NO_WINDOW
cmd
}

#[cfg(not(target_os = "windows"))]
fn silent_command(program: &str) -> Command {
Command::new(program)
}

/// Field names under which an MCP server entry stores its environment-variable
/// block. Most agents use `"env"`; OpenCode's schema names the same block
/// `"environment"`. Centralized so secret-handling code (redaction, restore
Expand Down Expand Up @@ -614,7 +628,7 @@ pub fn check_update_with_cache(
}

pub fn get_remote_head(url: &str) -> Result<String, HkError> {
let output = Command::new("git")
let output = silent_command("git")
.args(["ls-remote", "--heads", "--", url])
.output()
.map_err(|e| HkError::CommandFailed(format!("Failed to run git ls-remote: {e}")))?;
Expand Down Expand Up @@ -659,7 +673,7 @@ pub fn install_from_git_with_id(
.map_err(|e| HkError::Internal(format!("Failed to create temp directory: {e}")))?;
let clone_dir = temp.path().join("repo");

let output = Command::new("git")
let output = silent_command("git")
.args(["clone", "--depth", "1", "--", url, &clone_dir.to_string_lossy()])
.output()
.map_err(|e| HkError::CommandFailed(format!("Failed to run git clone: {e}")))?;
Expand Down Expand Up @@ -1042,7 +1056,7 @@ fn find_skill_dir_in_tree(
/// Run `git rev-parse HEAD` in the given directory to capture the current revision.
/// Returns None if the command fails (e.g. not a git repo).
fn capture_git_revision(repo_dir: &Path) -> Option<String> {
Command::new("git")
silent_command("git")
.args(["rev-parse", "HEAD"])
.current_dir(repo_dir)
.output()
Expand Down
18 changes: 16 additions & 2 deletions crates/hk-core/src/scanner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ use std::collections::{HashMap, HashSet};
use std::path::{Path, PathBuf};
use std::sync::LazyLock;

/// Create a `Command` that does NOT flash a console window on Windows.
#[cfg(target_os = "windows")]
fn silent_command(program: &str) -> std::process::Command {
use std::os::windows::process::CommandExt;
let mut cmd = std::process::Command::new(program);
cmd.creation_flags(0x08000000); // CREATE_NO_WINDOW
cmd
}

#[cfg(not(target_os = "windows"))]
fn silent_command(program: &str) -> std::process::Command {
std::process::Command::new(program)
}

struct KnownCli {
binary_name: &'static str,
display_name: &'static str,
Expand Down Expand Up @@ -479,7 +493,7 @@ pub(crate) fn run_which(name: &str) -> Option<String> {
#[cfg(not(target_os = "windows"))]
const WHICH_CMD: &str = "which";

std::process::Command::new(WHICH_CMD)
silent_command(WHICH_CMD)
.arg(name)
.output()
.ok()
Expand Down Expand Up @@ -548,7 +562,7 @@ fn get_binary_version(name: &str) -> Option<String> {
}
static VERSION_RE: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"(\d+\.\d+(?:\.\d+)?)").unwrap());
let output = std::process::Command::new(name)
let output = silent_command(name)
.arg("--version")
.output()
.ok()?;
Expand Down
18 changes: 16 additions & 2 deletions crates/hk-desktop/src/commands/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ use hk_core::service::ExtensionContent;
use hk_core::{HkError, manager, models::*, scanner, service};
use tauri::{Emitter, State};

/// Create a `Command` that does NOT flash a console window on Windows.
#[cfg(target_os = "windows")]
fn silent_command(program: &str) -> std::process::Command {
use std::os::windows::process::CommandExt;
let mut cmd = std::process::Command::new(program);
cmd.creation_flags(0x08000000); // CREATE_NO_WINDOW
cmd
}

#[cfg(not(target_os = "windows"))]
fn silent_command(program: &str) -> std::process::Command {
std::process::Command::new(program)
}

#[tauri::command]
pub fn list_extensions(
state: State<AppState>,
Expand Down Expand Up @@ -455,7 +469,7 @@ pub async fn check_updates(
Err(_) => continue,
};
let clone_path = temp.path().join("repo");
let output = std::process::Command::new("git")
let output = silent_command("git")
.args(["clone", "--depth", "1", "--", url, &clone_path.to_string_lossy()])
.output();
let ok = output.map(|o| o.status.success()).unwrap_or(false);
Expand Down Expand Up @@ -582,7 +596,7 @@ pub async fn update_extension(
// Clone the repo once
let temp = tempfile::tempdir().map_err(|e| HkError::Internal(e.to_string()))?;
let clone_dir = temp.path().join("repo");
let output = std::process::Command::new("git")
let output = silent_command("git")
.args(["clone", "--depth", "1", "--", url, &clone_dir.to_string_lossy()])
.output()
.map_err(|e| HkError::CommandFailed(format!("Failed to run git clone: {}", e)))?;
Expand Down
18 changes: 16 additions & 2 deletions crates/hk-desktop/src/commands/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,20 @@ use super::{AppState, PendingClone};
use hk_core::{HkError, deployer, manager, marketplace, models::*, scanner, service};
use tauri::State;

/// Create a `Command` that does NOT flash a console window on Windows.
#[cfg(target_os = "windows")]
fn silent_command(program: &str) -> std::process::Command {
use std::os::windows::process::CommandExt;
let mut cmd = std::process::Command::new(program);
cmd.creation_flags(0x08000000); // CREATE_NO_WINDOW
cmd
}

#[cfg(not(target_os = "windows"))]
fn silent_command(program: &str) -> std::process::Command {
std::process::Command::new(program)
}

// --- Multi-skill git install flow ---

#[derive(serde::Serialize)]
Expand Down Expand Up @@ -219,7 +233,7 @@ pub async fn scan_git_repo(
let temp = tempfile::tempdir()?;
let clone_dir = temp.path().join("repo");

let output = std::process::Command::new("git")
let output = silent_command("git")
.args([
"clone",
"--depth",
Expand Down Expand Up @@ -476,7 +490,7 @@ pub async fn install_new_repo_skills(
let temp = tempfile::tempdir()
.map_err(|e| HkError::Internal(format!("Failed to create temp directory: {e}")))?;
let clone_dir = temp.path().join("repo");
let output = std::process::Command::new("git")
let output = silent_command("git")
.args([
"clone",
"--depth",
Expand Down
7 changes: 1 addition & 6 deletions crates/hk-desktop/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,7 @@
"width": 1280,
"height": 800,
"minWidth": 900,
"minHeight": 600,
"transparent": true,
"windowEffects": {
"effects": ["sidebar"],
"state": "followsWindowActiveState"
}
"minHeight": 600
}
],
"security": {
Expand Down
4 changes: 4 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ export default function App() {
if (!isDesktop()) {
root.setAttribute("data-web", "true");
}
// Detect Windows platform for CSS background handling
if (isDesktop() && navigator.userAgent.includes("Windows")) {
root.setAttribute("data-platform", "windows");
}
// Force macOS vibrancy to match — "light" | "dark" | null (system)
if (isDesktop()) {
getCurrentWindow()
Expand Down
6 changes: 6 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,12 @@ html.dark[data-theme="tiesen"][data-web="true"] {
#root {
background: transparent;
}
/* Windows: no vibrancy support, use solid background instead of transparent */
html[data-platform="windows"],
html[data-platform="windows"] body,
html[data-platform="windows"] #root {
background: var(--background);
}
/* Web mode: lock the browser's canvas color to our theme so the
translucent bg-sidebar/25 layer has a stable backdrop regardless of
OS prefers-color-scheme or Chrome's Force Dark Mode. `only` defeats
Expand Down