Repository navigation
Conversation
|
confirmed this is fixed by this PR on my windows 26100.8328 Cheers! 🍻 |
|
Hi @mlalpho - how did you test it? I have a hard time reproducing the windows popping up |
|
hi @neriousy , i was hitting pretty regularly so didn't have trouble. watching conhost fires: # Watch for new conhost.exe processes (visible console windows) while testing
# the OpenCode desktop app. Run this in a PowerShell window, then exercise the
# app (agent commands, Code Mode tool calls). New conhost entries with a real
# parent chain indicate a console window was allocated. ConPTY sessions also
# create conhost.exe entries; the parent/command line distinguishes them.
#
# Usage: powershell -ExecutionPolicy Bypass -File watch-conhost.ps1 -Seconds 180
param(
[int]$Seconds = 180
)
$ErrorActionPreference = "SilentlyContinue"
$query = "SELECT * FROM __InstanceCreationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.Name LIKE 'conhost%'"
Write-Host "Watching for new conhost.exe processes for $Seconds seconds..."
Write-Host "Exercise the app now (run agent commands, Code Mode tool calls)."
Write-Host ""
$watcher = New-Object System.Management.ManagementEventWatcher($query)
$count = 0
$sw = [System.Diagnostics.Stopwatch]::StartNew()
while ($sw.Elapsed.TotalSeconds -lt $Seconds) {
try {
$event = $watcher.WaitForNextEvent()
$p = $event.TargetInstance
$count++
$parentPid = $p.ParentProcessId
$parent = Get-CimInstance Win32_Process -Filter "ProcessId=$parentPid"
$parentName = "<pid $parentPid exited>"
if ($parent) { $parentName = $parent.Name + " (" + $parent.CommandLine + ")" }
$cmd = $p.CommandLine
if (-not $cmd) { $cmd = "" }
if ($cmd.Length -gt 160) { $cmd = $cmd.Substring(0, 160) + "..." }
Write-Host ("[{0}] conhost pid={1}" -f (Get-Date -Format "HH:mm:ss.fff"), $p.ProcessId)
Write-Host (" parent: {0}" -f $parentName)
Write-Host (" cmd: {0}" -f $cmd)
} catch [System.Management.ManagementException] {
# query poll timeout; continue
}
}
Write-Host ""
Write-Host ("Done. Total new conhost.exe processes observed: {0}" -f $count)
Write-Host "Notes:"
Write-Host " - conhost with parent opencode-cli.exe/opencode.exe + no '--headless' can be a visible flash (bug)"
Write-Host " - conhost parents under \WindowsApps or with ConPTY handles are usually hidden pseudoconsoles"This is the prompt i sent to the session while running the opencode beta build i made from this pr's commit: running prompt A/B (on production and beta and watching conhost log and checking for popups before and after: |
|
But this doesn't help me. it doesnt pop up windows for me. Do you use any plugins? |
|
yes, in this test it loaded 3 plugins that work on v2. only two plugin tools 'custom file reading tool' and 'custom shell tool' were exercised by this prompt. the rest were via native tool calls or code mode. i'm rerunning on project that doesn't load plugins locally. |
|
well dang, I can't reproduce without these plugins loaded (empty project folder) ... i can still confirm the fix works. it looks like i might be seeing a tool.execute.before hook that spawns a cmd.exe wrapper with node's execSync |
|
welcome to my world lol! Like I feel like I'm onto somethig but not quite |
|
good luck ! i'll let you if i find anything more concrete. looking forward to this fix lol |
|
you can try cleaning your .opencode/plugins directories maybe that will do smth |
|
I found the underlying script that the plugin was running. the call site for execSync needed an explicit 'windowsHide: true' .. which is what this PR fixes at a lower level. at the moment its up to plugin developers to play whack-a-mole with windowsHide params and exec*Sync calls (or similar spawn sites) This particular script was called by the tool.execute.before hook so it looked like almost all tools were causing. |
Issue for this PR
Closes #51887
Closes #50868
Refs #42440, #45259
Type of change
What does this PR do?
Problem. Clients start the shared service with
detached: true(packages/client/src/service-contender.ts). On Windows that isDETACHED_PROCESS, so the service has no console. Every console program it starts withoutCREATE_NO_WINDOW(windowsHide) then gets a new visible console window (a conhost window or a Windows Terminal tab that steals focus).Core's own spawns already pass
windowsHide(cross-spawn-spawner.ts). The reports come from processes we don't control:Bun.spawn/$/child_process(omo runningtasklistin [Bug] OpenCode2 CLI Endlessly Pops Up Windows on Windows #51887,rtk.tsandherdr-agent-state.json every shell command in windows: console window flashes on every subprocess spawn (v2 next build) #42440,oh-my-opencode-slim)git rev-parseguards)git ls-remote/git clonefor git plugin specs (server: unpinned plugin update check flashes visible git console window on Windows #50868)In v1 the server ran inside the TUI's console, so all of these were invisible. That's also why
--standalonemakes the flashing disappear. AddingwindowsHideto the service spawn (#45259) doesn't work, because Windows ignoresCREATE_NO_WINDOWwhen it's combined withDETACHED_PROCESS. Droppingdetacheddoesn't work either: libuv puts non-detached children in a kill-on-close job, so the service would die with the CLI.Fix. When running as
serve --serviceon Windows, the service callsAllocConsoleWithOptions(ALLOC_CONSOLE_MODE_NO_WINDOW)at startup, before anything is spawned. The service now has a console with no window, and processes it starts share it instead of allocating their own. This covers plugins, hooks, MCP launch chains and npm's git calls without each call site having to setwindowsHide. Desktop starts the service throughserve --servicetoo, so it's covered.AllocConsoleWithOptionsexists. Older builds skip it and keep today's behavior. The older fallback (AllocConsole+ hide) would likely flash once at startup, and with Windows Terminal as the default terminal it could leave a visible tab, so I left it out.opencode-node) gets a no-op through the#hidden-consoleimport, the same waypackages/corehandles#pty.How did you verify your code works?
bun typecheckinpackages/clibun test test/service.test.ts test/import-boundaries.test.ts test/standalone.test.tsinpackages/cli#hidden-consoleto the Bun file and Node to the no-op file; on macOS the call is a no-opNot yet verified on Windows. This is a draft until someone tests it on Windows 11 24H2+:
opencode service stopwindowsHide(omo,rtk.ts) and/or an unpinned git plugin such assuperpowers@git+https://github.com/obra/superpowers.gitcould not attach a hidden consolewarning in the service logScreenshots / recordings
N/A
Checklist