自动隔离损坏的策划会话并修复 CI
Project CI / Repository checks (pull_request) Successful in 2m40s
Project CI / Frontend tests (pull_request) Successful in 3m20s
Project CI / Backend tests (pull_request) Successful in 6m3s
Project CI / Native shell tests (pull_request) Successful in 17m48s

会话读取损坏时自动备份并允许项目继续打开

登记会话重置命令并补齐 Native shell 配置检查
This commit is contained in:
2026-09-12 07:48:07 +00:00
parent f505d2792f
commit 2e87a1403a
2 changed files with 32 additions and 8 deletions
@@ -114,6 +114,7 @@ const allowedUncalledTauriCommands = [
'open_game_creator_launcher_window',
'open_game_creator_workspace_window',
'read_direct_project_conversation',
'reset_design_agent_session',
'stop_local_game_preview_if_matches',
'start_game_creator_external_mcp',
'stop_game_creator_external_mcp',
@@ -835,7 +835,15 @@ pub(crate) fn hydrate_design_agent_session(
return Ok(None);
}
let project_id = design_project_id(root)?;
let Some(session) = read_design_session(root)? else {
let session = match read_design_session(root) {
Ok(session) => session,
Err(error) if design_session_error_is_recoverable(&error) => {
quarantine_corrupted_design_session(root)?;
return Ok(None);
}
Err(error) => return Err(error),
};
let Some(session) = session else {
return Ok(None);
};
if session.project_id != project_id {
@@ -845,20 +853,35 @@ pub(crate) fn hydrate_design_agent_session(
Ok(Some(design_view(&session, active.is_none())))
}
fn design_session_error_is_recoverable(error: &str) -> bool {
error.contains("策划 Agent 会话")
&& (error.contains("解析")
|| error.contains("字段无效")
|| error.contains("超过")
|| error.contains("JSON"))
}
fn quarantine_corrupted_design_session(root: &Path) -> Result<(), String> {
let _lock = acquire_game_creator_agent_runtime_project_write_lock_with_wait(
root,
"design.session-quarantine",
)?;
let path = crate::agent::runtime_protocol::design_session_path(root);
if !path.exists() {
return Ok(());
}
let backup = path.with_file_name(format!("session.corrupted.{}.json", unix_timestamp()));
std::fs::rename(&path, &backup).map_err(|error| format!("隔离损坏的策划会话失败:{error}"))
}
#[tauri::command]
pub(crate) fn reset_design_agent_session(project_path: String) -> Result<(), String> {
let root = Path::new(project_path.trim());
enforce_project_permission_policy(root, "conversation.write")?;
design_project_id(root)?;
let _lock = acquire_game_creator_agent_runtime_project_write_lock_with_wait(
root,
"design.session-reset",
)?;
let path = crate::agent::runtime_protocol::design_session_path(root);
if path.exists() {
let backup = path.with_file_name(format!("session.corrupted.{}.json", unix_timestamp()));
std::fs::rename(&path, &backup)
.map_err(|error| format!("备份损坏的策划会话失败:{error}"))?;
quarantine_corrupted_design_session(root)?;
}
Ok(())
}