From 2a3e64a9997a66ad1fc16f24deccc43606efcbd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Fri, 2 Oct 2026 16:36:44 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96=20AGC=20=E5=A3=B3?= =?UTF-8?q?=20Rust=20=E6=BA=90=E7=A0=81=EF=BC=88rustfmt=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - cargo fmt --all --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml - 覆盖退役与合并期间改动的 27 个文件,恢复 check:rustfmt 门禁 --- .../src-tauri/src/agent.rs | 20 +++++------ .../agent/codex_app_server/process_tree.rs | 14 ++++---- .../src-tauri/src/agent/design_runtime.rs | 35 +++++-------------- .../src-tauri/src/agent/design_tools.rs | 5 +-- .../src-tauri/src/agent/direct_events.rs | 11 +++--- .../src-tauri/src/agent/direct_patch.rs | 3 +- .../src/agent/direct_project_history.rs | 7 ++-- .../src-tauri/src/agent/direct_runtime/mod.rs | 17 +++------ .../src-tauri/src/agent/direct_tool_bridge.rs | 7 ++-- .../src-tauri/src/agent/direct_tools_mcp.rs | 5 +-- .../src/agent/generation/canvas_generation.rs | 11 ++---- .../src/agent/generation/draft_validation.rs | 5 +-- .../generation/external_generation_state.rs | 12 +++---- .../src-tauri/src/agent/task_lock.rs | 2 +- .../src-tauri/src/browser/sweep.rs | 16 +++++---- .../src-tauri/src/builtin_plugins.rs | 1 - .../src-tauri/src/command_exec.rs | 14 ++++---- .../src-tauri/src/command_output.rs | 5 ++- .../src-tauri/src/commands.rs | 10 ++---- .../src-tauri/src/commands/desktop.rs | 5 +-- .../web_creation/ownership.rs | 9 ++--- .../src-tauri/src/main.rs | 2 +- .../src-tauri/src/project/conversation.rs | 3 +- .../src-tauri/src/project/resource_editor.rs | 16 +++------ .../src-tauri/src/project/write_lock.rs | 21 +++++------ .../src/ui_editor/commands/recognition.rs | 23 ++++++------ 26 files changed, 111 insertions(+), 168 deletions(-) diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent.rs b/apps/ai-game-creator-shell/src-tauri/src/agent.rs index 1bf390c97..7a2fd4162 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent.rs @@ -4,8 +4,8 @@ use std::collections::BTreeSet; use std::io::{Seek, SeekFrom}; use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; -mod claude_code_cli; mod art_manifest; +mod claude_code_cli; mod codex_app_server; mod codex_cli; mod codex_provider_proxy; @@ -22,6 +22,7 @@ mod direct_patch; pub(crate) use direct_paid_submission::ensure_direct_paid_submission_dispatch; #[cfg(test)] pub(crate) use direct_paid_submission::with_test_direct_paid_submission_scope; +pub(crate) mod design_session; mod direct_project_context; mod direct_project_history; mod direct_project_turn_history; @@ -31,17 +32,17 @@ mod direct_tools_mcp; mod direct_turn_error; mod direct_turn_failure; mod direct_validation; -mod runtime_error; -mod runtime_models; mod generation; -pub(crate) mod design_session; pub(crate) mod json_sidecar; pub(crate) mod redaction; -mod task_lock; +mod runtime_error; +mod runtime_models; mod skill_pack; +mod task_lock; mod thread_manager; pub mod tool; +pub(crate) use art_manifest::*; use claude_code_cli::*; pub(crate) use claude_code_cli::{ cancel_direct_claude_code_turn_at, direct_game_creator_claude_code_chat_at, @@ -62,6 +63,7 @@ pub(crate) use codex_cli::{ pub(crate) use codex_provider_proxy::*; #[cfg(not(test))] pub(crate) use design_runtime::*; +pub(crate) use design_session::*; pub(crate) use direct_codex_attachments::*; pub(crate) use direct_codex_user_item::*; pub(crate) use direct_events::*; @@ -73,15 +75,13 @@ pub(crate) use direct_tools_mcp::*; pub(crate) use direct_turn_error::*; pub(crate) use direct_turn_failure::*; pub(crate) use direct_validation::DirectValidationConfig; -pub(crate) use art_manifest::*; -pub(crate) use runtime_error::*; -pub(in crate::agent) use runtime_models::*; pub(crate) use generation::*; -pub(crate) use design_session::*; pub(crate) use json_sidecar::*; pub(crate) use redaction::*; -pub(crate) use task_lock::*; +pub(crate) use runtime_error::*; +pub(in crate::agent) use runtime_models::*; pub(crate) use skill_pack::*; +pub(crate) use task_lock::*; pub(crate) use thread_manager::dispatch::*; pub(crate) use thread_manager::queue::*; pub(crate) use thread_manager::wire::*; diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/codex_app_server/process_tree.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/codex_app_server/process_tree.rs index e27c2717c..5a234b37d 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/codex_app_server/process_tree.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/codex_app_server/process_tree.rs @@ -44,10 +44,11 @@ impl OwnedProcessTree { pub(super) fn attach(child: &Child) -> Result { let pid = child.id().ok_or("app-server-process-owner-missing")?; #[cfg(unix)] - let start_identity = crate::process_identity::external_agent_runner_process_start_identity(pid) - .map_err(|_| "app-server-process-identity-unknown")? - .filter(|value| !value.is_empty()) - .ok_or("app-server-process-identity-unknown")?; + let start_identity = + crate::process_identity::external_agent_runner_process_start_identity(pid) + .map_err(|_| "app-server-process-identity-unknown")? + .filter(|value| !value.is_empty()) + .ok_or("app-server-process-identity-unknown")?; #[cfg(windows)] let job = crate::process_session::WindowsProcessJob::assign_tokio_named( child, @@ -162,8 +163,9 @@ impl OwnedProcessTree { return Ok(()); } // leader 已消失或 PID 被复用时不盲杀 PGID;保留不确定状态。 - let current = crate::process_identity::external_agent_runner_process_start_identity(self.pid) - .map_err(|_| "app-server-process-identity-unknown")?; + let current = + crate::process_identity::external_agent_runner_process_start_identity(self.pid) + .map_err(|_| "app-server-process-identity-unknown")?; if current.as_deref() != Some(self.start_identity.as_str()) { return Err("app-server-process-owner-mismatch".into()); } diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/design_runtime.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/design_runtime.rs index 3f450383c..3f8c99995 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/design_runtime.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/design_runtime.rs @@ -17,9 +17,7 @@ const DESIGN_ACTIVE_LOCK: &str = ".agent/design-agent/active.lock"; const DESIGN_PROVIDER_TRANSIENT_BACKOFF_MAX_MS: u64 = 30_000; /// 判定一个 Provider 错误是否属于可重试的瞬时故障;预算/余额类错误不算。 -fn design_provider_error_transient_kind( - error: &platform_llm::LlmError, -) -> Option<&'static str> { +fn design_provider_error_transient_kind(error: &platform_llm::LlmError) -> Option<&'static str> { if game_creator_agent_llm_error_is_mud_points_insufficient(error) { return None; } @@ -526,8 +524,7 @@ fn resolve_design_turn_llm_config( } fn checkpoint_design(root: &Path, session: &DesignSession) -> Result<(), String> { - let _write = - acquire_project_write_lock_with_wait(root, "design.session")?; + let _write = acquire_project_write_lock_with_wait(root, "design.session")?; write_design_session(root, session) } @@ -952,9 +949,7 @@ async fn request_design_provider( "error", json!({"turnId":turn_id,"attempt":attempt,"error":detail}), ); - if attempt == max_retries - || design_provider_error_transient_kind(&error) - .is_none() + if attempt == max_retries || design_provider_error_transient_kind(&error).is_none() { emit(design_reasoning_event( root, @@ -965,10 +960,7 @@ async fn request_design_provider( return Err(design_provider_failure(&error, detail)); } tokio::time::sleep(Duration::from_millis( - design_provider_transient_retry_backoff_ms( - llm.retry_backoff_ms, - attempt + 1, - ), + design_provider_transient_retry_backoff_ms(llm.retry_backoff_ms, attempt + 1), )) .await; } @@ -1034,9 +1026,7 @@ async fn request_scripted_design_provider( &game_creator_agent_llm_error_public_summary(&error), 1800, ); - if attempt == max_retries - || design_provider_error_transient_kind(&error) - .is_none() + if attempt == max_retries || design_provider_error_transient_kind(&error).is_none() { emit(design_reasoning_event( root, @@ -1514,10 +1504,7 @@ fn design_session_error_is_recoverable(error: &str) -> bool { } fn quarantine_corrupted_design_session(root: &Path) -> Result<(), String> { - let _lock = acquire_project_write_lock_with_wait( - root, - "design.session-quarantine", - )?; + let _lock = acquire_project_write_lock_with_wait(root, "design.session-quarantine")?; let path = crate::agent::design_session::design_session_path(root); if !path.exists() { return Ok(()); @@ -1589,10 +1576,7 @@ pub(crate) fn set_design_agent_runtime_mode( let root = Path::new(project_path.trim()); enforce_project_permission_policy(root, "conversation.write")?; design_project_id(root)?; - let _lock = acquire_project_write_lock_with_wait( - root, - "design.runtime-mode", - )?; + let _lock = acquire_project_write_lock_with_wait(root, "design.runtime-mode")?; if active_runtime.trim() == "game" { if crate::assets::register_design_artifacts_at(root)? { advance_agent_runtime_project_revision_locked(root)?; @@ -1624,10 +1608,7 @@ fn debug_fast_forward_design_session_at( } let project_id = design_project_id(root)?; let target_index = design_phase_index(target_phase.trim())?; - let _lock = acquire_project_write_lock_with_wait( - root, - "design.debug-fast-forward", - )?; + let _lock = acquire_project_write_lock_with_wait(root, "design.debug-fast-forward")?; let artifact_paths = [ "project/00_concept/design.md", "project/速览卡.md", diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/design_tools.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/design_tools.rs index b8f737507..5dc6c824c 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/design_tools.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/design_tools.rs @@ -572,10 +572,7 @@ fn import_design_workspace_file_at( ) -> Result { enforce_project_permission_policy(root, "conversation.write")?; read_existing_manifest_for_project(root)?; - let _lock = acquire_project_write_lock_with_wait( - root, - "conversation.write", - )?; + let _lock = acquire_project_write_lock_with_wait(root, "conversation.write")?; if file_name.contains(['/', '\\']) { return Err("附件文件名必须是单个文件名,不能包含目录".to_string()); diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_events.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_events.rs index 1efa5ba54..bafdb8b7f 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_events.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_events.rs @@ -2,9 +2,10 @@ //! 从已退役的 runtime_driver 中抽出,仅保留直连路径与外部编辑器桥仍在使用的事件接线。 use crate::agent::thread_manager::update_active_turn; -use crate::{GameCreatorAgentProgressEvent, GameCreatorManifestInvalidatedEvent, - GameCreatorManifestInvalidationEventSink, GameCreatorManifestInvalidationRelayEnvelope}; -use tauri::Emitter; +use crate::{ + GameCreatorAgentProgressEvent, GameCreatorManifestInvalidatedEvent, + GameCreatorManifestInvalidationEventSink, GameCreatorManifestInvalidationRelayEnvelope, +}; use std::io::{Read, Write}; use std::net::{TcpListener, TcpStream}; use std::path::Path; @@ -12,9 +13,9 @@ use std::sync::atomic::{AtomicU64, Ordering}; use std::sync::{Arc, Mutex, OnceLock}; use std::thread; use std::time::{Duration, SystemTime, UNIX_EPOCH}; +use tauri::Emitter; -static GAME_CREATOR_AGENT_RUNTIME_UPDATE_APP_HANDLE: OnceLock = - OnceLock::new(); +static GAME_CREATOR_AGENT_RUNTIME_UPDATE_APP_HANDLE: OnceLock = OnceLock::new(); /// 同一 AppData 允许多个界面窗口同时挂载事件接收端,因此这里是按 token 去重的注册表。 static GAME_CREATOR_MANIFEST_INVALIDATION_EVENT_SINKS: OnceLock< std::sync::Mutex>, diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_patch.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_patch.rs index bb42fb421..ad4026ad4 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_patch.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_patch.rs @@ -274,8 +274,7 @@ fn run_transaction( return Err("direct-execution-closed: 本轮执行许可已关闭,未派发补丁".into()); } enforce_project_permission_policy(root, "file.write")?; - let _lock = - acquire_project_write_lock_with_wait(root, "direct.patch")?; + let _lock = acquire_project_write_lock_with_wait(root, "direct.patch")?; let targets = collect_targets(root, &parsed.hunks)?; let executable = session.codex_executor()?; validate_argv(&executable, &parsed.patch)?; diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_project_history.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_project_history.rs index 9ff124fd1..d3c021dec 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_project_history.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_project_history.rs @@ -1,5 +1,5 @@ -use crate::acquire_project_write_lock_with_wait; use super::thread_item_identity; +use crate::acquire_project_write_lock_with_wait; use crate::config::prepare_game_creator_private_path_for_read; use crate::project::{ append_jsonl_line_unlocked, enforce_project_permission_policy, project_append_lock_for, @@ -465,10 +465,7 @@ fn append_direct_project_history_item_once(root: &Path, item: &Value) -> Result< // 流式历史落盘在写文件期间直接失败,并把整轮判成“项目正在被其他写操作占用” // (持锁方 commandId=direct-codex.file.write、ownerIsSelf=true)。这里与其它写入口 // 保持同一档有界等待;主路径已在阻塞线程池中执行。 - let _project_lock = acquire_project_write_lock_with_wait( - root, - "conversation.write", - )?; + let _project_lock = acquire_project_write_lock_with_wait(root, "conversation.write")?; let lock = project_append_lock_for(&path)?; let _append_guard = lock.lock("DirectProject 历史追加写")?; // 回扫到取锁之间可能有别的进程(或本项目另一条链)追加过:只有文件状态仍与回扫时一致 diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_runtime/mod.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_runtime/mod.rs index 0652f703d..b9f351829 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_runtime/mod.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_runtime/mod.rs @@ -987,10 +987,8 @@ fn finish_direct_taonier_regeneration_reset_at( root: &Path, expected: &DirectTaonierRegenerationWorkflow, ) -> Result { - let _lock = acquire_project_write_lock_with_wait( - root, - "direct-codex.taonier-package-reset-finish", - )?; + let _lock = + acquire_project_write_lock_with_wait(root, "direct-codex.taonier-package-reset-finish")?; let current = read_direct_taonier_regeneration_workflow_at(root)?; if current.as_ref() != Some(expected) || expected.state != DirectTaonierRegenerationWorkflowState::Resetting @@ -2863,10 +2861,8 @@ async fn recover_direct_taonier_spritesheet_read_only_at( if !validated.has_visible_pixels { return Err("恢复的陶泥儿 art-spritesheet 没有可见像素".to_string()); } - let _lock = acquire_project_write_lock_with_wait( - root, - "direct-codex.art-spritesheet-recovery", - )?; + let _lock = + acquire_project_write_lock_with_wait(root, "direct-codex.art-spritesheet-recovery")?; let _platform_session_lease = access .frozen_platform_session() .map(|session| acquire_platform_session_identity_lease(&session.identity())) @@ -4100,10 +4096,7 @@ fn sync_direct_codex_project_file_projection_at( } update_manifest_task_status_at(root, "code-prototype", GameCreationAppTaskStatus::Completed)?; if outputs_changed || manifest_requires_sync { - let _lock = acquire_project_write_lock_with_wait( - root, - "direct-codex.version", - )?; + let _lock = acquire_project_write_lock_with_wait(root, "direct-codex.version")?; let version_revision = advance_agent_runtime_project_revision_locked(root)?; append_agent_game_iteration_version_at(root, version_revision)?; } diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tool_bridge.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tool_bridge.rs index 1bb294d60..2e2d583e9 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tool_bridge.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tool_bridge.rs @@ -1829,11 +1829,8 @@ fn bridge_write_file_with_permit( // 这是用户直接触发、失败即整轮无法落盘的项目写入通道: // 短暂重叠排队等成功,只有预算耗尽才报出带持锁方身份的错误。 let acquire_started = std::time::Instant::now(); - let _lock = acquire_project_write_lock_with_wait( - root, - "direct-codex.file.write", - ) - .map_err(|cause| WriteFileError::WriteLockUnavailable { cause })?; + let _lock = acquire_project_write_lock_with_wait(root, "direct-codex.file.write") + .map_err(|cause| WriteFileError::WriteLockUnavailable { cause })?; let lock_wait_ms = acquire_started.elapsed().as_millis(); let analytics_change_kind = write_permit.and_then(|_| { let kind = crate::analytics::project::file_change_kind(&path)?; diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tools_mcp.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tools_mcp.rs index 59a1365e6..6e2d51cb4 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tools_mcp.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/direct_tools_mcp.rs @@ -1282,10 +1282,7 @@ fn external_mcp_record_response(root: &Path, arguments: &Value) -> Value { } // 与 DirectProject 历史落盘同一档有界等待:`agc_write_file` 持锁期间可能持续数秒, // 零等待取锁会让 Codex 返回记录直接丢失。调用方已把本函数放进阻塞线程池。 - let _project_lock = match acquire_project_write_lock_with_wait( - root, - "conversation.write", - ) { + let _project_lock = match acquire_project_write_lock_with_wait(root, "conversation.write") { Ok(lock) => lock, Err(error) => { return mcp_tool_result(format!("项目对话锁不可用:{error}"), Vec::new(), true) diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/generation/canvas_generation.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/generation/canvas_generation.rs index d92c35c08..661ae2ad2 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/generation/canvas_generation.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/generation/canvas_generation.rs @@ -3026,10 +3026,8 @@ async fn generate_platform_art_asset_with_runtime_options_and_retention_at( // platform-art request. Both operations are short-lived project writes; // wait for the active writer instead of failing the whole generation on // the expected startup race. - let recovery_lock = acquire_project_write_lock_with_wait( - root, - "canvas.asset_generate.runtime.recover", - )?; + let recovery_lock = + acquire_project_write_lock_with_wait(root, "canvas.asset_generate.runtime.recover")?; recover_interrupted_strict_platform_art_transaction_locked_at(root, &recovery_lock)?; } let mut prepared = request_platform_art_asset_with_runtime_options_at( @@ -3056,10 +3054,7 @@ async fn generate_platform_art_asset_with_runtime_options_and_retention_at( } } prepared.validate_frozen_session()?; - let lock = acquire_project_write_lock_with_wait( - root, - "canvas.asset_generate.runtime", - )?; + let lock = acquire_project_write_lock_with_wait(root, "canvas.asset_generate.runtime")?; recover_interrupted_strict_platform_art_transaction_locked_at(root, &lock)?; advance_agent_runtime_project_revision_locked(root)?; let generated = if require_slices { diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/generation/draft_validation.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/generation/draft_validation.rs index 1bb34be45..4c2549ce1 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/generation/draft_validation.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/generation/draft_validation.rs @@ -9,7 +9,6 @@ use oxc_parser::Parser as JavascriptParser; use oxc_semantic::SemanticBuilder as JavascriptSemanticBuilder; use oxc_span::{GetSpan as JavascriptGetSpan, SourceType as JavascriptSourceType}; - pub(crate) fn evaluate_game_draft(prompt: &str, draft: &LlmGameDraft) -> Vec { let mut issues = Vec::new(); if let Err(error) = validate_llm_game_draft(prompt, draft) { @@ -497,9 +496,7 @@ fn javascript_is_syntactically_valid(content: &str, is_module: bool) -> bool { semantic.diagnostics.is_empty() } -fn validate_executable_inline_javascript_syntax( - html: &str, -) -> Result<(), String> { +fn validate_executable_inline_javascript_syntax(html: &str) -> Result<(), String> { let lower = html.to_ascii_lowercase(); let mut cursor = 0usize; let mut executable_index = 0usize; diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/generation/external_generation_state.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/generation/external_generation_state.rs index fd9efc84c..6a0c211ec 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/generation/external_generation_state.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/generation/external_generation_state.rs @@ -641,10 +641,8 @@ pub(super) fn prepare_platform_art_generation_runtime_state( // Idempotency-Key. Hold the cross-process project lock across the complete // read/create/readback claim so two callers can never both observe Missing // and publish different keys for the same fixed stage identity. - let _claim_lock = acquire_project_write_lock_with_wait( - root, - "canvas.asset_generate.runtime.claim", - )?; + let _claim_lock = + acquire_project_write_lock_with_wait(root, "canvas.asset_generate.runtime.claim")?; if let Some(existing) = read_platform_art_generation_runtime_state(root, context)? { let existing = migrate_platform_art_generation_external_configuration(root, existing, access)?; @@ -1130,10 +1128,8 @@ pub(super) fn adopt_legacy_standalone_platform_art_generation_runtime_state_at( } // 与账本创建互斥:迁移必须在同一把项目写锁内完成,否则两个调用可能同时把同一份 // 旧账本迁移到新路径,或与新建账本互相覆盖。 - let _claim_lock = acquire_project_write_lock_with_wait( - root, - "canvas.asset_generate.runtime.claim", - )?; + let _claim_lock = + acquire_project_write_lock_with_wait(root, "canvas.asset_generate.runtime.claim")?; if game_creator_agent_runtime_external_generation_exists( root, &context.agent_id, diff --git a/apps/ai-game-creator-shell/src-tauri/src/agent/task_lock.rs b/apps/ai-game-creator-shell/src-tauri/src/agent/task_lock.rs index aa699651a..950cc6491 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent/task_lock.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent/task_lock.rs @@ -3,10 +3,10 @@ //! 这套锁只服务外部编辑器绑定、设计会话和埋点侧车这些仍在服役的写路径, //! 与已退役的 Agent Runtime 状态机解耦;自锁方式是在 `.agent/runtime/locks/` //! 下打开一个普通文件并对它加系统文件锁(unix flock / windows share-deny)。 -use crate::project::{normalize_relative_path, unix_timestamp, validate_project_root}; use super::redaction::unix_timestamp_nanos; #[cfg(windows)] use crate::process_identity::validate_windows_regular_file_handle; +use crate::project::{normalize_relative_path, unix_timestamp, validate_project_root}; use std::fs::{self, File}; use std::io::{Seek, SeekFrom, Write}; use std::path::Path; diff --git a/apps/ai-game-creator-shell/src-tauri/src/browser/sweep.rs b/apps/ai-game-creator-shell/src-tauri/src/browser/sweep.rs index 74cf2df02..d33a4a2ef 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/browser/sweep.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/browser/sweep.rs @@ -35,7 +35,8 @@ pub(super) struct BrowserProcessOwner { /// 运行期 launch 的身份锚点;任何一步拿不到身份证明都不写, /// 该目录之后按旧残留只删不杀。 pub(super) fn write_browser_process_owner(temp_root: &Path, browser_pid: u32, executable: &Path) { - let identity = crate::process_identity::external_agent_runner_process_start_identity(browser_pid); + let identity = + crate::process_identity::external_agent_runner_process_start_identity(browser_pid); let owner_identity = crate::process_identity::external_agent_runner_process_start_identity(std::process::id()); let (Ok(Some(identity)), Ok(Some(owner_identity))) = (identity, owner_identity) else { @@ -252,7 +253,9 @@ fn track_process(tracked: &mut Vec<(u32, String)>, pid: u32) { if tracked.iter().any(|(known, _)| *known == pid) { return; } - if let Ok(Some(identity)) = crate::process_identity::external_agent_runner_process_start_identity(pid) { + if let Ok(Some(identity)) = + crate::process_identity::external_agent_runner_process_start_identity(pid) + { tracked.push((pid, identity)); } } @@ -486,10 +489,11 @@ mod tests { let root = tempfile::tempdir().unwrap(); let dir = root.path().join(format!("{BROWSER_TEMP_PREFIX}owned")); fs::create_dir(&dir).unwrap(); - let owner_identity = - crate::process_identity::external_agent_runner_process_start_identity(std::process::id()) - .expect("self identity") - .expect("self identity present"); + let owner_identity = crate::process_identity::external_agent_runner_process_start_identity( + std::process::id(), + ) + .expect("self identity") + .expect("self identity present"); let mut owner = owner_fixture(exited_child_pid(), std::process::id()); owner.owner_start_identity = owner_identity; write_owner(&dir, &owner); diff --git a/apps/ai-game-creator-shell/src-tauri/src/builtin_plugins.rs b/apps/ai-game-creator-shell/src-tauri/src/builtin_plugins.rs index ade0b2636..71b235ba8 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/builtin_plugins.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/builtin_plugins.rs @@ -525,5 +525,4 @@ mod tests { assert!(initialize(directory.path()).is_err()); assert!(!is_enabled(AGC_COCOS_EDITOR_PLUGIN_ID)); } - } diff --git a/apps/ai-game-creator-shell/src-tauri/src/command_exec.rs b/apps/ai-game-creator-shell/src-tauri/src/command_exec.rs index bb7b7972f..14a4e6096 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/command_exec.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/command_exec.rs @@ -153,10 +153,11 @@ impl ProjectCommandTree { #[cfg(not(windows))] { let pid = child.id().ok_or("受控命令缺少进程身份")?; - let start_identity = crate::process_identity::external_agent_runner_process_start_identity(pid) - .ok() - .flatten() - .filter(|identity| !identity.is_empty()); + let start_identity = + crate::process_identity::external_agent_runner_process_start_identity(pid) + .ok() + .flatten() + .filter(|identity| !identity.is_empty()); Ok(Self::Group { pid, start_identity, @@ -183,8 +184,9 @@ impl ProjectCommandTree { Err("受控进程组状态未确认,拒绝发送终止信号".into()) }; } - let observed = crate::process_identity::external_agent_runner_process_start_identity(*pid) - .map_err(|_| "受控进程组 leader 身份未确认,拒绝发送终止信号")?; + let observed = + crate::process_identity::external_agent_runner_process_start_identity(*pid) + .map_err(|_| "受控进程组 leader 身份未确认,拒绝发送终止信号")?; if !owned_project_command_group_identity_matches( start_identity.as_deref(), observed.as_deref(), diff --git a/apps/ai-game-creator-shell/src-tauri/src/command_output.rs b/apps/ai-game-creator-shell/src-tauri/src/command_output.rs index 7eb40b38e..b87c60013 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/command_output.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/command_output.rs @@ -457,7 +457,10 @@ fn validate_command_output_file_handle(file: &File, path: &Path) -> Result<(), S } } #[cfg(windows)] - crate::process_identity::validate_windows_regular_file_handle(file, "command.exec 输出 sidecar")?; + crate::process_identity::validate_windows_regular_file_handle( + file, + "command.exec 输出 sidecar", + )?; Ok(()) } diff --git a/apps/ai-game-creator-shell/src-tauri/src/commands.rs b/apps/ai-game-creator-shell/src-tauri/src/commands.rs index 4f5f81253..9bcdfd7ee 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/commands.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/commands.rs @@ -3178,10 +3178,7 @@ pub(crate) fn import_local_project_assets_for_agent_with_write_permit( )); } - let _lock = acquire_project_write_lock_with_wait( - root, - "canvas.asset_import", - )?; + let _lock = acquire_project_write_lock_with_wait(root, "canvas.asset_import")?; enforce_project_permission_policy(root, "canvas.asset_import")?; let commit = || { let manifest = read_existing_manifest_for_project(root)?; @@ -3413,10 +3410,7 @@ fn commit_account_editor_asset_downloads( write_permit: Option<&crate::agent::WritePermit>, frozen_session: Option<&PlatformSessionSnapshot>, ) -> Result { - let _lock = acquire_project_write_lock_with_wait( - root, - "canvas.asset_import", - )?; + let _lock = acquire_project_write_lock_with_wait(root, "canvas.asset_import")?; enforce_project_permission_policy(root, "canvas.asset_import")?; // 等待后才取得身份租约;等待期间允许换号,提交时拒绝旧账号结果。 let _platform_session_lease = frozen_session diff --git a/apps/ai-game-creator-shell/src-tauri/src/commands/desktop.rs b/apps/ai-game-creator-shell/src-tauri/src/commands/desktop.rs index b7d8b4798..22f2a3a5d 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/commands/desktop.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/commands/desktop.rs @@ -944,10 +944,7 @@ pub(crate) fn create_game_creator_agent_session( enforce_project_permission_policy(root, "conversation.write")?; // 首轮策划消息可能紧跟项目初始化写入到达;对话保存应等待这段短暂的 // 项目锁竞争,避免把可恢复的初始化竞态直接显示成保存失败。 - let _lock = acquire_project_write_lock_with_wait( - root, - "conversation.write", - )?; + let _lock = acquire_project_write_lock_with_wait(root, "conversation.write")?; create_game_creator_agent_session_at(root, agent_id.trim(), title.trim()) } diff --git a/apps/ai-game-creator-shell/src-tauri/src/environment_check/web_creation/ownership.rs b/apps/ai-game-creator-shell/src-tauri/src/environment_check/web_creation/ownership.rs index 7fb888d63..db5d6df15 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/environment_check/web_creation/ownership.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/environment_check/web_creation/ownership.rs @@ -15,10 +15,11 @@ impl ProcessIdentity { if pid == 0 { return Err("web-scaffold-process-identity-unknown".into()); } - let start_identity = crate::process_identity::external_agent_runner_process_start_identity(pid) - .map_err(|_| "web-scaffold-process-identity-unknown")? - .filter(|value| !value.is_empty()) - .ok_or("web-scaffold-process-identity-unknown")?; + let start_identity = + crate::process_identity::external_agent_runner_process_start_identity(pid) + .map_err(|_| "web-scaffold-process-identity-unknown")? + .filter(|value| !value.is_empty()) + .ok_or("web-scaffold-process-identity-unknown")?; Ok(Self { pid, start_identity, diff --git a/apps/ai-game-creator-shell/src-tauri/src/main.rs b/apps/ai-game-creator-shell/src-tauri/src/main.rs index 5c4f63d53..8db190f8d 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/main.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/main.rs @@ -114,11 +114,11 @@ mod platform_maintenance; mod platform_session; mod plugin_host; mod preview; +mod process_identity; mod process_session; mod process_session_bridge; mod project; mod project_snapshot; -mod process_identity; mod repository_context; mod resource_inspect; mod resource_preview_scheduler; diff --git a/apps/ai-game-creator-shell/src-tauri/src/project/conversation.rs b/apps/ai-game-creator-shell/src-tauri/src/project/conversation.rs index 82c9a5502..c0c58ee12 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/project/conversation.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/project/conversation.rs @@ -519,8 +519,7 @@ where .find(|session| session.session_id == source_session_id) .cloned() .ok_or_else(|| format!("Agent Session 不存在:{source_session_id}"))?; - if source.session_id != catalog.active_session_id { - } + if source.session_id != catalog.active_session_id {} let records = read_persisted_local_conversation_records_unlocked(&source_path)?; let session_id = new_agent_conversation_session_id(&catalog, &agent_id)?; diff --git a/apps/ai-game-creator-shell/src-tauri/src/project/resource_editor.rs b/apps/ai-game-creator-shell/src-tauri/src/project/resource_editor.rs index 8be8e0c89..a3195c7fa 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/project/resource_editor.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/project/resource_editor.rs @@ -4302,8 +4302,7 @@ fn commit_resource_edit_asset_internal( reference_resource_ids: vec![source.canonical_resource_id.clone()], }, }; - let _project_lock = - acquire_project_write_lock_with_wait(root, "resource.edit")?; + let _project_lock = acquire_project_write_lock_with_wait(root, "resource.edit")?; let mut manifest = read_existing_manifest_for_project(root)?; if manifest.project_id != input.expected_project_id { return Err("project-identity-conflict".to_string()); @@ -4618,8 +4617,7 @@ fn commit_resource_edit_asset_with_frozen_platform_session( ) -> Result { // 项目锁先于平台身份租约,避免等待时挡住换号或与其它提交形成锁顺序反转。 // 内层提交在同一线程复用项目锁,整个事务不能跨 await 或线程迁移。 - let _project_lock = - acquire_project_write_lock_with_wait(root, "resource.edit")?; + let _project_lock = acquire_project_write_lock_with_wait(root, "resource.edit")?; with_frozen_resource_edit_platform_session(platform_session, || { commit_resource_edit_asset(root, input, source, prompt, asset_name, ledger) }) @@ -4701,10 +4699,7 @@ fn commit_resource_edit_version( ledger: &mut ResourceEditLedger, ) -> Result { let version_id = format!("edit-{}", input.operation_id); - let _project_lock = acquire_project_write_lock_with_wait( - root, - "resource.edit.version", - )?; + let _project_lock = acquire_project_write_lock_with_wait(root, "resource.edit.version")?; let mut manifest = read_existing_manifest_for_project(root)?; if manifest.project_id != input.expected_project_id { return Err("project-identity-conflict".to_string()); @@ -5672,10 +5667,7 @@ pub(crate) async fn derive_local_project_resource_at( let _project_guard = project_guard; if ledger.phase == ResourceEditLedgerPhase::Committed { let _project_write_lock = - acquire_project_write_lock_with_wait( - &root, - "resource.edit.cleanup", - )?; + acquire_project_write_lock_with_wait(&root, "resource.edit.cleanup")?; cleanup_committed_resource_edit_staging(&root, &mut ledger)?; committed_resource_edit_result( &root, diff --git a/apps/ai-game-creator-shell/src-tauri/src/project/write_lock.rs b/apps/ai-game-creator-shell/src-tauri/src/project/write_lock.rs index a1cb95371..2ff6097a6 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/project/write_lock.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/project/write_lock.rs @@ -991,7 +991,9 @@ fn project_revision_project_id(root: &Path) -> Result { return Err("项目 revision 缺少项目 ID".to_string()); } Ok(crate::agent::redaction::redact_agent_runtime_project_paths( - root, &project_id, 240, + root, + &project_id, + 240, )) } @@ -1023,15 +1025,14 @@ fn validate_project_revision( pub(crate) fn read_game_creator_agent_runtime_project_revision( root: &Path, ) -> Result { - let revision = crate::agent::json_sidecar::read_agent_runtime_json_sidecar::< - AgentRuntimeProjectRevision, - >( - root, - AGENT_RUNTIME_PROJECT_REVISION_RELATIVE_PATH, - "项目 revision", - )? - .map(Ok) - .unwrap_or_else(|| default_project_revision(root))?; + let revision = + crate::agent::json_sidecar::read_agent_runtime_json_sidecar::( + root, + AGENT_RUNTIME_PROJECT_REVISION_RELATIVE_PATH, + "项目 revision", + )? + .map(Ok) + .unwrap_or_else(|| default_project_revision(root))?; validate_project_revision(root, &revision)?; Ok(revision) } diff --git a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/recognition.rs b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/recognition.rs index ebae3d1c2..0850366ca 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/recognition.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/ui_editor/commands/recognition.rs @@ -630,11 +630,10 @@ pub(crate) async fn recognize_ui_impl( error })? .llm; - let client = - build_game_creator_llm_client_from_llm_config(&llm, "llm").map_err(|error| { - eprintln!("ui_recognition.error stage=build_client error={error}"); - error - })?; + let client = build_game_creator_llm_client_from_llm_config(&llm, "llm").map_err(|error| { + eprintln!("ui_recognition.error stage=build_client error={error}"); + error + })?; let schema = recognition_json_schema().map_err(|error| { app_log!("ui_recognition.error stage=build_schema error={error}"); error @@ -691,13 +690,13 @@ pub(crate) async fn recognize_ui_impl( .with_tool_choice(LlmToolChoice::Required); let response = request_ui_editor_llm(&client, &llm, request) .await - .map_err(|error| { - app_log!( - "ui_recognition.error stage=llm_request root={} error={error}", - root_id.as_str() - ); - format!("UI 结构识别失败(根界面图 {}):{error}", root_id.as_str()) - })?; + .map_err(|error| { + app_log!( + "ui_recognition.error stage=llm_request root={} error={error}", + root_id.as_str() + ); + format!("UI 结构识别失败(根界面图 {}):{error}", root_id.as_str()) + })?; app_log!( "ui_recognition.llm_output root={} text_present={} tool_call_count={}", root_id.as_str(),