修复 Web 游戏预检的用户目录依赖 #527
@@ -355,10 +355,25 @@ fn valid_version(value: &str) -> bool {
|
||||
}
|
||||
|
||||
async fn probe_version(runtime: &NodeRuntime, npm: bool) -> Result<String, String> {
|
||||
// npm 初始化也会查询用户目录;显式隔离,避免依赖 Windows 后备查询。
|
||||
let home = tempfile::tempdir().map_err(|_| "runtime-probe-home-unavailable")?;
|
||||
let config = home.path().join("user.npmrc");
|
||||
let global_config = home.path().join("global.npmrc");
|
||||
fs::write(&config, b"").map_err(|_| "runtime-probe-home-unavailable")?;
|
||||
fs::write(&global_config, b"").map_err(|_| "runtime-probe-home-unavailable")?;
|
||||
let mut command = tokio::process::Command::new(&runtime.node);
|
||||
command
|
||||
.env_clear()
|
||||
.env("PATH", &runtime.safe_path)
|
||||
.current_dir(home.path())
|
||||
.env("HOME", home.path())
|
||||
.env("USERPROFILE", home.path())
|
||||
.env("APPDATA", home.path())
|
||||
.env("LOCALAPPDATA", home.path())
|
||||
.env("npm_config_userconfig", &config)
|
||||
.env("npm_config_globalconfig", &global_config)
|
||||
.env("npm_config_cache", home.path().join("npm-cache"))
|
||||
.env("npm_config_update_notifier", "false")
|
||||
.stdin(Stdio::null())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::null())
|
||||
@@ -651,5 +666,19 @@ mod tests {
|
||||
));
|
||||
assert!(valid_version(&probe_version(&runtime, true).await.unwrap()));
|
||||
assert_eq!(fs::read_dir(root.path()).unwrap().count(), 0);
|
||||
let fixture = root.path().join("probe.cjs");
|
||||
fs::write(
|
||||
&fixture,
|
||||
include_str!("../tests/fixtures/environment-probe.cjs"),
|
||||
)
|
||||
.unwrap();
|
||||
let fixture_runtime = NodeRuntime {
|
||||
npm_cli: fixture,
|
||||
..runtime
|
||||
};
|
||||
assert_eq!(
|
||||
probe_version(&fixture_runtime, true).await.unwrap(),
|
||||
"1.0.0"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const home = process.env.HOME;
|
||||
assert.ok(home && fs.statSync(home).isDirectory());
|
||||
for (const key of ['USERPROFILE', 'APPDATA', 'LOCALAPPDATA']) {
|
||||
assert.equal(process.env[key], home);
|
||||
}
|
||||
assert.equal(fs.realpathSync(process.cwd()), fs.realpathSync(home));
|
||||
assert.equal(
|
||||
fs.realpathSync(require('node:os').homedir()),
|
||||
fs.realpathSync(home),
|
||||
);
|
||||
for (const key of ['npm_config_userconfig', 'npm_config_globalconfig']) {
|
||||
assert.equal(path.dirname(process.env[key]), home);
|
||||
assert.equal(fs.readFileSync(process.env[key], 'utf8'), '');
|
||||
}
|
||||
assert.equal(process.env.npm_config_cache, path.join(home, 'npm-cache'));
|
||||
process.stdout.write('1.0.0\n');
|
||||
@@ -1,5 +1,9 @@
|
||||
# 踩坑与排障记录
|
||||
|
||||
## AGC 版本探测必须显式提供隔离用户目录
|
||||
|
||||
清空子进程环境后缺少 `USERPROFILE/HOME` 会让 npm 依赖 Windows 后备用户查询,部分机器报 `uv_os_homedir` / `ENOMEM`。正常机器探测成功不能证明环境完整,需同时验证子进程环境。版本探测使用临时用户目录和空 npm 配置,详见 [AGC 实施计划](../../technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md) 的“Web 环境版本探测的用户目录隔离”。
|
||||
|
||||
## 美术包固定 PNG 路径与平台返回格式不一致
|
||||
|
||||
- 平台生成成功仍可能返回 JPEG/WebP;直接按 `assets/art-spec.png` 等固定路径保存会在扩展名校验时失败,图片尚未落盘但已付费结果账本仍存在,不能据 manifest 为空认定没有生成结果。
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# AI 游戏创作智能体 App 实施计划
|
||||
|
||||
## 2026-09-28 Web 环境版本探测的用户目录隔离
|
||||
|
||||
Node/npm 版本探测清空继承环境后,必须设置客户端创建的临时 `HOME`、`USERPROFILE`、`APPDATA` 和 `LOCALAPPDATA`,并指定空的用户及全局 npm 配置、临时缓存和临时工作目录。临时目录保留到探测子进程退出,不依赖 Windows 用户资料查询,也不读取用户或项目的 `.npmrc`。探测继续使用校验后的客户端运行时;初始化临时环境失败返回 `runtime-probe-home-unavailable`,不回退到系统 Node 或真实用户目录。
|
||||
|
||||
验证使用真实 Node/npm 的 `environment_check::tests::real_node_npm_environment_versions`,同时用 `src-tauri/tests/fixtures/environment-probe.cjs` 检查隔离目录及空配置,避免正常机器的 Windows 后备查询掩盖回归。测试通过 `include_str!` 引用独立夹具,不把 Node 环境断言内嵌到生产源码扫描范围。此测试需要本地 Node/npm,默认忽略,定向验收时显式运行;另运行 `npm run ai-game-creator-shell:typecheck` 覆盖配置静态检查。
|
||||
|
||||
## 2026-09-28 AGC 客户端现行分工:离线前端、事件驱动与维护态出口
|
||||
|
||||
本节是 AGC 客户端「React 只做展示与交互」的现行口径,取代更早文档里渲染层直连平台网络、按固定频率轮询、自行解析维护响应的做法。
|
||||
|
||||
Reference in New Issue
Block a user