清理低风险编译警告并修复构建检查脚本

清理冗余导入、可变绑定和赋值,将 AGC 默认编译警告从 231 条降至 195 条
按测试和平台边界限定导入,保留兼容出口与待核查的业务参数
修复预览部署器嵌套 npm 警告和移动端检查脚本的 Windows 启动错误
更新警告清单、开发运维文档与共享开发流程,记录验证结果和剩余项
This commit is contained in:
2026-09-23 10:58:19 +00:00
parent 07feed7511
commit 018697203f
31 changed files with 115 additions and 60 deletions
@@ -8,7 +8,6 @@ use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
use std::sync::{Arc, OnceLock, Weak};
use tokio::io::{AsyncBufRead, AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader};
use tokio::sync::{mpsc, oneshot, Mutex, Notify};
use uuid::Uuid;
mod direct_project_history_wire;
use direct_project_history_wire::build_direct_project_history_injection_params;
@@ -3236,9 +3235,9 @@ impl CodexAppServerConnection {
snapshot: &AgentRuntimeProviderRequestSnapshot,
llm: &GameCreatorLlmConfig,
request: LlmRunRequest,
mut on_agent_message_delta: Option<&mut (dyn FnMut(&platform_llm::LlmStreamDelta) + Send)>,
mut direct_observer: Option<&mut (dyn FnMut(DirectCodexTurnObservation) + Send)>,
mut audit: Option<&mut DirectCodexTurnAudit>,
on_agent_message_delta: Option<&mut (dyn FnMut(&platform_llm::LlmStreamDelta) + Send)>,
direct_observer: Option<&mut (dyn FnMut(DirectCodexTurnObservation) + Send)>,
audit: Option<&mut DirectCodexTurnAudit>,
) -> Result<platform_llm::LlmRunResponse, platform_llm::LlmError> {
self.run_turn_with_direct_observer_and_history(
snapshot,
@@ -3288,7 +3287,6 @@ impl CodexAppServerConnection {
}
}
});
let mut request = request;
let history_root = direct_history_root.unwrap_or(&self.inner.workspace_path);
// 工具调用卡片的 turnId 用 AGC 客户端回合 id(与实时事件、落盘条目同一口径),
// 不用 Codex app-server 自己的 turnId——前端要按它把卡片挂回对应的那一轮。
@@ -4,7 +4,7 @@ use axum::extract::State;
use axum::http::{HeaderMap, HeaderName, Request, Response, StatusCode};
use axum::routing::any;
use axum::Router;
use futures::{Stream, StreamExt};
use futures::Stream;
use std::pin::Pin;
use std::sync::{Arc, Mutex};
use std::task::{Context, Poll};
@@ -6,7 +6,9 @@ use serde_json::{json, Value};
use sha2::{Digest, Sha256};
use std::collections::HashSet;
use std::io::Read;
use std::path::{Path, PathBuf};
use std::path::Path;
#[cfg(test)]
use std::path::PathBuf;
use std::sync::Arc;
const MAX_FILES: usize = 8;
@@ -2,14 +2,15 @@ use super::*;
use base64::Engine as _;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::future::Future;
use std::io::Write;
use std::path::{Path, PathBuf};
use std::sync::{Mutex, OnceLock};
use std::time::{SystemTime, UNIX_EPOCH};
mod user_input;
pub(crate) use user_input::{chat_with_game_creator_direct_codex, normalize_direct_client_turn_id};
pub(crate) use user_input::chat_with_game_creator_direct_codex;
#[cfg(test)]
pub(crate) use user_input::normalize_direct_client_turn_id;
const MAX_DIRECT_SYSTEM_PROMPT_CHARS: usize = 16 * 1024;
const MIN_DIRECT_CLIENT_TURN_ID_CHARS: usize = 6;
@@ -1,6 +1,10 @@
use super::*;
use axum::extract::{DefaultBodyLimit, Query, State};
use axum::routing::{get, post};
#[cfg(test)]
use axum::extract::Query;
use axum::extract::{DefaultBodyLimit, State};
#[cfg(test)]
use axum::routing::get;
use axum::routing::post;
use axum::{Json, Router};
use base64::{engine::general_purpose::STANDARD as BASE64_STANDARD, Engine as _};
use serde::Deserialize;
@@ -777,7 +781,7 @@ pub(crate) fn compact_mcp_image_data(data: &str) -> Option<(String, &'static str
preview = image.thumbnail(dimension, dimension);
}
let mut encoded = Vec::new();
let mut encoder = image::codecs::jpeg::JpegEncoder::new_with_quality(&mut encoded, quality);
let encoder = image::codecs::jpeg::JpegEncoder::new_with_quality(&mut encoded, quality);
preview.write_with_encoder(encoder).ok()?;
if encoded.len() <= DIRECT_TOOL_BRIDGE_IMAGE_PREVIEW_MAX_BYTES {
return Some((BASE64_STANDARD.encode(encoded), "image/jpeg"));
@@ -60,8 +60,7 @@ pub(in crate::agent) async fn compact_game_creator_agent_runtime_context_at(
let app_config = load_game_creator_app_config()?;
let llm = resolve_game_creator_llm_config_for_agent(&app_config, &template_agent_id);
let config_path = format!("agentLlm.{template_agent_id}");
let mut request =
build_game_creator_agent_runtime_context_compaction_request(&source, &llm)?;
let request = build_game_creator_agent_runtime_context_compaction_request(&source, &llm)?;
let estimated_request_tokens = estimate_game_creator_llm_request_tokens(&request)?;
validate_game_creator_llm_request_context_budget(
&llm,
@@ -603,7 +603,7 @@ fn build_game_creator_agent_background_tool_plan_request_at(
.messages
.push(LlmMessage::user(goal_contract_instruction));
}
let mut request = apply_game_creator_llm_reasoning_effort(request, &llm)?;
let request = apply_game_creator_llm_reasoning_effort(request, &llm)?;
let request = apply_game_creator_llm_web_search(request, &llm, true)?;
Ok((
llm,
@@ -6322,7 +6322,7 @@ fn autonomous_manifest_parent_completion_gaps_at(
{
missing_paths.push(gap);
}
let mut owner_artifact_gaps = autonomous_manifest_owner_artifact_gaps_at(
let owner_artifact_gaps = autonomous_manifest_owner_artifact_gaps_at(
root,
&seed_task.id,
contract.baseline_index_sha256.as_deref(),
@@ -31,6 +31,8 @@ pub(in crate::agent) fn sync_agent_runtime_sidecar_parent(
path: &Path,
label: &str,
) -> Result<(), String> {
#[cfg(not(unix))]
let _ = (path, label);
#[cfg(unix)]
{
let parent = path.parent().ok_or_else(|| format!("{label} 缺少父目录"))?;
@@ -1,5 +1,5 @@
use super::*;
use sha2::{Digest as _, Sha256};
use sha2::Sha256;
use shared_contracts::game_creation_app::GameCreationAppAssetCategory;
use std::future::Future;
@@ -2089,7 +2089,7 @@ pub(crate) fn create_ui_design_resource(
use std::os::windows::fs::OpenOptionsExt;
options.custom_flags(crate::PROJECT_FILE_FLAG_OPEN_REPARSE_POINT);
}
let mut file = options
let file = options
.open(&absolute_path)
.map_err(|error| format!("创建 UI 资源失败:{}: {error}", absolute_path.display()))?;
if let Err(error) = harden_new_game_creator_private_path(&absolute_path, false, "UI 资源") {
@@ -4640,13 +4640,13 @@ pub(crate) async fn import_ui_editor_remote_assets(
);
let local_path = remote_asset_local_path(&asset_id, extension);
reserve_remote_asset_destination(&mut destinations, &local_path)?;
downloads.push((asset, asset_id, media_type.to_string(), local_path, bytes));
downloads.push((asset, media_type.to_string(), local_path, bytes));
}
let _lock = acquire_project_write_lock(root, "canvas.asset_import")?;
// 远程素材导入保持与本地图片/字体相同的增量语义,不对已成功项目文件做整批回滚。
let mut imported = Vec::with_capacity(downloads.len());
for (asset, asset_id, media_type, local_path, bytes) in downloads {
for (asset, media_type, local_path, bytes) in downloads {
let target = resolve_local_project_path(root, &local_path)?;
if let Some(parent) = target.parent() {
ensure_game_creator_private_directory_tree(parent, "平台素材导入目录")?;
@@ -3639,7 +3639,6 @@ pub(crate) fn migrate_legacy_game_creator_agent_mode(path: &Path) -> Result<(),
if let Some(llm) = config.llm.as_mut() {
if llm.web_search_enabled.is_none() {
llm.web_search_enabled = Some(true);
changed = true;
}
}
}
@@ -10,7 +10,6 @@ use std::fs::{File, OpenOptions};
use std::io::{BufRead, BufReader, Read, Seek, SeekFrom, Write};
use std::net::{TcpListener, TcpStream};
use std::path::{Path, PathBuf};
use std::process::Command;
use std::sync::atomic::AtomicBool;
use std::sync::{mpsc, Arc, Mutex, OnceLock};
use std::thread;
@@ -2453,7 +2452,7 @@ fn main() {
set_game_creator_runtime_config_dir(config_dir);
}
let mut tauri_context = tauri::generate_context!();
let tauri_context = tauri::generate_context!();
// 配置目录确定之前先推导启动日志路径:优先用已经生效的配置目录(例如
// `--config-dir`),否则退到平台配置根,保证
// `configure_game_creator_runtime_config_dir` 自身失败也有落点。
@@ -186,7 +186,7 @@ fn read_fixture_file(path: &Path) -> Result<Vec<u8>, String> {
use std::os::unix::fs::OpenOptionsExt;
options.custom_flags(libc::O_NOFOLLOW);
}
let mut file = options
let file = options
.open(path)
.map_err(|_| "平台登录态 fixture 文件不可读取".to_string())?;
let opened = file
@@ -351,7 +351,7 @@ pub(crate) fn load_local_project_media_preview_with_cancellation(
}
cancellation.check()?;
let source_byte_len = bytes.len() as u64;
/**
/*
* 图像容器(TGA / TIFF / HDR / EXR)在浏览器里没有解码器:先在原生侧转成 PNG,
* 再走与 GIF / BMP / AVIF 完全相同的「数据 URL + 图片卡」链路。转码是**只读**的,
* 不改工程文件;像素尺寸仍受既有的尺寸与像素总量上限约束,不会因为多一层解码
@@ -1040,9 +1040,8 @@ pub(crate) fn acquire_external_agent_runner_gui_participant_lock(
None
};
let deadline = Instant::now() + EXTERNAL_AGENT_RUNNER_GUI_PARTICIPANT_LOCK_ACQUIRE_TIMEOUT;
let mut last_error = "AGC 界面参与锁未知失败".to_string();
loop {
match open_external_agent_runner_lock_file(
let last_error = match open_external_agent_runner_lock_file(
&path,
"AGC 界面参与锁",
ExternalAgentRunnerLockMode::Shared,
@@ -1052,10 +1051,10 @@ pub(crate) fn acquire_external_agent_runner_gui_participant_lock(
return Ok(ExternalAgentRunnerGuiParticipantLock { _file: file });
}
Ok(None) => {
last_error = format!("AGC 界面参与锁无法以共享方式取得:{}", path.display());
format!("AGC 界面参与锁无法以共享方式取得:{}", path.display())
}
Err(error) => last_error = error,
}
Err(error) => error,
};
if Instant::now() >= deadline {
return Err(format!("取得 AGC 界面参与锁失败:{last_error}"));
}
@@ -1,5 +1,7 @@
use super::{dispatch::*, endpoint::*, protocol::*, state::*};
#[cfg(target_os = "linux")]
use sha2::{Digest as _, Sha256};
#[cfg(target_os = "linux")]
use std::fs;
use std::io;
use std::net::{Ipv4Addr, SocketAddrV4, TcpListener};
@@ -1,9 +1,10 @@
use std::collections::BTreeMap;
use std::path::Path;
use super::model::{AgentRuntimeToolPlanHandoffLedger, TOOL_PLAN_HANDOFF_MAX_DISCOVERED_LEDGERS};
#[cfg(unix)]
use super::model::{
AgentRuntimeToolPlanHandoffLedger, TOOL_PLAN_HANDOFF_MAX_DISCOVERED_AGENTS,
TOOL_PLAN_HANDOFF_MAX_DISCOVERED_FILES, TOOL_PLAN_HANDOFF_MAX_DISCOVERED_LEDGERS,
TOOL_PLAN_HANDOFF_MAX_DISCOVERED_AGENTS, TOOL_PLAN_HANDOFF_MAX_DISCOVERED_FILES,
};
use super::storage_common::is_handoff_path_key;
#[cfg(unix)]
@@ -12,7 +12,7 @@ use crate::ui_editor::layout::node::{Node as LayoutNode, NodeMetadata, NodeSourc
use crate::ui_editor::layout::transform::Transform;
use crate::ui_editor::resource::ui_design_image::UIDesignImage;
use crate::ui_editor::state::{State, UITree};
use crate::ui_editor::utils::{random_node_id, NodeId, UIDesignImageId};
use crate::ui_editor::utils::{random_node_id, UIDesignImageId};
use nalgebra::{Point2, Vector2};
use platform_llm::{
LlmFunctionTool, LlmMessage, LlmMessageContentPart, LlmRunRequest, LlmToolChoice,
@@ -1,6 +1,8 @@
use super::area::MIN_VISIBLE_ALPHA;
use base64::Engine as _;
use image::{ImageFormat, ImageReader, Rgba, RgbaImage};
#[cfg(test)]
use image::RgbaImage;
use image::{ImageFormat, ImageReader, Rgba};
use std::fs;
use std::io::Cursor;
use std::path::{Path, PathBuf};
@@ -1,5 +1,4 @@
use super::model::*;
use crate::ui_editor::commands::separation::*;
use std::fs::{self, OpenOptions};
use std::io::Write;
use std::path::{Path, PathBuf};
@@ -137,7 +137,7 @@ pub(crate) fn render_ui_design_state_js(
}
fn render_tree(state: &State, tree: &UITree) -> Result<Markup, String> {
let image = state
state
.ui_design_images
.get(&tree.src_ui_design)
.ok_or_else(|| format!("UITree 缺少 src_ui_design{}", tree.src_ui_design.as_str()))?;
@@ -12,7 +12,9 @@ use nalgebra::Vector2;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use std::collections::HashSet;
use std::fs::{self, File};
use std::fs;
#[cfg(unix)]
use std::fs::File;
use std::io::{Read, Write};
use std::path::Path;
use std::time::{SystemTime, UNIX_EPOCH};
@@ -19,7 +19,7 @@ use crate::*;
use image::GenericImageView as _;
use nalgebra::Vector2;
use serde::{Deserialize, Serialize};
use sha2::{Digest as _, Sha256};
use sha2::Sha256;
use shared_contracts::game_creation_app::GameCreationAppAssetKind;
use std::collections::{HashMap, HashSet};
use std::fs;
@@ -1,5 +1,7 @@
import { spawnSync } from 'node:child_process';
import fs from 'node:fs';
import { createRequire } from 'node:module';
import { dirname, resolve } from 'node:path';
const shellRoot = new URL('../', import.meta.url);
const easConfigPath = new URL('eas.json', shellRoot);
@@ -7,7 +9,10 @@ const packagePath = new URL('package.json', shellRoot);
const easConfig = JSON.parse(fs.readFileSync(easConfigPath, 'utf8'));
const packageConfig = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';
const shellRequire = createRequire(packagePath);
const easPackagePath = shellRequire.resolve('eas-cli/package.json');
const easPackage = JSON.parse(fs.readFileSync(easPackagePath, 'utf8'));
const easCliPath = resolve(dirname(easPackagePath), easPackage.bin.eas);
const androidBuildOutputPath =
'../../build/native/mobile/genarrative-mobile-android.apk';
const iosSimulatorBuildOutputPath =
@@ -43,8 +48,8 @@ if (packageConfig.devDependencies?.['eas-cli'] !== '^20.3.0') {
}
const easVersionResult = spawnSync(
npmCommand,
['exec', 'eas', '--', '--version'],
process.execPath,
[easCliPath, '--version'],
{
cwd: shellRoot,
encoding: 'utf8',

Some files were not shown because too many files have changed in this diff Show More