diff --git a/app/src-tauri/Cargo.lock b/app/src-tauri/Cargo.lock index 2ec1aa6..4126886 100644 --- a/app/src-tauri/Cargo.lock +++ b/app/src-tauri/Cargo.lock @@ -684,7 +684,6 @@ name = "dataclaw-app" version = "0.4.2" dependencies = [ "dirs 5.0.1", - "keyring", "minisign-verify", "notify", "reqwest 0.12.28", @@ -2065,16 +2064,6 @@ dependencies = [ "unicode-segmentation", ] -[[package]] -name = "keyring" -version = "3.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eebcc3aff044e5944a8fbaf69eb277d11986064cba30c468730e8b9909fb551c" -dependencies = [ - "log", - "zeroize", -] - [[package]] name = "kqueue" version = "1.1.1" diff --git a/app/src-tauri/Cargo.toml b/app/src-tauri/Cargo.toml index 8d8a72b..72d78a2 100644 --- a/app/src-tauri/Cargo.toml +++ b/app/src-tauri/Cargo.toml @@ -12,7 +12,6 @@ tauri-plugin-shell = "2" tauri-plugin-fs = "2" tauri-plugin-notification = "2" tauri-plugin-updater = "2" -keyring = "3" notify = "6" dirs = "5" serde = { version = "1", features = ["derive"] } diff --git a/app/src-tauri/src/dataclaw.rs b/app/src-tauri/src/dataclaw.rs index 3309336..852a2d3 100644 --- a/app/src-tauri/src/dataclaw.rs +++ b/app/src-tauri/src/dataclaw.rs @@ -307,7 +307,6 @@ fn base_env() -> HashMap { "LC_CTYPE", "USER", "TMPDIR", - "HF_TOKEN", "HF_HOME", "HUGGINGFACE_HUB_CACHE", ] { diff --git a/app/src-tauri/src/hf.rs b/app/src-tauri/src/hf.rs index 23eaa20..ef2d17f 100644 --- a/app/src-tauri/src/hf.rs +++ b/app/src-tauri/src/hf.rs @@ -3,14 +3,8 @@ use std::{collections::HashMap, fs}; use serde_json::{json, Value}; use tauri::AppHandle; -const SERVICE: &str = "io.dataclaw.app"; -const ACCOUNT: &str = "hf_token"; const WHOAMI_URL: &str = "https://huggingface.co/api/whoami-v2"; -fn entry() -> Result { - keyring::Entry::new(SERVICE, ACCOUNT).map_err(|e| e.to_string()) -} - pub fn hf_token_path() -> std::path::PathBuf { dirs::home_dir() .expect("home directory is required") @@ -19,7 +13,7 @@ pub fn hf_token_path() -> std::path::PathBuf { .join("token") } -fn write_mirror(token: &str) -> Result<(), String> { +fn write_token_file(token: &str) -> Result<(), String> { let path = hf_token_path(); let parent = path .parent() @@ -35,7 +29,7 @@ fn write_mirror(token: &str) -> Result<(), String> { Ok(()) } -fn read_mirror() -> Option { +fn read_token_file() -> Option { let token = fs::read_to_string(hf_token_path()).ok()?; let trimmed = token.trim(); if trimmed.is_empty() { @@ -45,7 +39,7 @@ fn read_mirror() -> Option { } } -fn delete_mirror() -> Result<(), String> { +fn delete_token_file() -> Result<(), String> { match fs::remove_file(hf_token_path()) { Ok(()) => Ok(()), Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()), @@ -53,46 +47,24 @@ fn delete_mirror() -> Result<(), String> { } } -fn try_save_keychain(token: &str) { - if let Ok(entry) = entry() { - let _ = entry.set_password(token); - } -} - -fn try_load_keychain() -> Option { - entry().ok()?.get_password().ok() -} - -fn try_delete_keychain() { - if let Ok(entry) = entry() { - let _ = entry.delete_credential(); - } -} - #[tauri::command] pub fn hf_save_token(token: String) -> Result<(), String> { let trimmed = token.trim(); if trimmed.is_empty() { return Err("token is empty".into()); } - write_mirror(trimmed)?; - try_save_keychain(trimmed); + write_token_file(trimmed)?; Ok(()) } #[tauri::command] pub fn hf_load_token() -> Result, String> { - if let Some(token) = read_mirror() { - return Ok(Some(token)); - } - Ok(try_load_keychain()) + Ok(read_token_file()) } #[tauri::command] pub fn hf_delete_token() -> Result<(), String> { - try_delete_keychain(); - let _ = delete_mirror(); - Ok(()) + delete_token_file() } pub async fn run_with_token(app: &AppHandle, args: &[&str]) -> Result { @@ -148,7 +120,7 @@ pub async fn hf_whoami(_app: AppHandle) -> Result { #[cfg(test)] mod tests { - use super::{delete_mirror, hf_token_path, write_mirror}; + use super::{delete_token_file, hf_token_path, write_token_file}; use std::{ fs, sync::Mutex, @@ -178,11 +150,11 @@ mod tests { #[cfg(unix)] #[test] - fn write_mirror_writes_token_with_chmod_600() { + fn write_token_file_writes_token_with_chmod_600() { use std::os::unix::fs::PermissionsExt; with_temp_home(|| { - write_mirror("hf_test").unwrap(); + write_token_file("hf_test").unwrap(); let path = hf_token_path(); assert_eq!(fs::read_to_string(&path).unwrap(), "hf_test"); let mode = fs::metadata(path).unwrap().permissions().mode() & 0o777; @@ -191,12 +163,12 @@ mod tests { } #[test] - fn delete_mirror_removes_file() { + fn delete_token_file_removes_file() { with_temp_home(|| { - write_mirror("hf_test").unwrap(); + write_token_file("hf_test").unwrap(); let path = hf_token_path(); assert!(path.exists()); - delete_mirror().unwrap(); + delete_token_file().unwrap(); assert!(!path.exists()); }); } diff --git a/app/src/routes/Auth.tsx b/app/src/routes/Auth.tsx index 5cc0991..a2cf4a1 100644 --- a/app/src/routes/Auth.tsx +++ b/app/src/routes/Auth.tsx @@ -109,9 +109,9 @@ export default function Auth() {

Token

- Paste a Hugging Face access token with write permission. It is stored in - macOS Keychain and mirrored to ~/.cache/huggingface/token (mode 600) so the CLI - and scheduled runs find it. Get a token at{" "} + Paste a Hugging Face access token with write permission. It is stored at{" "} + ~/.cache/huggingface/token (mode 600) so the CLI and scheduled runs find it. + Get a token at{" "} huggingface.co/settings/tokens diff --git a/scripts/build-sidecar.sh b/scripts/build-sidecar.sh index c1e7354..57c55e4 100755 --- a/scripts/build-sidecar.sh +++ b/scripts/build-sidecar.sh @@ -23,7 +23,7 @@ mkdir -p app/src-tauri/binaries cp dist/dataclaw "app/src-tauri/binaries/dataclaw-${TRIPLE}" codesign --force --sign - "app/src-tauri/binaries/dataclaw-${TRIPLE}" -SIDECAR_PATH="app/src-tauri/binaries/dataclaw-${TRIPLE}" python - <<'PY' +SIDECAR_PATH="app/src-tauri/binaries/dataclaw-${TRIPLE}" "${PYTHON_BIN}" - <<'PY' import os import subprocess