Skip to content

docker-compose: expose WINEBOT_ALLOW_HEADLESS_HYBRID in headless profile#52

Closed
mark-e-deyoung wants to merge 1 commit into
SemperSupra:mainfrom
mark-e-deyoung:fix/allow-headless-hybrid-override
Closed

docker-compose: expose WINEBOT_ALLOW_HEADLESS_HYBRID in headless profile#52
mark-e-deyoung wants to merge 1 commit into
SemperSupra:mainfrom
mark-e-deyoung:fix/allow-headless-hybrid-override

Conversation

@mark-e-deyoung

Copy link
Copy Markdown
Collaborator

Problem

Headless WineBot containers cannot programmatically launch or control Windows applications via the API. All agent-initiated endpoints (/apps/run, /run/ahk, /run/python, /input/*) return HTTP 423: Agent control denied by policy.

Root Cause

The docker-compose headless profile does not expose WINEBOT_ALLOW_HEADLESS_HYBRID, which is required to enable hybrid control mode in headless operation. This env var is already fully supported in:

  • api/core/config_guard.py (lines 317-320, 334)
  • api/utils/config.py (line 49, 193-194)
  • api/routers/control.py (lines 161-162)
  • scripts/internal/validate-winebot-config.py (line 81)
  • tests/test_config_guard.py (test_headless_hybrid_requires_explicit_override)
  • tests/test_invariants.py (line 47)
  • README.md (line 49)

Input Pipeline Architecture

The Wine desktop shell (explorer.exe /desktop) intercepts X11 keyboard events, preventing VNC/xdotool key injection from reaching individual app windows. For headless automation that needs per-app keyboard control, there are two paths:

  1. Hybrid control mode (WINEBOT_ALLOW_HEADLESS_HYBRID=1): Enables API endpoints that use AutoHotkey/Windows hooks for keyboard injection within the Wine desktop — these bypass the X11 interception layer.

  2. No desktop shell (WINEBOT_SUPERVISE_EXPLORER=0): Disables the desktop supervisor so explorer.exe /desktop does not restart. Apps then create standalone X11 windows that xdotool and VNC keyboards can target directly.

Fix

  • Add WINEBOT_ALLOW_HEADLESS_HYBRID to the shared x-winebot-env anchor so ALL profiles inherit it
  • Add it explicitly to the headless profile
  • Add WINEBOT_SUPERVISE_EXPLORER to the headless profile so automation can optionally disable the desktop shell supervisor

Usage

# Enable agent-initiated automation in headless mode:
WINEBOT_ALLOW_HEADLESS_HYBRID=1 \
WINEBOT_INSTANCE_CONTROL_MODE=hybrid \
docker compose --profile headless up

# Or disable the desktop shell for per-app X11 targeting:
WINEBOT_SUPERVISE_EXPLORER=0 \
docker compose --profile headless up

Testing

Existing test coverage confirms this works:

  • tests/test_config_guard.py::test_headless_hybrid_requires_explicit_override (passes)
  • tests/test_invariants.py (line 47 tests allow_headless_hybrid=True -> ok=True)

No new tests needed — this is a configuration exposure, not a code change.

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

The WINEBOT_ALLOW_HEADLESS_HYBRID env var was already plumbed through
the config guard, API, tests, and README, but was not exposed in the
docker-compose headless profile. This prevented headless automation
from programmatically launching apps or injecting input via the API.

Changes:
- Add WINEBOT_ALLOW_HEADLESS_HYBRID to x-winebot-env shared anchor
  so all profiles inherit it
- Add WINEBOT_ALLOW_HEADLESS_HYBRID to headless profile explicitly
- Add WINEBOT_SUPERVISE_EXPLORER to headless profile so headless
  automation can disable the desktop shell supervisor when needed

When WINEBOT_ALLOW_HEADLESS_HYBRID=1 and
WINEBOT_INSTANCE_CONTROL_MODE=hybrid, agent-initiated /apps/run,
/run/ahk, /run/python, and /input/* endpoints become available.

This enables headless WineBot containers to load and control Windows
applications programmatically without human-in-the-loop VNC clicks.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@mark-e-deyoung

Copy link
Copy Markdown
Collaborator Author

Superseded by commit a7184c8 which includes these docker-compose changes plus a new /input/key endpoint and comprehensive tests.

mark-e-deyoung added a commit that referenced this pull request Jun 21, 2026
feat: add /input/key endpoint and fix headless keyboard input pipeline

Adds a POST /input/key API endpoint for keyboard injection into Windows
applications. The endpoint defaults to AHK Send injection, which operates
inside the Wine process space and bypasses the X11 explorer.exe/desktop
keyboard interception layer entirely.

Key changes:
- New /input/key endpoint in api/routers/input.py with AHK and xdotool backends
- xdotool-to-AHK key syntax translation (_xdotool_to_ahk_keys)
- KeyModel Pydantic model for request validation
- WINEBOT_INPUT_KEY_BACKEND and WINEBOT_TIMEOUT_INPUT_KEY_SECONDS config fields
- Expose WINEBOT_ALLOW_HEADLESS_HYBRID and WINEBOT_SUPERVISE_EXPLORER in docker-compose
- Document keyboard barrier and solutions in docs/troubleshooting.md
- 20 unit tests for key translation, e2e test for full pipeline
- All existing tests pass (162 passed, 0 new failures)
- Ruff and Mypy pass clean

Closes PR #52 and #53 (superseded by this commit).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant