TL;DR (EN): On Windows, when aoci runs console-less (e.g. as an MCP stdio child of a host), every git probe spawns git.exe via exec.Command without SysProcAttr, so Windows allocates a new visible console for each child — windows flash and steal focus constantly. Suggested fix: HideWindow + CREATE_NO_WINDOW on Windows (patch below, locally verified: 0 windowed git.exe across 1310 samples).
环境
- Windows 11(10.0.22631)
- aoci v0.1.0-rc14(commit 92c78bc)
- MCP stdio 方式(ZCode 宿主,按 README 配置)+ Git for Windows
现象
aoci 每次刷新(MCP 服务启动时的 verify/check、aoci_overview / aoci_maintain / aoci_search 等工具调用中的 git 探测)都会弹出一个新的控制台窗口并抢占前台焦点,git.exe 退出后窗口随即关闭。agent 会话内刷新频繁时几乎无法正常打字,只能杀掉 aoci.exe。弹出的是承载 git.exe 的控制台窗口(不是 bash——aoci 不调 bash)。
根因
internal/fs/git_command.go 的 UntrustedRepositoryGitCommand(全仓读取 Git 事实的唯一通道,rev-parse/ls-files 等全部经它)直接 exec.Command("git", ...),未设置任何 Windows 窗口抑制:
command := exec.Command("git", append(hardened, args...)...)
command.Env = append(os.Environ(), "GIT_OPTIONAL_LOCKS=0")
return command
MCP stdio 场景下宿主以无控制台方式拉起 aoci;无控制台的父进程再拉起控制台子进程时,Windows 会为子进程新分配一个可见控制台窗口(见 Creation of a Console)。全仓目前只有 internal/ui/detach_windows.go 设置了 HideWindow(UI 服务器专用),git 链路没有。installer.go 给 codex 安装的 powershell hook 包装(powershell.exe -NoProfile ...)同样会在无控制台宿主下弹窗。
复现与度量方法
用 PowerShell 以 CreateNoWindow(模拟宿主拉 MCP 的形态)运行任意触发 git 探测的命令(如 aoci check),以 15ms 间隔轮询 Get-Process git 的 MainWindowHandle:补丁前即本 issue 描述的弹窗现象;打补丁后全程采样 1310 次 git.exe 子进程,0 个带窗口句柄。
建议修复(本地已验证)
按平台分文件给 git 构造器加隐藏控制台,共三处改动:
internal/fs/git_command_windows.go(新增):
//go:build windows
// Windows 控制台抑制 —— 与 git_command.go 同包的平台侧实现
//
// 威胁: aoci 常以无控制台形态运行(如 MCP stdio 由宿主拉起)。此时 exec 拉起
// 控制台子进程(git.exe)时,Windows 会为子进程新分配一个可见控制台窗口——
// 刷新期间反复弹窗并抢占用户焦点。
// 边界: CREATE_NO_WINDOW 只抑制控制台分配,不改变 stdio 句柄继承;宿主提供的
// 管道与真实终端下的交互输出不受影响。HideWindow(STARTF_USESHOWWINDOW+SW_HIDE)
// 作为兜底。调用方环境变量属操作者自身信任域,不在此处覆盖。
package fs
import (
"os/exec"
"syscall"
)
// createNoWindow 即 Win32 CREATE_NO_WINDOW(0x08000000)。
const createNoWindow = 0x08000000
// hideChildConsole 阻止 Windows 为 git.exe 子进程新建可见控制台窗口。
func hideChildConsole(cmd *exec.Cmd) {
if cmd.SysProcAttr == nil {
cmd.SysProcAttr = &syscall.SysProcAttr{}
}
cmd.SysProcAttr.HideWindow = true
cmd.SysProcAttr.CreationFlags |= createNoWindow
}
internal/fs/git_command_other.go(新增):
//go:build !windows
package fs
import "os/exec"
// hideChildConsole 在非 Windows 平台为空操作;可见控制台窗口问题仅 Windows 存在。
func hideChildConsole(*exec.Cmd) {}
internal/fs/git_command.go(一行):
hideChildConsole(command)
依据:Process Creation Flags — CREATE_NO_WINDOW (0x08000000):"The process is a console application that is being run without a console window."
本地验证结果(rc14 + 上述补丁,仅叠加本修复)
gofmt -l 干净;go vet ./... 通过;staticcheck 2026.2.1 零发现
go test ./... -count=1:除 internal/cli 外全部通过。internal/cli 的 17 个失败经在未打补丁的 rc14 上复跑确认为 Windows 既有问题(测试夹具以 baseline.json.bak\blocker 路径注入故障在 Windows 不生效),与本修复无关
scripts/blackbox/mcp_conformance.py:46 项中 44 项通过;2 项失败(search/get_entries)系套件以 aoci-code 仓自身文件为预期目标、对第三方仓库运行时的目标差异
- 真实 MCP 会话(ZCode 重连)确认运行版本为打好补丁的构建,刷新全程静默
如需要我可以直接按此提交 PR。
TL;DR (EN): On Windows, when aoci runs console-less (e.g. as an MCP stdio child of a host), every git probe spawns
git.exeviaexec.CommandwithoutSysProcAttr, so Windows allocates a new visible console for each child — windows flash and steal focus constantly. Suggested fix:HideWindow + CREATE_NO_WINDOWon Windows (patch below, locally verified: 0 windowed git.exe across 1310 samples).环境
现象
aoci 每次刷新(MCP 服务启动时的 verify/check、
aoci_overview/aoci_maintain/aoci_search等工具调用中的 git 探测)都会弹出一个新的控制台窗口并抢占前台焦点,git.exe 退出后窗口随即关闭。agent 会话内刷新频繁时几乎无法正常打字,只能杀掉 aoci.exe。弹出的是承载 git.exe 的控制台窗口(不是 bash——aoci 不调 bash)。根因
internal/fs/git_command.go的UntrustedRepositoryGitCommand(全仓读取 Git 事实的唯一通道,rev-parse/ls-files等全部经它)直接exec.Command("git", ...),未设置任何 Windows 窗口抑制:MCP stdio 场景下宿主以无控制台方式拉起 aoci;无控制台的父进程再拉起控制台子进程时,Windows 会为子进程新分配一个可见控制台窗口(见 Creation of a Console)。全仓目前只有
internal/ui/detach_windows.go设置了HideWindow(UI 服务器专用),git 链路没有。installer.go给 codex 安装的 powershell hook 包装(powershell.exe -NoProfile ...)同样会在无控制台宿主下弹窗。复现与度量方法
用 PowerShell 以
CreateNoWindow(模拟宿主拉 MCP 的形态)运行任意触发 git 探测的命令(如aoci check),以 15ms 间隔轮询Get-Process git的MainWindowHandle:补丁前即本 issue 描述的弹窗现象;打补丁后全程采样 1310 次 git.exe 子进程,0 个带窗口句柄。建议修复(本地已验证)
按平台分文件给 git 构造器加隐藏控制台,共三处改动:
internal/fs/git_command_windows.go(新增):internal/fs/git_command_other.go(新增):internal/fs/git_command.go(一行):依据:Process Creation Flags — CREATE_NO_WINDOW (0x08000000):"The process is a console application that is being run without a console window."
本地验证结果(rc14 + 上述补丁,仅叠加本修复)
gofmt -l干净;go vet ./...通过;staticcheck 2026.2.1 零发现go test ./... -count=1:除internal/cli外全部通过。internal/cli的 17 个失败经在未打补丁的 rc14 上复跑确认为 Windows 既有问题(测试夹具以baseline.json.bak\blocker路径注入故障在 Windows 不生效),与本修复无关scripts/blackbox/mcp_conformance.py:46 项中 44 项通过;2 项失败(search/get_entries)系套件以 aoci-code 仓自身文件为预期目标、对第三方仓库运行时的目标差异如需要我可以直接按此提交 PR。