Console window sentinel (stray black console windows are hidden)
The helper that stops stray black console windows from popping over the app on Windows when automated work starts a program with no console to attach to. Covers what it hides, what it deliberately leaves alone, how to read its log, the companion rule about registering scheduled tasks, and the agent-browser equivalent.
Status: shipped, ON by default on Windows. Nothing to set up. Developers can switch it off with
AMC_DISABLE_CONSOLE_SENTINEL=1in the app's environment. macOS and Linux have no stray console windows, so it does nothing there.
What it is
On Windows, the programs that agents run all day — git hooks, PowerShell, node, the Git-for-Windows
shell tools — sometimes start without a console to attach to. When that happens Windows draws a
brand-new black console window on your screen and often hands it the keyboard focus. With many
agents running, that can happen several times an hour: a black box pops over Omniscio, your typing
lands in it, and it may sit there for minutes. The same thing happens when a scheduled task is
registered with a bare console program (powershell.exe -File …) — Task Scheduler runs it in your
session with a full-size visible window.
The console window sentinel is a small helper that Omniscio starts with the app. It watches for console windows the moment they appear and hides the ones that belong to automation:
- a console opened anywhere inside an agent session's process tree;
- a console opened by one of Omniscio's own helper processes;
- a console opened by a Windows Scheduled Task running in your session.
Hiding only hides the window — the program keeps running exactly as before, its output is unaffected, nothing is killed, and no Windows setting is changed.
Where to find it
There is nothing to open and nothing to switch on — the sentinel starts with the app and works invisibly, so it never appears as a panel, a menu item or a settings page. Nothing about it is visible while it is doing its job; the only place it surfaces is a log of its decisions, which you reach by asking an agent to read it out rather than by clicking anything.
How it behaves
What it never does
- It never hides a console you opened yourself — from Explorer, Windows Terminal, a shortcut, or any program you launched. It only hides a window it can positively prove belongs to automation.
- When it cannot tell who owns a window, it leaves the window alone and writes down why.
- It never shows an inbox card or a toast. Its whole job is to be silent.
- A program that genuinely needs a visible console (a sign-in flow you have to see) can declare it
with
AMC_ALLOW_VISIBLE_CONSOLE=1in its environment and is left visible; Omniscio's own intentional terminals are never touched.
How to see what it did
Every decision — hide, leave, or "could not tell" — is one line in a small rolling log with the
window title, the owning program, its parent chain, and the rule that decided. Ask an agent to run
npm run console-sentinel:report (or run it in the repo yourself) to see the most recent lines.
"Which process popped a window?" always has an answer.
The companion guard
Agents may no longer register a Windows Scheduled Task whose action is a bare console program
(powershell, cmd, node, git, bash, python, npm…). The registration is refused with the
hidden form spelled out (conhost.exe --headless <program> <args>). A deliberately visible task
states AMC_ALLOW_VISIBLE_TASK=1 in the command.
Agent browsers
The second thing that used to pop over Omniscio was not a console at all: an agent browser (the agent-browser tool) opened with a visible window, which lands blank and dark at the top-left of the screen and takes the focus. Two things now deal with it:
- An agent command that would open a visible browser is refused before it runs, with the headless
alternative named:
agent-browser --headed,ab-broker watchorlogin,AGENT_BROWSER_HEADED=1, and the one with no flag at all — a project (or user)agent-browser.jsonthat declaresextensions, which makes agent-browser open a real window even when the same file says"headed": false. Chrome loads extensions headless since version 112, so the refusal points at the form that keeps the extension without the window:agent-browser --args "--load-extension=<path>" open <url>. A person who wants to watch addsAMC_ALLOW_VISIBLE_BROWSER=1to the command. - A window that still appears is parked off-screen by the browser-window hider the moment it shows.
That only holds while the hider is actually running: check for a process whose command line
contains
amc-browser-window-hiderrather than trusting a schedule that says it ran.
Omniscio does not try to force headless through the environment: AGENT_BROWSER_HEADED only ever
turns the window on, so setting it to 0 changes nothing (measured).
Limits worth knowing
- The window can flash for a moment before it is hidden. Windows paints a new console window before anything is told about it, so a brief flicker is the floor for hiding it after the fact. It is hidden as soon as it appears — not at the next periodic check — so a window that sits on screen for a second or more means the sentinel is not keeping up, which is a bug worth reporting.
- Agent Bash tool calls no longer bring a console of their own. On Windows each agent shell now
attaches to its session's hidden console (or opens a windowless one) through a bundled bash
trampoline, so the per-command console — and its flash — is never created in the first place. A
flash from a
bash.exeunder aclaudesession means the trampoline is switched off (AMC_DISABLE_BASH_TRAMPOLINE=1) or its executable is missing; the session then runs as before. - A descendant of the app is recognised even when its environment was cleaned and its parent has
already exited. Omniscio writes a short, install-specific marker directory into the
PATHof every process it starts, and the sentinel treats an exact match on that entry as proof of ownership.PATHis what survives the cleanup that strips the other breadcrumbs, so a window whose owner kept only itsPATHis still hidden rather than left on screen. A window that carries neither the marker nor any traceable ancestry is still left visible and logged — the sentinel never hides on a guess. - The sentinel only watches while the app is running — it starts with the app and stops when
it quits. So the background jobs
npm run devkicks off while it starts (the master catch-up, the verdict tool install) and the tidy-up it runs as the app quits are launched with a hidden console of their own instead: nothing they run opens a window, whether or not the sentinel is up yet. A burst of console windows whilenpm run devstarts or the app quits is a bug worth reporting. - A console window opened by a program running as administrator cannot be hidden by Omniscio, because Windows does not let a normal process hide an elevated window. Those windows are retried and then logged; they are the one case Omniscio cannot fully silence.
- Packaged installer builds ship it too. The helper and the native bridge it needs travel with the app, so a normal installed Omniscio hides stray consoles exactly the way a development checkout does. (Before 2026-10-06 they did not ship the helper, and the sentinel quietly did nothing on an installed build — the 2026-10-06 report of a console window popping over a packaged install while a test tool started its own helper program.) A detached child is the shape that gets one: a tool that starts its helper with a detached process gets a brand-new visible console from Windows, which is what the sentinel hides.
- At most one sentinel runs per machine; if Omniscio is restarted, the old one steps aside and the new app's sentinel takes over.
Related
The older, opt-in switch that changes which terminal hosts a stray console is described under Reduce terminal popups — the sentinel makes it largely unnecessary, but the two do not conflict. The visible-agent-browser problem shares this page because it is the same complaint from a different source; the browser tooling the agent drives, and the headless flags this page names, are on the Chrome extension dev page.
- Reduce terminal popups — the older, opt-in setting that changes WHICH terminal hosts a stray console. The sentinel makes it largely unnecessary, but both can be on.
- Contract:
.claude/memory/contracts/console-window-sentinel-contract.md.
Last verified 2026-10-06