Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
69bf9a4
feat: add Google Antigravity CLI (agy) hook integration (resolves #1975)
thelok1s May 25, 2026
3087260
fix: replace floor_char_boundary with is_char_boundary loop (Homebrew…
thelok1s May 24, 2026
4faf02f
fix(antigravity): correct agy CLI hook config location and payload fo…
thelok1s May 24, 2026
b76dd43
fix(antigravity): write absolute rtk path into agy settings.json
thelok1s May 24, 2026
5c0964a
fix(gemini): handle agy rich payload format in rtk hook gemini
thelok1s May 24, 2026
70cde6e
fix(antigravity): use hooks.json and correct PreToolHookResult overwr…
thelok1s May 25, 2026
eb73c4a
fix(antigravity): always output {} for non-shell tools to prevent den…
thelok1s May 25, 2026
f0cb279
fix(antigravity): set allowTool:true in all hook responses
thelok1s May 25, 2026
9cdcb68
fix(antigravity): overwrite implies allow; allowTool only for passthr…
thelok1s May 25, 2026
407776b
fix(antigravity): grant command(rtk) permission during rtk init
thelok1s May 25, 2026
4078ac2
fix(agy): switch from overwrite to deny-with-reason for agy hook
thelok1s May 25, 2026
26a5693
fix(agy): reference GEMINI.md instead of CLAUDE.md in deny reason
thelok1s May 25, 2026
9184533
chore: remove duplicate test and fix fmt from cherry-pick resolution
thelok1s May 25, 2026
adab348
fix(agy): switch back to overwrite for transparent rewriting
thelok1s May 25, 2026
94a4b6d
fix(agy): add allowTool:true alongside overwrite to prevent denial
thelok1s May 25, 2026
2db2723
fix(agy): revert to denyReason — overwrite silently ignored by agy
thelok1s May 26, 2026
5b90914
fix(agy): address Copilot review — hardening, tests, and docs
thelok1s May 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,11 @@ rtk init -g # Claude Code / Copilot (default)
rtk init -g --gemini # Gemini CLI
rtk init -g --codex # Codex (OpenAI)
rtk init -g --agent cursor # Cursor
rtk init -g --agent agy # Google Antigravity CLI (agy)
rtk init --agent windsurf # Windsurf
rtk init --agent cline # Cline / Roo Code
rtk init --agent kilocode # Kilo Code
rtk init --agent antigravity # Google Antigravity
rtk init --agent antigravity # Google Antigravity IDE (rules-based)
rtk init --agent hermes # Hermes

# 2. Restart your AI tool, then test
Expand Down Expand Up @@ -351,7 +352,7 @@ rtk git status

## Supported AI Tools

RTK supports 13 AI coding tools. Each integration rewrites shell commands to `rtk` equivalents for 60-90% token savings where the agent supports command interception.
RTK supports 14 AI coding tools. Each integration rewrites shell commands to `rtk` equivalents for 60-90% token savings where the agent supports command interception.

| Tool | Install | Method |
|------|---------|--------|
Expand All @@ -360,6 +361,7 @@ RTK supports 13 AI coding tools. Each integration rewrites shell commands to `rt
| **GitHub Copilot CLI** | `rtk init -g --copilot` | PreToolUse deny-with-suggestion (CLI limitation) |
| **Cursor** | `rtk init -g --agent cursor` | preToolUse hook (hooks.json) |
| **Gemini CLI** | `rtk init -g --gemini` | BeforeTool hook |
| **Google Antigravity CLI (`agy`)** | `rtk init -g --agent agy` | PreToolUse hook — deny-with-reason (global) |
| **Codex** | `rtk init -g --codex` | AGENTS.md + RTK.md instructions |
| **Windsurf** | `rtk init --agent windsurf` | .windsurfrules (project-scoped) |
| **Cline / Roo Code** | `rtk init --agent cline` | .clinerules (project-scoped) |
Expand All @@ -368,7 +370,7 @@ RTK supports 13 AI coding tools. Each integration rewrites shell commands to `rt
| **Hermes** | `rtk init --agent hermes` | Python plugin adapter (terminal command mutation via `rtk rewrite`) |
| **Mistral Vibe** | Planned ([#800](https://github.com/rtk-ai/rtk/issues/800)) | Blocked on upstream |
| **Kilo Code** | `rtk init --agent kilocode` | .kilocode/rules/rtk-rules.md (project-scoped) |
| **Google Antigravity** | `rtk init --agent antigravity` | .agents/rules/antigravity-rtk-rules.md (project-scoped) |
| **Google Antigravity IDE** | `rtk init --agent antigravity` | .agents/rules/antigravity-rtk-rules.md (project-scoped) |

For per-agent setup details, override controls, and graceful degradation, see the [Supported Agents guide](https://www.rtk-ai.app/guide/getting-started/supported-agents). The Hermes plugin source and tests live in `hooks/hermes/`; installed Hermes runtime files still live under `~/.hermes/plugins/rtk-rewrite/`.

Expand Down
85 changes: 81 additions & 4 deletions hooks/antigravity/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,85 @@

> Part of [`hooks/`](../README.md) — see also [`src/hooks/`](../../src/hooks/README.md) for installation code

## Specifics
## Supported Modes

- Prompt-level guidance only (no programmatic hook) -- relies on Antigravity reading custom instructions
- `rules.md` contains the instruction to prefix all shell commands with `rtk`, usage examples, and meta commands
- Installed to `.agents/rules/antigravity-rtk-rules.md` (project-local) by `rtk init --agent antigravity`
RTK supports two separate Google Antigravity integrations:

### 1. Antigravity CLI (`agy`) — Programmatic Hook

The `agy` CLI (successor to Gemini CLI) supports a JSON hook protocol. RTK registers as a `PreToolUse` hook that rewrites shell commands before execution.

**Install (global only):**
```bash
rtk init -g --agent agy
```

agy CLI hook support is **global-only** — there is no project-local install. The hook runner is registered system-wide so it intercepts all agy sessions.

**Files written:**
- `~/.gemini/config/hooks.json` — registers the `PreToolUse` hook
- `~/.gemini/antigravity-cli/settings.json` — grants `command(rtk)` permission

**Hook entry written to `~/.gemini/config/hooks.json`:**
```json
{
"rtk-antigravity": {
"enabled": true,
"PreToolUse": [
{
"toolNameMatcher": "^(run_command|Bash|bash)$",
"hooks": [{"type": "command", "command": "/path/to/rtk hook antigravity"}]
}
]
}
}
```

**Hook protocol:**

agy sends a JSON payload to stdin; the hook replies to stdout.

Input (`run_command` tool):
```json
{"toolCall": {"name": "run_command", "args": {"CommandLine": "git status"}}}
```

Output — deny with replacement name (model retries with `rtk git status`, auto-approved via `command(rtk)` allow entry):
```json
{"denyReason": "RTK: use 'rtk git status' instead of 'git status' (60-90% token savings)"}
```

Input (`Bash` tool):
```json
{"toolCall": {"name": "Bash", "args": {"command": "cargo test"}}}
```

Non-shell tools and commands already prefixed with `rtk` receive `{"allowTool": true}` and pass through unchanged.

> **Note:** agy's `overwrite` field in `PreToolHookResult` is silently ignored regardless of `toolPermission` mode. RTK uses the deny-and-retry pattern as a workaround until `overwrite` is implemented by agy.

**Uninstall:**
```bash
rtk init -g --uninstall --agent agy
```

### 2. Antigravity IDE — Prompt-Level Guidance

The Antigravity IDE (formerly "Antigravity") reads project rules files. RTK installs its awareness instructions as a rules file.

**Install (project-local only):**
```bash
rtk init --agent antigravity
```

- Installs `.agents/rules/antigravity-rtk-rules.md` in the project root
- Instructs Antigravity to prefix shell commands with `rtk`
- No programmatic hook — relies on the model following the rules

## Gemini CLI (Legacy)

The Gemini CLI is still supported but is now considered **legacy**. New users should use `agy`.

```bash
rtk init -g --gemini # Gemini CLI (legacy)
```
3 changes: 2 additions & 1 deletion src/cmds/system/json_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ fn compact_json(value: &Value, depth: usize, max_depth: usize) -> String {
Value::Number(n) => format!("{}{}", indent, n),
Value::String(s) => {
if s.len() > 80 {
let end = s.floor_char_boundary(77);
let mut end = 77.min(s.len());
while !s.is_char_boundary(end) { end -= 1; }
format!("{}\"{}...\"", indent, &s[..end])
} else {
format!("{}\"{}\"", indent, s)
Expand Down
4 changes: 2 additions & 2 deletions src/cmds/system/pipe_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,9 @@ fn find_wrapper(input: &str) -> String {
}

pub fn auto_detect_filter(input: &str) -> fn(&str) -> String {
let end = input.len().min(1024);
let mut end = input.len().min(1024);
// Avoid panic: byte 1024 may fall inside a multi-byte UTF-8 char
let end = input.floor_char_boundary(end);
while !input.is_char_boundary(end) { end -= 1; }
let first_1k = &input[..end];

if first_1k.contains("test result:") && first_1k.contains("passed;") {
Expand Down
7 changes: 7 additions & 0 deletions src/hooks/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ pub const OPENCODE_PLUGIN_FILE: &str = "rtk.ts";
pub const CURSOR_DIR: &str = ".cursor";
pub const CODEX_DIR: &str = ".codex";
pub const GEMINI_DIR: &str = ".gemini";

#[allow(dead_code)]
pub const ANTIGRAVITY_DIR: &str = ".agents";

/// Config subdirectory for the Antigravity CLI (agy) under ~/.gemini/
pub const AGY_CLI_SUBDIR: &str = "antigravity-cli";

pub const HERMES_DIR: &str = ".hermes";
pub const HERMES_PLUGINS_SUBDIR: &str = "plugins";
pub const HERMES_PLUGIN_NAME: &str = "rtk-rewrite";
Expand Down
Loading