* feat: add antigravity_cli integration harness
Register the `antigravity_cli` target, resolve its configuration
directory to `~/.gemini/antigravity-cli/`, wire target actions,
and add lifecycle hook scripts for Unix and Windows.
* feat: support session resume for antigravity-cli
* fix: correct antigravity-cli hook config path, shape, and agent label
Antigravity CLI reads global customizations from ~/.gemini/config, keys
hooks.json by hook name, and only accepts the matcher/hooks wrapper for
the tool events. The previous install wrote event arrays at the top level
of ~/.gemini/antigravity-cli/hooks.json, which agy never reads and would
reject anyway, so no Herdr hook ever ran.
Session reports were dropped for a third reason: the hooks reported the
agent as antigravity-cli, but the server normalizes that to the canonical
label agy before matching, so is_official_agent_source never matched and
agy --conversation resume was unreachable.
- Resolve the config dir to ~/.gemini/config
- Nest Herdr entries under a Herdr-owned "herdr" block that install
rewrites and uninstall removes, leaving other named hooks untouched
- Emit grouped entries for PreToolUse/PostToolUse and flat handler lists
for PreInvocation/PostInvocation/Stop
- Report the canonical agy label from both hook assets and match it in
agent_resume
- Compile-gate the hook asset constants and stop shadowing $args in the
PowerShell hook
- Document the real directory, that it must already exist, and the
named-block behavior
refs #1011
refs #1571
* fix: make antigravity-cli integration session-only
antigravity cli cannot express lifecycle safely: there is no blocked
event, postinvocation is skipped on interruption, and stop fires at the
end of a turn rather than on process exit, which left stale state and
released authority at the wrong time.
report only the conversation on preinvocation and let screen detection
own agent state. resume via `agy --conversation <id>` is unchanged.
* fix: update antigravity session after conversation switch
---------
Co-authored-by: Can Celik <ogulcancelik@gmail.com>
herdr tab close on a workspace's only tab returned tab_close_failed,
while the TUI close-tab action on the same tab closes the tab and
cascades to closing the workspace. Cascade in the API too, emitting
tab.closed then workspace.closed. When the cascade would close a whole
worktree group, return confirmation_required instead, matching
pane.close and the TUI prompt.
refs #1760
* feat: switch IME to ASCII in prefix mode on Windows
Extend switch_ascii_input_source_in_prefix to Windows: detect IME state
via WM_IME_CONTROL and toggle to ASCII with SendInput for the Korean IME.
Other IME languages are detected and left unchanged.
refs #1802
* docs: clarify Windows (Korean IME) support for prefix ASCII switching
Follow-up to the Windows prefix ASCII switch, which extended
switch_ascii_input_source_in_prefix to Windows but left the surrounding
text describing macOS only.
- Settings row label: "(macOS)" -> "(macOS/Windows)", plus its test.
- Generalize the Windows behavior wording to "switches the IME to
English (ASCII) input" in the config-reference.json entry and the
model.rs doc comment, and state that Windows support is currently
limited to the Korean IME.
- Add a :::caution aside noting the Korean-IME-only limitation to the
en/ja/zh preview docs, keeping the three translations in sync.
refs #1802
* fix: warn when prefix IME toggle injection is incomplete
SendInput can queue fewer events than requested (for example when blocked
by UIPI), which would otherwise leave the IME silently stuck in ASCII or
native mode. Log a warning with the sent and expected counts so the failure
is diagnosable.
refs #1802
* fix: guard prefix IME restore and correct open-status naming
Address maintainer review on the Windows prefix ASCII switch:
- Restore only when safe: store the foreground window at switch time and,
before toggling back, require that the same window is still focused and
the IME is still in English. This stops restore from toggling another
application or overriding a manual return to Hangul during prefix mode.
- Report injection success from send_vk_tap and only arm restoration when
the initial toggle landed; on a partial injection retry the dropped
key-up so a key is not left logically held down. The injection policy is
split into send_vk_tap_with(inject) so the success, partial, and failure
branches are unit-tested without the real SendInput.
- Correct the WM_IME_CONTROL sub-command naming: 0x0005 is IMC_GETOPENSTATUS
(IME open state), not IMC_GETCONVERSIONMODE. Behavior is unchanged; the
constant, comments, and tests now describe the open-status read.
refs #1802
* fix: bound IME open-status read with a timeout
The prefix IME switch reads IMC_GETOPENSTATUS via WM_IME_CONTROL, which
crosses into the terminal-emulator process. A plain SendMessageW would block
herdr's client thread until that process responds, indefinitely if it hangs.
Read through SendMessageTimeoutW with SMTO_ABORTIFHUNG and a short timeout
instead; on timeout the switch is skipped and restore does nothing, so a hung
host process can no longer freeze prefix-mode entry or exit.
refs #1802
* fix: preserve windows ime restoration after partial injection
refs #1802
---------
Co-authored-by: Ogulcan Celik <ogulcancelik@gmail.com>
* feat: add grok cli integration for native session restore
tl;dr: adds `herdr integration install grok` (session-identity tier: a
SessionStart hook reports the grok session id for native restore; state
stays screen-detected via the bundled manifest).
Grok merges every ~/.grok/hooks/*.json, so install writes a
self-contained hooks/herdr.json registering a SessionStart hook next to
hooks/herdr-agent-state.sh, and never touches other hook files. The hook
prefers $GROK_SESSION_ID (injected into every grok hook process) and
reports through the socket API; herdr:grok is a reserved-native-state
source so screen detection stays authoritative. Restore uses
`grok --resume <id>`. Additive JSON API change; no protocol bump; the
schema artifact is regenerated.
refs #1800
* fix: honor GROK_HOME and validate grok hook config in status
Review follow-ups: grok_dir now resolves GROK_CONFIG_DIR (herdr test
seam) before GROK_HOME (the grok CLI's own config-home override) before
~/.grok, so hook installs land where grok actually looks. Integration
status now also validates the herdr-owned hooks/herdr.json next to the
hook script — missing, corrupt, or no-longer-referencing configs report
the install as outdated instead of masking a hook grok never invokes.
refs #1800
* fix: validate the exact grok session hook command in status
The config validator matched on a filename substring, so a SessionStart
command like `echo herdr-agent-state.sh`, or one invoking the script
without the `session` action, still reported the integration as current
while grok never delivered a session id. Status now compares against the
exact command the installer writes, via a shared builder, and the
degradation tests cover both nonfunctional shapes.
refs #1800
* fix: require a command-type grok session hook in status validation
A config entry carrying the exact generated command under a non-command
hook type (e.g. "http") is never executed by grok, so it must not report
the integration as current. The validator now also requires
type = "command", with a degradation test for the mismatched-type shape.
refs #1800
* fix: validate the complete grok hook config
refs #1800
---------
Co-authored-by: Ogulcan Celik <ogulcancelik@gmail.com>