Skip to content

Post-Mortem: Mobile Keyboard Suppression Failure & GitOps Worktree Friction #87

Description

@BrianV1981

Post-Mortem & Architecture Failures

1. The Mobile Keyboard Suppression Rabbit Hole (A Complete Failure)

For several hours, we attempted to surgically suppress the native Android Chrome mobile keyboard while allowing users to scroll and highlight text in the Monaco Editor and Xterm.js terminal ("Read-Only" mode).
This endeavor ended in a catastrophic failure and had to be completely abandoned via a hard git reset.

The Cat-and-Mouse Game:

  1. We initially used React useEffect to set disableStdin on Xterm and readOnly on Monaco. Android Chrome completely ignored this and spawned the keyboard upon touching the screen anyway.
  2. We then attempted a DOM sweep using document.querySelectorAll('textarea').forEach(el => el.readOnly = true; el.setAttribute('inputmode', 'none')). This worked momentarily, but Monaco dynamically destroys and re-creates its textareas when the canvas resizes, bypassing the sweep.
  3. We implemented a nuclear CSS override using .hide-native-keyboard textarea { visibility: hidden !important; pointer-events: none !important; }. Monaco detected its element was hidden, panicked, and forcefully injected inline DOM styles (visibility: visible !important) to fight back. Android saw the visible textarea and spawned the keyboard.
  4. We deployed a MutationObserver to watch the DOM and forcefully set disabled=true on any new textareas. Monaco bypassed this by not injecting new elements, but rather secretly flipping contenteditable="false" back to contenteditable="true" on existing nodes via touch event handlers.
  5. We updated the MutationObserver to watch for attributes: true. However, because we didn't perfectly account for standard textareas returning null for contenteditable, our boolean check evaluated to true, causing the observer to mutate the element again. This triggered another mutation event, plunging the React engine into a catastrophic infinite layout loop that flooded the browser's JavaScript execution thread, completely freezing the UI and rendering all buttons unresponsive.

Conclusion:
Fighting the mobile OS's native keyboard heuristics via DOM hacking is fundamentally flawed. We reverted to the stable VS Code Monaco editor configuration. The Android keyboard will pop up when text is highlighted on mobile, but the app is stable.

2. The GitOps / Workspace Sandbox Difficulties

During the aim-connect project, we experienced severe operational friction regarding the GitOps sandbox architecture.

The Problem:
We use python3 .aim_core/aim_cli.py fix <id> to check out a unique branch into an isolated git worktree inside the workspace/ directory (e.g., workspace/issue-86/).
However, the aim-connect backend and frontend rely on shared .env files, static mount directories (/assets), and dist/ folders.
When operating in an isolated worktree, the build tools and backend scripts constantly get confused about their Root Directory, resulting in:

  • npm run build compiling to the wrong dist/ folder or being unable to be served by the backend.
  • Tmux background terminals inheriting the outer workspace's environment variables rather than the isolated worktree's environment, causing the backend to serve old code.
  • Frequent 404 errors for static assets like index.html because the SPA middleware doesn't cleanly support isolated worktree paths out of the box without manual .env override injections (AIM_WORKSPACE).

Recommendation:
The GitOps Sandbox / Worktree architecture needs a native "environment localization" wrapper. When an agent enters a worktree, all background tmux sessions, Vite build tools, and FastAPI static mount paths MUST dynamically lock their working directories to the worktree path, overriding any inherited .env states from the parent git repository.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions