Add full disk access checks and settings

Add background themes and custom images

Add shell command logging toggle

Add UTF-8 locale guarantee for PTY

Add Claude hook settings injection

Add hotkey system for GUI

Add glass panel styling

Add search disabled state for agent panels

Add zoom toggle command

Add device report filtering

Add entitlements for notarization

Update version to 0.1.27
This commit is contained in:
2026-06-15 22:26:06 +07:00
parent 2ee2aaaffb
commit ee845e15b3
30 changed files with 859 additions and 123 deletions
+1 -1
View File
@@ -3440,7 +3440,7 @@ dependencies = [
[[package]]
name = "spacesh-proto"
version = "0.1.10"
version = "0.1.26"
dependencies = [
"bytes",
"serde",
+16
View File
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- WKWebView's JavaScriptCore needs JIT + writable/executable memory under the
hardened runtime required for notarization. -->
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<!-- The bundle embeds the spaceshd sidecar (same Team) and loads system/webview
components; relax library validation so loading never trips the hardened runtime. -->
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
</dict>
</plist>
+48 -1
View File
@@ -534,6 +534,32 @@ pub fn open_external(url: String) -> Result<(), String> {
Ok(())
}
/// Whether spaceshell.app has Full Disk Access. Terminals spawned inside the app
/// inherit its TCC grants (the app is their "responsible process"), so without FDA
/// commands like `tmutil` fail. Probe: reading the user's TCC database requires FDA —
/// a permission error means we lack it; success (or the file being absent) means we
/// have it.
#[tauri::command]
pub fn has_full_disk_access() -> bool {
let Some(home) = std::env::var_os("HOME") else { return false };
let probe = std::path::Path::new(&home).join("Library/Application Support/com.apple.TCC/TCC.db");
match std::fs::File::open(&probe) {
Ok(_) => true,
Err(e) => e.kind() == std::io::ErrorKind::NotFound,
}
}
/// Open System Settings → Privacy & Security → Full Disk Access so the user can add
/// spaceshell. macOS cannot grant this programmatically; we only deep-link the pane.
#[tauri::command]
pub fn open_full_disk_access_settings() -> Result<(), String> {
std::process::Command::new("open")
.arg("x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles")
.spawn()
.map_err(|e| e.to_string())?;
Ok(())
}
/// List the user's installed font families (CoreText) so Settings can offer any of
/// them for the terminal. Hidden system families (".SF NS" etc.) are dropped; the
/// result is de-duplicated and sorted case-insensitively.
@@ -568,8 +594,29 @@ pub async fn set_config(
font_size: Option<u16>,
theme: Option<String>,
accent: Option<String>,
background: Option<String>,
background_image: Option<String>,
log_shell_commands: Option<bool>,
) -> Result<Value, String> {
data_of(state.request(Cmd::SetConfig { default_shell, font_family, font_size, theme, accent }).await.map_err(|e| e.to_string())?)
data_of(state.request(Cmd::SetConfig { default_shell, font_family, font_size, theme, accent, background, background_image, log_shell_commands }).await.map_err(|e| e.to_string())?)
}
/// Read a local image file and return it as a `data:` URL for use as a CSS
/// background. Kept in the GUI bridge (not the daemon) so the bytes load straight
/// into the webview without crossing the socket.
#[tauri::command]
pub async fn read_image_data_url(path: String) -> Result<String, String> {
use base64::Engine as _;
let bytes = tokio::fs::read(&path).await.map_err(|e| e.to_string())?;
let mime = match std::path::Path::new(&path).extension().and_then(|e| e.to_str()).map(|e| e.to_ascii_lowercase()).as_deref() {
Some("png") => "image/png",
Some("jpg") | Some("jpeg") => "image/jpeg",
Some("webp") => "image/webp",
Some("gif") => "image/gif",
_ => "application/octet-stream",
};
let b64 = base64::engine::general_purpose::STANDARD.encode(&bytes);
Ok(format!("data:{mime};base64,{b64}"))
}
#[tauri::command]
+3
View File
@@ -57,9 +57,12 @@ pub fn run() {
bridge::which_agents,
bridge::check_update,
bridge::open_external,
bridge::has_full_disk_access,
bridge::open_full_disk_access_settings,
bridge::list_fonts,
bridge::get_config,
bridge::set_config,
bridge::read_image_data_url,
bridge::shutdown_daemon,
])
.run(tauri::generate_context!())
+4 -1
View File
@@ -1,6 +1,9 @@
{
"$schema": "https://schema.tauri.app/config/2",
"bundle": {
"externalBin": ["bin/spaceshd"]
"externalBin": ["bin/spaceshd"],
"macOS": {
"entitlements": "Entitlements.plist"
}
}
}
+4 -2
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "spaceshell",
"version": "0.1.10",
"version": "0.1.27",
"identifier": "xyz.spacesh.app",
"build": {
"frontendDist": "../dist",
@@ -14,7 +14,9 @@
{
"title": "spaceshell",
"width": 1100,
"height": 720
"height": 720,
"titleBarStyle": "Overlay",
"hiddenTitle": true
}
],
"security": {