diff --git a/apps/ai-game-creator-shell/scripts/game-creator-config-wizard.mjs b/apps/ai-game-creator-shell/scripts/game-creator-config-wizard.mjs index 6751f1f4a..0d0522f22 100644 --- a/apps/ai-game-creator-shell/scripts/game-creator-config-wizard.mjs +++ b/apps/ai-game-creator-shell/scripts/game-creator-config-wizard.mjs @@ -31,8 +31,8 @@ const npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm'; const windowsPrivateAclScript = String.raw` $ErrorActionPreference = 'Stop' -$target = [System.IO.Path]::GetFullPath($args[0]) -$isDirectory = [System.Boolean]::Parse($args[1]) +$target = [System.IO.Path]::GetFullPath($env:GENARRATIVE_AGC_PRIVATE_PATH) +$isDirectory = [System.Boolean]::Parse($env:GENARRATIVE_AGC_PRIVATE_IS_DIRECTORY) $currentSid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User $inheritance = [System.Security.AccessControl.InheritanceFlags]::None if ($isDirectory) { @@ -297,9 +297,13 @@ export async function secureWindowsGameCreatorPathForCurrentUser( 'Bypass', '-Command', windowsPrivateAclScript, - targetPath, - String(isDirectory), - ]); + ], { + env: { + ...process.env, + GENARRATIVE_AGC_PRIVATE_PATH: targetPath, + GENARRATIVE_AGC_PRIVATE_IS_DIRECTORY: String(isDirectory), + }, + }); if (result.code !== 0 || result.signal) { const detail = result.stderr.trim() || result.stdout.trim(); throw new Error( diff --git a/docs/project-memory/shared-memory/pitfalls.md b/docs/project-memory/shared-memory/pitfalls.md index e694a6326..3c774f3aa 100644 --- a/docs/project-memory/shared-memory/pitfalls.md +++ b/docs/project-memory/shared-memory/pitfalls.md @@ -3641,6 +3641,7 @@ - 原因:把首次配置、手工多轮聊天、单轮真实测试和持续试玩当成同一个交互生命周期;同时让 GUI 与 CLI 使用不同配置入口,或把 EOF 既解释为“提交当前需求”又解释为“没有输入”,会让退出语义随调用环境漂移。 - 处理:GUI 与 `npm run agc:config` 共用系统 AppData `game-creator.config.json`,终端隐藏输入 API Key 并禁止 `--api-key`;更新时保留 `agentLlm`、`editorApi`、`mcpServers` 等其它配置,POSIX 权限维持目录 `0700` / 文件 `0600` 并原子替换。显式 `--config-dir` 必须以 `world.genarrative.ai-game-creator` 为独立叶目录,不能让向导对 `/tmp`、AppData 根或共享目录整体 chmod / 重建 DACL。隐藏输入调用 `stdin.resume()` 后必须记住原 pause 状态,在成功、取消、异常和 `SIGINT / SIGTERM / SIGHUP` 路径恢复 raw mode 并 `pause()`,信号恢复后重发;只移除 `data` listener 会让 `--configure-only`、配置检查失败或 Ctrl+C 保持活动 stdin。缺配置时仅 TTY 人工会话可询问进入向导,非 TTY 立即失败并提示配置命令。 - Windows 密钥复制:`mode: 0o600` 和 POSIX `chmod` 在 Windows 上不能代替 DACL。隔离 AppData 目录必须先设置仅当前用户、禁止继承的 DACL;目标配置文件先以空文件创建并收紧 DACL,之后才允许把 API Key 字节写入。先 `copyFile` 再依赖 Rust 只读检查或事后收紧会留下密钥暴露窗口,也可能因继承 ACL 不满足 Runtime 合同而在首次 `--llm-status` 失败。 +- Windows PowerShell 参数:不要把 DACL 目标路径和目录标记直接追加在 `powershell.exe -Command