Marcin, just an idea/theory: it may be possible to inject something into a page that monkey-patches XMLHttpRequest and wraps it, to allow you to trigger logic before/after it is complete. Angular's Zone module does something similar to trigger change detection. So (again, in theory) it could be possible to replace XMLHttpRequest in the page with something that communicates back to Geb and triggers an "auto-wait" for the async call.
Unfortunately, I'm not sure even that would really work, since usually an app actually does something itself after an async call. I don't see any way for Geb to "know" how to wait for any app-specific logic that's triggered after the async call is done. I suppose as a halfway solution, Geb could just add an additional second or something onto its wait for XMLHttpRequest, which would assume that any app-specific logic would be done by then. Maybe this could even be configurable (if the user wants to make it wait longer than the default "post-XMLHttpRequest fudge factor" time that Geb sets up).