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 aeab6c9ab..27399f568 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/agent.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/agent.rs @@ -14,9 +14,9 @@ mod codex_cli; mod codex_provider_proxy; mod direct_codex_attachments; mod direct_codex_audit; +mod direct_codex_references; mod direct_project_history; mod direct_project_turn_history; -mod direct_codex_references; mod direct_runtime; mod direct_tool_bridge; mod direct_tools_mcp; @@ -41,9 +41,9 @@ pub(crate) use codex_cli::{ pub(crate) use codex_provider_proxy::*; pub(crate) use direct_codex_attachments::*; pub(crate) use direct_codex_audit::*; +pub(crate) use direct_codex_references::*; pub(crate) use direct_project_history::*; pub(crate) use direct_project_turn_history::*; -pub(crate) use direct_codex_references::*; pub(crate) use direct_runtime::*; pub(crate) use direct_tool_bridge::*; pub(crate) use direct_tools_mcp::*; diff --git a/apps/ai-game-creator-shell/src-tauri/src/assets.rs b/apps/ai-game-creator-shell/src-tauri/src/assets.rs index 985b536ac..b4f225918 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/assets.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/assets.rs @@ -1650,7 +1650,8 @@ pub(crate) fn infer_canvas_export_asset_kind( || contains_any(layer_type, &["序列", "动画", "动作"]) { "character-animation" - } else if file.starts_with("media/") || contains_any(layer_type, &["音频", "音乐", "音效"]) { + } else if file.starts_with("media/") || contains_any(layer_type, &["音频", "音乐", "音效"]) + { "audio" } else if contains_any(layer_type, &["角色"]) { "character" diff --git a/apps/ai-game-creator-shell/src-tauri/src/project/asset_export.rs b/apps/ai-game-creator-shell/src-tauri/src/project/asset_export.rs index 7adaa60bb..dc0a19150 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/project/asset_export.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/project/asset_export.rs @@ -23,10 +23,7 @@ pub(crate) struct SaveLocalProjectAssetFileResult { pub(crate) byte_len: u64, } -fn resolve_export_source_file( - root: &Path, - relative_path: &str, -) -> Result { +fn resolve_export_source_file(root: &Path, relative_path: &str) -> Result { let normalized = normalize_relative_path(relative_path.trim())?; if normalized.is_empty() { return Err("待保存的素材路径不能为空".to_string()); @@ -76,10 +73,9 @@ pub(crate) fn save_local_project_asset_file_at( let source = resolve_export_source_file(root, &input.relative_path)?; let destination = resolve_export_destination_file(&input.destination_path)?; - let mut reader = - File::open(&source).map_err(|error| format!("打开素材文件失败:{error}"))?; - let mut writer = File::create(&destination) - .map_err(|error| format!("创建保存目标失败:{error}"))?; + let mut reader = File::open(&source).map_err(|error| format!("打开素材文件失败:{error}"))?; + let mut writer = + File::create(&destination).map_err(|error| format!("创建保存目标失败:{error}"))?; let mut buffer = vec![0_u8; ASSET_EXPORT_COPY_CHUNK_BYTES]; let mut byte_len = 0_u64; loop { @@ -215,16 +211,14 @@ mod tests { assert!(blank.contains("保存目标路径不能为空"), "{blank}"); let missing_parent_directory = unique_asset_export_directory("absent"); - let missing_parent = save_local_project_asset_file_at( - SaveLocalProjectAssetFileInput { - project_path: root.to_string_lossy().into_owned(), - relative_path: "assets/hero.png".to_string(), - destination_path: missing_parent_directory - .join("hero-copy.png") - .to_string_lossy() - .into_owned(), - }, - ) + let missing_parent = save_local_project_asset_file_at(SaveLocalProjectAssetFileInput { + project_path: root.to_string_lossy().into_owned(), + relative_path: "assets/hero.png".to_string(), + destination_path: missing_parent_directory + .join("hero-copy.png") + .to_string_lossy() + .into_owned(), + }) .expect_err("missing parent directory must fail"); assert!( missing_parent.contains("保存目标的父目录不存在"), diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/asset_delete.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/asset_delete.rs index c43a0f8d1..b5e4d3c06 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/asset_delete.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/asset_delete.rs @@ -230,9 +230,15 @@ fn asset_delete_removes_referencing_versions_when_confirmed() { assert!(root.join(&result.local_path).is_file()); let manifest = read_manifest_for_project(&root).expect("read manifest after delete"); - assert!(manifest.assets.iter().all(|asset| asset.id != removed_asset_id)); + assert!(manifest + .assets + .iter() + .all(|asset| asset.id != removed_asset_id)); assert!( - manifest.assets.iter().any(|asset| asset.id == kept_asset_id), + manifest + .assets + .iter() + .any(|asset| asset.id == kept_asset_id), "未被删除的素材登记必须保留" ); assert_eq!( @@ -252,7 +258,10 @@ fn asset_delete_removes_referencing_versions_when_confirmed() { .all(|version| !version_references_asset(version, &removed_asset_id)), "剩余版本不得再引用被删素材" ); - assert_eq!(manifest.versions[0].version_id, before.versions[0].version_id); + assert_eq!( + manifest.versions[0].version_id, + before.versions[0].version_id + ); fs::remove_dir_all(root).ok(); } @@ -267,8 +276,8 @@ fn asset_reference_projection_lists_only_versions_using_the_asset() { register_agent_version(&root); let manifest = read_manifest_for_project(&root).expect("read manifest"); - let late_references = - read_manifest_asset_references_at(&root, &late_asset_id).expect("read late asset references"); + let late_references = read_manifest_asset_references_at(&root, &late_asset_id) + .expect("read late asset references"); assert_eq!(late_references.asset_id, late_asset_id); assert_eq!(late_references.versions.len(), 1); assert_eq!( @@ -324,7 +333,10 @@ fn version_removal_stays_rejected_outside_the_confirmed_asset_delete() { Ok(()) }) .expect_err("a plain manifest mutation must not delete versions"); - assert!(error.contains("不可修改、删除或重排"), "unexpected error: {error}"); + assert!( + error.contains("不可修改、删除或重排"), + "unexpected error: {error}" + ); let reordered = mutate_manifest_at(&root, |manifest| { manifest.versions.swap(0, 1); @@ -349,14 +361,9 @@ fn asset_delete_enforces_revision_and_identity_cas() { let asset_id = register_asset_delete_fixture_asset(&root, "assets/hero.png", "art-asset-plan"); let revision_before = project_revision(&root); - let revision_error = delete_manifest_asset_at( - &root, - "project-1", - revision_before + 1, - &asset_id, - true, - ) - .expect_err("stale revision must be rejected"); + let revision_error = + delete_manifest_asset_at(&root, "project-1", revision_before + 1, &asset_id, true) + .expect_err("stale revision must be rejected"); assert_eq!(revision_error, "project-revision-conflict"); let identity_error = @@ -364,8 +371,9 @@ fn asset_delete_enforces_revision_and_identity_cas() { .expect_err("cross-project identity must be rejected"); assert_eq!(identity_error, "project-identity-conflict"); - let missing_error = delete_manifest_asset_at(&root, "project-1", revision_before, "absent", true) - .expect_err("missing asset must be rejected"); + let missing_error = + delete_manifest_asset_at(&root, "project-1", revision_before, "absent", true) + .expect_err("missing asset must be rejected"); assert!( missing_error.contains("项目资源不存在"), "unexpected error: {missing_error}" diff --git a/apps/ai-game-creator-shell/src-tauri/src/tests/asset_rename.rs b/apps/ai-game-creator-shell/src-tauri/src/tests/asset_rename.rs index 4709cc90c..9242c4559 100644 --- a/apps/ai-game-creator-shell/src-tauri/src/tests/asset_rename.rs +++ b/apps/ai-game-creator-shell/src-tauri/src/tests/asset_rename.rs @@ -92,8 +92,8 @@ fn rename_local_project_asset_is_a_noop_for_the_same_file_name() { let manifest_before = fs::read(root.join(".agent/manifest.json")).expect("manifest bytes"); let revision_before = asset_rename_revision(&root); - let result = rename_local_project_asset_at(&root, &asset_id, "hero.png", None) - .expect("no-op rename"); + let result = + rename_local_project_asset_at(&root, &asset_id, "hero.png", None).expect("no-op rename"); assert_eq!(result.previous_local_path, "assets/hero.png"); assert_eq!(result.asset.local_path, "assets/hero.png"); @@ -128,9 +128,7 @@ fn rename_local_project_asset_rejects_unsafe_file_names() { let error = rename_local_project_asset_at(&root, &asset_id, name, None) .expect_err("unsafe file name must be rejected"); assert!( - error.contains("不能为空") - || error.contains("路径分隔符") - || error.contains(".."), + error.contains("不能为空") || error.contains("路径分隔符") || error.contains(".."), "意外错误:{error}" ); } @@ -203,7 +201,8 @@ fn rename_local_project_asset_rejects_extension_changes() { #[test] fn rename_local_project_asset_rejects_existing_target_name() { let (root, asset_id) = asset_rename_project_fixture(); - write_local_project_file_at(&root, "assets/other.png", "other-bytes").expect("other asset file"); + write_local_project_file_at(&root, "assets/other.png", "other-bytes") + .expect("other asset file"); let manifest_before = fs::read(root.join(".agent/manifest.json")).expect("manifest bytes"); let error = rename_local_project_asset_at(&root, &asset_id, "other.png", None)