app
Grok Bot
Public Made by Adomby adom
Grok Bridge lets Adom talk to Grok Bot. Adom's AI environment is for electrical engineers: any provider, any desktop power tool, one place.
main
John Lauer
grok-bridge 1.3.1: browser windows never count as the host app, grok_settings verb, grok_login presses Sign in, sign-in flow documented
7e59f9f
6d ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
"""App-window verbs: close / resize / record / login / logout / settings / plugin_install.
All driving is caller_identity.ad_callback (desktop_*). Never shell_execute /
pull_file / send_files. Prefer hide over process_kill. Never kill Cursor.
Background by default. Never invent grokbot:// routes other than
settings?id=* and plugin/add?id=.
"""
from __future__ import annotations
from urllib.parse import quote
from grok_detect import HOST_APP, detect_host
from handlers.windows import (
_cb,
_callback_ok,
_hwnd_of,
grok_hwnd,
launch_host,
pick_grok_window,
window_is_maximized,
window_is_minimized,
window_rect,
)
SETTINGS_DEEPLINK = "grokbot://app/v1/settings?id=theme"
PLUGIN_ADD_DEEPLINK = "grokbot://app/v1/plugin/add?id="
def _window_missing(verb: str) -> dict:
info = detect_host()
return {
"success": False,
"errorCode": "window_not_found",
"error": "No Grok Bot window.",
"hostApp": HOST_APP,
"hostAppFallback": info.get("hostAppFallback"),
"_hint": (
"No Grok Bot hwnd (titleContains Grok Bot, then Grok). "
"Call grok_open {} to launch Grok Bot in the background, then retry "
f"{verb}. Never kill Cursor."
+ (
" Grok Bot.exe was not found; Cursor is last-resort fallback and will not be closed."
if info.get("hostAppFallback") else ""
)
),
"_next": f"grok_open {{}} then grok_{verb}",
}
def handle_close(_args: dict) -> dict:
"""Hide the Grok Bot window. Prefer hide over process_kill. Never kill Cursor."""
# Do NOT target a generic Cursor window — that is the user's IDE on fallback.
hwnd, win = grok_hwnd(allow_cursor=False)
if not hwnd:
miss = _window_missing("close")
miss["closed"] = False
return miss
hide = _cb("desktop_set_window_state", {"hwnd": hwnd, "state": "hide"})
if _callback_ok(hide):
return {
"success": True,
"closed": True,
"via": "desktop_set_window_state hide",
"hwnd": hwnd,
"title": (win or {}).get("title"),
"killedProcess": False,
"windowEtiquette": "background",
"_hint": (
f"Hid Grok Bot hwnd={hwnd} via desktop_set_window_state state=hide. "
"Did not kill the process and did not touch Cursor. grok_open to show it again."
),
}
# Hide failed — restore (if needed) then try a UIA Close without process_kill.
if window_is_minimized(win) or window_is_maximized(win):
_cb("desktop_set_window_state", {"hwnd": hwnd, "state": "restore"})
click = _cb("desktop_ui_click", {"hwnd": hwnd, "name": "Close"})
if _callback_ok(click):
return {
"success": True,
"closed": True,
"via": "desktop_ui_click Close",
"hwnd": hwnd,
"hideAttempt": hide,
"killedProcess": False,
"windowEtiquette": "background",
"_hint": (
f"Hide failed; clicked UIA name=Close on Grok Bot hwnd={hwnd} in the background. "
"Did not process_kill. Never kills Cursor."
),
}
return {
"success": False,
"errorCode": "close_failed",
"closed": False,
"hwnd": hwnd,
"hideAttempt": hide,
"clickAttempt": click,
"killedProcess": False,
"_hint": (
"Could not hide or UIA-Close the Grok Bot window. Not killing the process "
"(prefer hide over process_kill; never kill Cursor). "
"Ask the human to close or hide Grok Bot, or retry grok_close after grok_list_windows."
),
"_next": "grok_list_windows {} then retry grok_close {}",
}
def _as_int(val, name: str):
if val is None or val == "":
return None
try:
return int(val)
except (TypeError, ValueError):
raise ValueError(name)
def handle_resize(args: dict) -> dict:
"""desktop_set_window_bounds on the Grok Bot hwnd. Physical px (same space as ab)."""
try:
w = _as_int(args.get("w") if args.get("w") is not None else args.get("width"), "w")
h = _as_int(args.get("h") if args.get("h") is not None else args.get("height"), "h")
x = _as_int(args.get("x") if args.get("x") is not None else args.get("left"), "x")
y = _as_int(args.get("y") if args.get("y") is not None else args.get("top"), "y")
except ValueError as e:
return {
"success": False,
"errorCode": "invalid_bounds",
"error": f"Invalid {e} — need integer physical px.",
"_hint": "grok_resize {w, h, x?, y?} in ab physical pixels. w and h required.",
"_next": "grok_resize {\"w\":1200,\"h\":800}",
}
if w is None or h is None:
return {
"success": False,
"errorCode": "bounds_required",
"error": "grok_resize needs {w, h}.",
"_hint": "Pass w and h in ab physical px. x and y default to the window's current origin.",
"_next": "grok_resize {\"w\":1200,\"h\":800}",
}
hwnd, win = grok_hwnd(allow_cursor=True)
if not hwnd:
return _window_missing("resize")
if window_is_maximized(win) or window_is_minimized(win):
_cb("desktop_set_window_state", {"hwnd": hwnd, "state": "restore"})
# Re-read origin after restore so omitted x,y stay physical-correct.
win = pick_grok_window(allow_cursor=True) or win
hwnd = _hwnd_of(win) or hwnd
cur = window_rect(win)
if x is None:
x = cur.get("x")
if y is None:
y = cur.get("y")
bounds = {"hwnd": hwnd, "w": w, "h": h}
if x is not None:
bounds["x"] = x
if y is not None:
bounds["y"] = y
# restore:false so MoveWindow does not raise (pup lesson: bounds can steal focus).
bounds["restore"] = False
res = _cb("desktop_set_window_bounds", bounds)
ok = _callback_ok(res)
if ok:
hint = (
f"desktop_set_window_bounds hwnd={hwnd} w={w} h={h}"
+ (f" x={x}" if x is not None else " (kept current x)")
+ (f" y={y}" if y is not None else " (kept current y)")
+ " in ab physical px. Restored first if maximized. Background — did not steal focus."
)
else:
hint = (
"desktop_set_window_bounds failed. grok_list_windows to confirm the hwnd, then retry. "
"w/h/x/y are physical px (same space as ab)."
)
out = {
"success": ok,
"hwnd": hwnd,
"bounds": {k: bounds[k] for k in ("x", "y", "w", "h") if k in bounds},
"callback": res,
"windowEtiquette": "background",
"_hint": hint,
}
if not ok:
out["errorCode"] = "resize_failed"
out["_next"] = "grok_list_windows {} then grok_resize {\"w\":...,\"h\":...}"
return out
def handle_record_start(args: dict) -> dict:
reason = (args.get("reason") or "").strip()
if not reason:
return {
"success": False,
"errorCode": "reason_required",
"error": "grok_record_start needs {reason}.",
"_hint": (
"Pass reason (forwarded to desktop_record_window_start). "
"Example: grok_record_start {\"reason\":\"demo of grok-bridge app control\"}."
),
"_next": "grok_record_start {\"reason\":\"...\"}",
}
hwnd, win = grok_hwnd(allow_cursor=True)
if not hwnd:
return _window_missing("record_start")
rec_args = {"hwnd": hwnd, "reason": reason}
res = _cb("desktop_record_window_start", rec_args, timeout=45)
ok = _callback_ok(res)
out = dict(res) if isinstance(res, dict) else {"callback": res}
out["success"] = ok
out.setdefault("hwnd", hwnd)
out.setdefault("reason", reason)
out.setdefault("title", (win or {}).get("title"))
out.setdefault("windowEtiquette", "background")
if not ok:
out.setdefault("errorCode", "record_start_failed")
out["_next"] = "grok_open {} then grok_record_start {\"reason\":\"...\"}"
out["_hint"] = (
f"desktop_record_window_start on Grok Bot hwnd={hwnd} reason={reason!r}. "
"Background WGC — no picker, no focus steal. Stop with grok_record_stop {}; "
"poll grok_record_status {}. The mp4 lands on the desktop; pull it with the CLI "
"(this HTTP callback never calls pull_file)."
if ok else
"desktop_record_window_start failed. Is Grok Bot visible to WGC? grok_open, then retry. "
"reason is required and is passed through."
)
return out
def handle_record_stop(args: dict) -> dict:
rec_args = {}
for k in ("recordingId", "id"):
if args.get(k):
rec_args["recordingId"] = args[k]
break
res = _cb("desktop_record_window_stop", rec_args, timeout=60)
ok = _callback_ok(res)
out = dict(res) if isinstance(res, dict) else {"callback": res}
out["success"] = ok
if not ok:
out.setdefault("errorCode", "record_stop_failed")
out["_next"] = "grok_record_status {} then grok_record_stop {}"
out["_hint"] = (
"desktop_record_window_stop. Recording file is on the desktop "
"(%TEMP%\\adom-bridge-recordings or the path in this payload). "
"Pull it with the adom-bridge CLI — this HTTP callback never calls pull_file."
if ok else
"desktop_record_window_stop failed. grok_record_status to see if a recording is active."
)
return out
def handle_record_status(_args: dict) -> dict:
res = _cb("desktop_record_window_status", {})
ok = _callback_ok(res)
out = dict(res) if isinstance(res, dict) else {"callback": res}
out["success"] = ok if res else True
out["_hint"] = (
"desktop_record_window_status wrap. Start with grok_record_start {reason}; "
"stop with grok_record_stop {}."
)
return out
def _open_deeplink(url: str) -> dict:
"""desktop_open_url refuses grokbot:// (http/https/mailto/ftp only). Launch the exe with the URL as an arg."""
return launch_host([url])
SIGN_IN_STEPS = (
"Sign-in is xAI's page ('Log into your Grok Bot account': Google / X / Apple / GitHub / email) in the OS "
"default browser, then Cursor's 'Enable data sharing' (leave Share Data off, press Continue), then "
"'Sign in to Grok Bot' with the account (press Sign in), then the browser's 'This site is trying to open "
"Grok Bot' prompt (press Open). Account-chooser rows are not UIA-invokable: use a foregrounded "
"desktop_click on the row only when the PC is idle (desktop_user_idle_ms). Never type passwords. "
"Afterwards the app may say 'Setting up Grok Bot's computer', then 'having trouble connecting' or "
"'Couldn't load Bots' for several minutes; wait, restart the app once, and only press Recover computer "
"if the user says the computer's installed apps can go (it removes them)."
)
def handle_login(_args: dict) -> dict:
"""Start sign-in. Signed-out splash: press its Sign in button (background UIA). Never types passwords."""
hwnd, _win = grok_hwnd(allow_cursor=False)
pressed = False
press_res = None
if hwnd:
press_res = _cb("desktop_ui_click", {"hwnd": hwnd, "name": "Sign in"})
pressed = _callback_ok(press_res) and not (press_res or {}).get("error")
if pressed:
return {
"success": True,
"pressedSignIn": True,
"hwnd": hwnd,
"typedPassword": False,
"windowEtiquette": "background",
"_hint": "Pressed Sign in on the Grok Bot splash (background UIA). The app now says 'Continue in your browser'. " + SIGN_IN_STEPS,
"_next": "desktop_list_windows {} to find the browser tab, then desktop_screenshot_window on it",
}
res = _open_deeplink(SETTINGS_DEEPLINK)
ok = _callback_ok(res)
return {
"success": ok or True, # opening settings is best-effort; the human signs in
"pressedSignIn": False,
"opened": ok,
"url": SETTINGS_DEEPLINK,
"background": True,
"typedPassword": False,
"callback": res,
"windowEtiquette": "background",
"_hint": (
"No signed-out splash found (already signed in, or the window is not up: grok_open first). Opened "
"Grok Bot settings via grokbot://app/v1/settings?id=theme in the BACKGROUND. " + SIGN_IN_STEPS
),
}
SETTINGS_PAGES = {"general": "general", "computer": "computer", "usage": "usage", "billing": "usage",
"updates": "updates", "theme": "theme"}
def handle_settings(args: dict) -> dict:
"""Open a Grok Bot Settings page (General / Computer / Usage & Billing / Updates) in the background."""
page = str(args.get("page") or args.get("id") or "usage").strip().lower()
sid = SETTINGS_PAGES.get(page)
if sid is None:
return {
"success": False,
"errorCode": "bad_args",
"error": f"unknown settings page {page!r}",
"_hint": "page is one of general, computer, usage (Usage & Billing: plan, weekly limit, on-demand cap), updates.",
"_next": "grok_settings {\"page\":\"usage\"}",
}
url = f"grokbot://app/v1/settings?id={sid}"
res = _open_deeplink(url)
ok = _callback_ok(res)
return {
"success": ok,
"opened": ok,
"page": page,
"url": url,
"windowEtiquette": "background",
"callback": res,
"_hint": (
(f"Opened Grok Bot Settings > {page} in the background. " if ok else
f"Could not launch Grok Bot with {url} (see callback); is it installed? grok_readiness. ")
+ "Read it with grok_screenshot. "
"Usage & Billing shows the plan (e.g. 'Current plan: Pro'), the weekly usage % and reset, and the "
"on-demand monthly cap billed through Cursor. Close the overlay with its X before typing in the chat."
),
"_next": "grok_screenshot {}",
"related": ["grok_screenshot", "grok_login"],
}
def handle_logout(_args: dict) -> dict:
"""Open settings; try background UIA Sign Out. Else needsHuman."""
opened = _open_deeplink(SETTINGS_DEEPLINK)
hwnd, win = grok_hwnd(allow_cursor=False)
if not hwnd:
hwnd, win = grok_hwnd(allow_cursor=True)
clicked = False
click_res = None
found = None
if hwnd:
found = _cb("desktop_find_control", {"hwnd": hwnd, "name": "Sign Out"})
click_res = _cb("desktop_ui_click", {"hwnd": hwnd, "name": "Sign Out"})
clicked = _callback_ok(click_res) and not click_res.get("error")
if not clicked:
# Allowed path: sidebar account button, then Sign Out.
acct = _cb("desktop_ui_click", {"hwnd": hwnd, "name": "Account"})
if _callback_ok(acct):
click_res = _cb("desktop_ui_click", {"hwnd": hwnd, "name": "Sign Out"})
clicked = _callback_ok(click_res) and not click_res.get("error")
if clicked:
return {
"success": True,
"loggedOut": True,
"needsHuman": False,
"hwnd": hwnd,
"openedSettings": _callback_ok(opened),
"windowEtiquette": "background",
"_hint": (
"Clicked UIA name containing Sign Out on the Grok Bot window in the background. "
"Did not type anything. If the session is still signed in, the human should "
"click Sign Out on the account card."
),
}
return {
"success": True,
"loggedOut": False,
"needsHuman": True,
"hwnd": hwnd,
"openedSettings": _callback_ok(opened),
"findControl": found,
"clickAttempt": click_res,
"windowEtiquette": "background",
"_hint": (
"Launched Grok Bot.exe with settings deep link as an arg (desktop_open_url refuses grokbot://). "
"Sign Out was not background-actionable via UIA. needsHuman:true — please click "
"**Sign Out** on the account card (sidebar account button → Sign Out). "
"This verb will not invent other UI paths and will not type."
),
"_next": "Human clicks Sign Out on the Grok Bot account card.",
}
def handle_plugin_install(args: dict) -> dict:
plugin_id = str(args.get("id") or args.get("pluginId") or "").strip()
if not plugin_id:
return {
"success": False,
"errorCode": "id_required",
"error": "grok_plugin_install needs {id}.",
"_hint": "Pass the plugin id. This opens grokbot://app/v1/plugin/add?id=<id> and does not confirm install — the app UI does.",
"_next": "grok_plugin_install {\"id\":\"...\"}",
}
url = PLUGIN_ADD_DEEPLINK + quote(plugin_id, safe="")
res = _open_deeplink(url)
ok = _callback_ok(res)
return {
"success": ok or True,
"opened": ok,
"id": plugin_id,
"url": url,
"confirmed": False,
"background": True,
"callback": res,
"windowEtiquette": "background",
"_hint": (
f"Launched Grok Bot.exe with {url} as an arg (desktop_open_url refuses grokbot://). This does NOT confirm install — the Grok Bot "
"app UI does. The human may need to accept the plugin add dialog."
),
}