Skip to content

fix(team): prevent Antigravity CLI coordination hangs - #1032

Open
harrytuckerr wants to merge 25 commits into
iOfficeAI:mainfrom
harrytuckerr:fix/agy-team-integration
Open

harrytuckerr wants to merge 25 commits into
iOfficeAI:mainfrom
harrytuckerr:fix/agy-team-integration

Conversation

@harrytuckerr

@harrytuckerr harrytuckerr commented Oct 19, 2026 •

Copy link
Copy Markdown

Team CLI commands could wait indefinitely for stdin EOF, preventing an Antigravity teammate from reporting its result. This change bounds input reads, documents foreground helper calls, and translates team permission selections per backend.

Changes:

  • Share bounded JSON input across team, session, conversation, skills, config and diagnose. Explicit JSON takes precedence over file input and implicit stdin. Preserve explicit {} config updates; normalize UTF-8/UTF-16 BOMs; report only safe input metadata. Source: crates/aionui-app/src/commands/json_input.rs and the command handlers.
  • Add POSIX and PowerShell foreground examples matching the Team descriptor, and skip login-shell PATH probing for short-lived helpers. Source: crates/aionui-team-prompts/src/team_tool_usage.rs, crates/aionui-app/src/commands/team_capabilities.rs, and crates/aionui-app/src/main.rs.
  • Record terminal status, terminal-frame presence, exit observation and classification without response text. Carry normalized error codes into delivery-exhaustion notices. Source: crates/aionui-session/src/backend/antigravity/conn.rs and crates/aionui-team/src/session.rs.
  • Translate full auto to each member backend's native mode, skip unsupported raw modes, and guard agy native mode arguments. Source: crates/aionui-team/src/service.rs and crates/aionui-session/src/backend/antigravity/argv.rs.
  • Set the approval-handler timeout above the callback wait. Prepare a canonical Windows command wrapper, restore it before publishing the hook configuration, and remove both together. Source: crates/aionui-ai-agent/src/antigravity_hook.rs and crates/aionui-session/src/backend/antigravity/conn.rs.
  • Record verified agy version 1.4.2 in crates/aionui-session/src/backend/cli_version.rs. The prompt transport remains unchanged.

Validation:

  • Pass: real macOS arm64 Team task with a Codex lead and agy 1.4.2 teammate. The exact requested file contents reached the lead's mailbox; initial and resumed teammate turns succeeded with no remaining RUNNING background commands.
  • Pass: 12 CLI process checks covering held-open stdin, terminal stdin, precedence, empty input, BOM/UTF-16 decoding, timeout and safe error metadata. Warm held-open stdin returned in about 1.36 seconds. Fresh debug-executable startup can exceed the input wait; no blanket cold-start latency claim is made.
  • Pass: final just push gate on bfc8235c: migration immutability, workspace lint/fixes, formatting and 9,439 tests passed (52 skipped).
  • Pass on unchanged AionUi baseline: typecheck, lint, format, i18n validation and 4,980 tests (5 skipped).

Limits:

  • Windows execution and PowerShell examples are Not exercised. BOM handling is defensive; the original Windows input bytes were not captured.
  • The original later-turn gateway error with a normal visible reply was Not reproduced. No speculative status-to-success mapping or conversation reset is included.
  • Windows large-prompt argv support is outside this PR. Existing delivery retries remain bounded at three; acknowledging partially observed work needs a separate domain decision.
  • Hooks remain workspace-shared. Per-conversation hooks and an agy MCP plugin are outside scope.
  • AionUi's backend pin can move after an AionCore release exists.

Protocol sources were inspected locally. Raw captures, logs, account details and machine-specific evidence paths are intentionally omitted from this public PR.

Related: AionUi #4322, #4317, #4294, #4095.

WS-5: write "timeout": CALLBACK_TIMEOUT + 20s into the hooks.json handler,
from one shared constant in aionui-api-types, so agy's 30s handler default
(hooks.md:132-133) no longer kills the hook while the permission card is still
open; the hook now always answers for itself with a fail-closed denial. The
callback wait itself is unchanged at 240s.

WS-6: on Windows install .agents/aionui-permission-hook.cmd and point
hooks.json at its bare name (agy sets the handler cwd to the hooks.json
directory, hooks.md:129-133); the wrapper carries the dunce-canonicalized
binary path, and a canonicalization failure is propagated rather than silently
replaced by the original path, which may be the \\?\ verbatim form the
wrapper exists to keep out (#4095, reporter-observed). remove_hooks_json
removes the wrapper with hooks.json. The Unix command form is unchanged.

Sources: hooks.md (installed agy-customizations docs); argv.rs --print-timeout
1h; ~/aion/protocols/samples/agy/1.4.2/root-probe-help.txt for agy's own
default 0. Windows runtime not exercised (no tester); wrapper format is pinned
by a cross-platform test.
write_hooks_json canonicalizes the binary before embedding it in the Windows
wrapper (ed69d303), so tests handing it placeholder /opt paths would fail on
Windows by design. Create a real temp stub file instead.
Record the result status token, outcome class, failed-step count, whether a
result frame arrived, and the process exit. Do not change how a missing or
present result is classified as success or failure.
Warn with status, outcome, and wire_error when an error TurnResult is
processed, instead of waiting for stdout EOF. After EOF, log the
immediate watcher state and one 200ms follow-up without inventing an
exit code. Absent results now log result_status=absent and exit_state.
Wire classification is wire_success or wire_error. The append_delta
rustdoc stays on append_delta. Synthesis mapping is unchanged.

Checks not run: ENOSPC.
…store

Move the wrapper file name into AntigravityHookConfig so the session layer can
name it without depending on aionui-ai-agent, and expose prepare_wrapper_body:
None off Windows, Some(contents) on Windows, canonicalization errors propagate
(never a fallback to the original path, which may be the \\?\ verbatim form
#4095 is about).

The antigravity factory prepares that wrapper beside permission_hook_body and
carries it through SessionBuildInputs and SessionConfig. Prepared only — a
full-auto session still installs no gate, and nothing here writes a file.
conn.rs is untouched; the mode-switch sync consumes the field in a follow-up.
needs_runtime=false commands still called enhance_process_path, which
blocks up to 3s on a login shell before stdin. Gate that probe to the
server, doctor, and prepare-managed-resources. Helpers keep the
inherited PATH. No helper command spawns an agent, so none stays on
the enrichment path.

Tests not run: root compiles.
Build helper-vs-runtime cases with Cli::try_parse_from so the test does
not name arg-struct fields that integrated WS-1 adds. Selection behavior
is unchanged.

Tests not run: root compiles.
The mode-switch path rewrote only hooks.json, so on Windows a session that
left full auto restored a hooks.json naming a wrapper that was never written.

sync_permission_hook now manages both files: full auto removes hooks.json and
the wrapper (NotFound ignored on each); leaving full auto writes the prepared
wrapper FIRST and aborts on failure, so hooks.json is never published pointing
at a missing file, and a failed wrapper write is logged as such instead of
claiming the gate was restored.

The wrapper file name moves to aionui-common and is re-exported on
AntigravityHookConfig, because aionui-session deliberately depends only on
aionui-common + aionui-process and could not otherwise name the file.

Tests: Windows lifecycle (both files restore/delete), Unix wrapper-free
restore, and a cross-platform failure test proving a failed wrapper write
leaves hooks.json unpublished. Source for the cmd/handler contract: the
installed agy-customizations/docs/hooks.md, "Hook Handler Fields".
hooks.md documents that agy runs handlers through cmd /c; it does not prove a
quoted absolute path is mangled. Attribute that to the reporter-observed #4317
stderr (a regression of the #4095 verbatim-path fix) instead of the doc.
@harrytuckerr
harrytuckerr marked this pull request as draft October 20, 2026 23:46
@harrytuckerr
harrytuckerr marked this pull request as ready for review October 20, 2026 23:46
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