Release version 0.2.6

非活跃连接在 1 分钟内没有活动就会被自动断开;
临时会话被顶替后立即断开连接;
设置界面支持版本控制、github账号管理、Git服务器管理;
增强git凭据处理,现在需要认证时会弹框来支持凭据自动处理。
This commit is contained in:
xintaofei
2026-03-21 15:40:07 +08:00
parent 7f5193d861
commit d6098df1a8
3 changed files with 300 additions and 23 deletions

View File

@@ -1,22 +1,84 @@
use std::collections::HashMap;
use tauri::Manager;
use tauri::State;
use crate::db::AppDatabase;
use crate::git_credential;
use crate::terminal::error::TerminalError;
use crate::terminal::manager::TerminalManager;
use crate::terminal::manager::{SpawnOptions, TerminalManager};
use crate::terminal::types::TerminalInfo;
/// Build extra env vars and a temp credential file for the terminal session.
///
/// Uses `GIT_ASKPASS` with a terminal-specific askpass script that reads from
/// a credential store file. This approach does NOT override the user's
/// existing `credential.helper` configuration (e.g. macOS Keychain).
async fn prepare_credential_env(
db: &AppDatabase,
app_data_dir: &std::path::Path,
terminal_id: &str,
) -> (Option<HashMap<String, String>>, Option<std::path::PathBuf>) {
let accounts = match git_credential::load_github_accounts(&db.conn).await {
Some(s) if !s.accounts.is_empty() => s.accounts,
_ => return (None, None),
};
let cred_file = app_data_dir.join(format!("git-creds-{}.tmp", terminal_id));
if let Err(e) = git_credential::write_credential_store_file(&accounts, &cred_file) {
eprintln!("[TERM] failed to write credential store file: {}", e);
return (None, None);
}
let askpass_script =
match git_credential::create_terminal_askpass_script(app_data_dir, &cred_file) {
Ok(p) => p,
Err(e) => {
eprintln!("[TERM] failed to create terminal askpass script: {}", e);
let _ = std::fs::remove_file(&cred_file);
return (None, None);
}
};
let mut env = HashMap::new();
env.insert(
"GIT_ASKPASS".to_string(),
askpass_script.to_string_lossy().to_string(),
);
(Some(env), Some(cred_file))
}
#[tauri::command]
pub fn terminal_spawn(
pub async fn terminal_spawn(
working_dir: String,
initial_command: Option<String>,
manager: State<'_, TerminalManager>,
db: State<'_, AppDatabase>,
app_handle: tauri::AppHandle,
window: tauri::WebviewWindow,
) -> Result<String, TerminalError> {
manager.spawn(
working_dir,
window.label().to_string(),
// Generate terminal ID early so we can use it for the credential file name
let terminal_id = uuid::Uuid::new_v4().to_string();
let app_data_dir = app_handle
.path()
.app_data_dir()
.map_err(|e| TerminalError::SpawnFailed(e.to_string()))?;
let (extra_env, cred_file) =
prepare_credential_env(&db, &app_data_dir, &terminal_id).await;
manager.spawn_with_id(
SpawnOptions {
terminal_id,
working_dir,
owner_window_label: window.label().to_string(),
initial_command,
extra_env,
credential_file: cred_file,
},
app_handle,
initial_command,
)
}