diff --git a/scripts/install.cmd b/scripts/install.cmd index 855d67ca3..ba0e2cf17 100644 --- a/scripts/install.cmd +++ b/scripts/install.cmd @@ -714,6 +714,16 @@ if !ERRORLEVEL! equ 0 ( echo Installed Gemini commands to !GEMINI_COMMANDS_DIR!\ ) + REM Antigravity CLI plugin commands (only when detected) + set "AGY_BASE=" + if exist "%USERPROFILE%\.gemini\config" (set "AGY_BASE=%USERPROFILE%\.gemini\config") else if exist "%USERPROFILE%\.gemini\antigravity-cli" set "AGY_BASE=%USERPROFILE%\.gemini\antigravity-cli" + if defined AGY_BASE if exist "apps\gemini\commands" ( + set "AGY_PLUGIN_COMMANDS_DIR=!AGY_BASE!\plugins\plannotator\commands" + if not exist "!AGY_PLUGIN_COMMANDS_DIR!" mkdir "!AGY_PLUGIN_COMMANDS_DIR!" + xcopy /y /q "apps\gemini\commands\*.toml" "!AGY_PLUGIN_COMMANDS_DIR!\" >nul 2>&1 + echo Installed Antigravity commands to !AGY_PLUGIN_COMMANDS_DIR!\ + ) + REM Kiro -> hand-maintained kiro skills (3) + 2 extras, only when detected. if "!KIRO_AVAILABLE!"=="1" if exist "apps\kiro-cli\skills" ( if not exist "!KIRO_SKILLS_DIR!" mkdir "!KIRO_SKILLS_DIR!" @@ -902,6 +912,39 @@ echo } REM checkout in the git-gated skills/commands block above, not written here. ) +REM --- Antigravity CLI support (only when detected) --- +set "AGY_BASE=" +if exist "%USERPROFILE%\.gemini\config" (set "AGY_BASE=%USERPROFILE%\.gemini\config") else if exist "%USERPROFILE%\.gemini\antigravity-cli" set "AGY_BASE=%USERPROFILE%\.gemini\antigravity-cli" +if defined AGY_BASE ( + set "AGY_PLUGIN_DIR=!AGY_BASE!\plugins\plannotator" + set "AGY_POLICIES_DIR=!AGY_BASE!\policies" + if not exist "!AGY_POLICIES_DIR!" mkdir "!AGY_POLICIES_DIR!" + if not exist "!AGY_PLUGIN_DIR!" mkdir "!AGY_PLUGIN_DIR!" + ( + echo # Plannotator policy for Antigravity CLI + echo # Allows exit_plan_mode without TUI confirmation so the browser UI is the sole gate. + echo [[rule]] + echo toolName = "exit_plan_mode" + echo decision = "allow" + echo priority = 100 + ) > "!AGY_POLICIES_DIR!\plannotator.toml" + >"!AGY_PLUGIN_DIR!\plugin.json" echo {"name":"plannotator"} + >"!AGY_PLUGIN_DIR!\hooks.json" echo {"hooks":{"BeforeTool":[{"matcher":"exit_plan_mode","hooks":[{"type":"command","command":"plannotator","timeout":345600}]}]}} + echo Installed Antigravity plugin to !AGY_PLUGIN_DIR! +) + +echo. +echo ========================================== +echo ANTIGRAVITY CLI USERS +echo ========================================== +echo. +echo Plannotator is installed as an Antigravity plugin. +echo Restart the CLI, and the following commands will be ready: +echo. +echo /plannotator-review +echo /plannotator-annotate +echo. +echo Plans will automatically open in your browser during plan reviews. echo. echo ========================================== echo KIRO CLI USERS diff --git a/scripts/install.ps1 b/scripts/install.ps1 index 7a32df189..93b2b1f9b 100644 --- a/scripts/install.ps1 +++ b/scripts/install.ps1 @@ -800,6 +800,18 @@ try { Write-Host "Installed Gemini slash commands to $geminiCommandsDir\" } } + + # Antigravity CLI plugin commands (only when detected) + $agyBase = if (Test-Path "$env:USERPROFILE\.gemini\config") { "$env:USERPROFILE\.gemini\config" } elseif (Test-Path "$env:USERPROFILE\.gemini\antigravity-cli") { "$env:USERPROFILE\.gemini\antigravity-cli" } else { $null } + if ($agyBase -and (Test-Path "apps\gemini\commands")) { + $agyPluginCommandsDir = "$agyBase\plugins\plannotator\commands" + $geminiCmds = Get-ChildItem "apps\gemini\commands\*.toml" -ErrorAction SilentlyContinue + if ($geminiCmds) { + New-Item -ItemType Directory -Force -Path $agyPluginCommandsDir | Out-Null + Copy-Item -Force "apps\gemini\commands\*.toml" $agyPluginCommandsDir + Write-Host "Installed Antigravity slash commands to $agyPluginCommandsDir\" + } + } } finally { Pop-Location } @@ -967,6 +979,24 @@ fs.writeFileSync('$($geminiSettings.Replace('\','/'))', JSON.stringify(settings, # (apps/gemini/commands) in the git-gated skills/commands install above. } +# --- Antigravity CLI support (only when detected) --- +$agyBase = if (Test-Path "$env:USERPROFILE\.gemini\config") { "$env:USERPROFILE\.gemini\config" } elseif (Test-Path "$env:USERPROFILE\.gemini\antigravity-cli") { "$env:USERPROFILE\.gemini\antigravity-cli" } else { $null } +if ($agyBase) { + $agyPluginDir = "$agyBase\plugins\plannotator" + New-Item -ItemType Directory -Force -Path "$agyBase\policies", $agyPluginDir | Out-Null + @' +# Plannotator policy for Antigravity CLI +# Allows exit_plan_mode without TUI confirmation so the browser UI is the sole gate. +[[rule]] +toolName = "exit_plan_mode" +decision = "allow" +priority = 100 +'@ | Set-Content -Path "$agyBase\policies\plannotator.toml" + '{"name":"plannotator"}' | Set-Content -Path "$agyPluginDir\plugin.json" + '{"hooks":{"BeforeTool":[{"matcher":"exit_plan_mode","hooks":[{"type":"command","command":"plannotator","timeout":345600}]}]}}' | Set-Content -Path "$agyPluginDir\hooks.json" + Write-Host "Installed Antigravity plugin to $agyPluginDir" +} + Write-Host "" Write-Host "==========================================" Write-Host " OPENCODE USERS" @@ -999,6 +1029,18 @@ if ($kiroAvailable) { } Write-Host "" Write-Host "==========================================" +Write-Host " ANTIGRAVITY CLI USERS" +Write-Host "==========================================" +Write-Host "" +Write-Host "Plannotator is installed as an Antigravity plugin." +Write-Host "Restart the CLI, and the following commands will be ready:" +Write-Host "" +Write-Host " /plannotator-review" +Write-Host " /plannotator-annotate" +Write-Host "" +Write-Host "Plans will automatically open in your browser during plan reviews." +Write-Host "" +Write-Host "==========================================" Write-Host " CLAUDE CODE USERS: YOU ARE ALL SET!" Write-Host "==========================================" Write-Host "" diff --git a/scripts/install.sh b/scripts/install.sh index f3aaa97a9..4e55f164f 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -1131,6 +1131,13 @@ checkout_failed=0 echo "Installed Gemini commands to ${GEMINI_COMMANDS_DIR}/" fi + # Antigravity CLI plugin commands (only when detected) + AGY_BASE=""; [ -d "$HOME/.gemini/config" ] && AGY_BASE="$HOME/.gemini/config" || { [ -d "$HOME/.gemini/antigravity-cli" ] && AGY_BASE="$HOME/.gemini/antigravity-cli"; } + if [ -n "$AGY_BASE" ] && [ -d "apps/gemini/commands" ] && [ -n "$(ls -A apps/gemini/commands 2>/dev/null)" ]; then + copy_commands_if_present apps/gemini/commands "$AGY_BASE/plugins/plannotator/commands" + echo "Installed Antigravity commands to ${AGY_BASE}/plugins/plannotator/commands/" + fi + if [ "$kiro_available" -eq 1 ] && [ -d "apps/kiro-cli/skills" ] && [ -n "$(ls -A apps/kiro-cli/skills 2>/dev/null)" ]; then mkdir -p "$KIRO_SKILLS_DIR" # Kiro-specific skills (origin baked in) come from apps/kiro-cli/skills. @@ -1297,6 +1304,28 @@ GEMINI_SETTINGS_EOF # the skills/commands install block above (apps/gemini/commands). fi +# --- Antigravity CLI support (only when detected) --- +AGY_BASE=""; [ -d "$HOME/.gemini/config" ] && AGY_BASE="$HOME/.gemini/config" || { [ -d "$HOME/.gemini/antigravity-cli" ] && AGY_BASE="$HOME/.gemini/antigravity-cli"; } +if [ -n "$AGY_BASE" ]; then + AGY_PLUGIN_DIR="$AGY_BASE/plugins/plannotator" + mkdir -p "$AGY_BASE/policies" "$AGY_PLUGIN_DIR" + cat > "$AGY_BASE/policies/plannotator.toml" << 'AGY_POLICY_EOF' +# Plannotator policy for Antigravity CLI +# Allows exit_plan_mode without TUI confirmation so the browser UI is the sole gate. +[[rule]] +toolName = "exit_plan_mode" +decision = "allow" +priority = 100 +AGY_POLICY_EOF + cat > "$AGY_PLUGIN_DIR/plugin.json" << 'AGY_PLUGIN_EOF' +{"name":"plannotator"} +AGY_PLUGIN_EOF + cat > "$AGY_PLUGIN_DIR/hooks.json" << 'AGY_HOOKS_EOF' +{"hooks":{"BeforeTool":[{"matcher":"exit_plan_mode","hooks":[{"type":"command","command":"plannotator","timeout":345600}]}]}} +AGY_HOOKS_EOF + echo "Installed Antigravity plugin to ${AGY_PLUGIN_DIR}" +fi + echo "" echo "==========================================" echo " OPENCODE USERS" @@ -1330,6 +1359,18 @@ echo "If settings.json was not auto-configured, see:" echo " ~/.gemini/settings.json (add BeforeTool hook)" echo "" echo "==========================================" +echo " ANTIGRAVITY CLI USERS" +echo "==========================================" +echo "" +echo "Plannotator is installed as an Antigravity plugin." +echo "Restart the CLI, and the following commands will be ready:" +echo "" +echo " /plannotator-review" +echo " /plannotator-annotate" +echo "" +echo "Plans will automatically open in your browser during plan reviews." +echo "" +echo "==========================================" echo " CODEX USERS" echo "==========================================" echo "" diff --git a/scripts/install.test.ts b/scripts/install.test.ts index 2d95376d4..063d2ba69 100644 --- a/scripts/install.test.ts +++ b/scripts/install.test.ts @@ -284,6 +284,12 @@ describe("install.sh", () => { expect(script).toContain('GEMINI_POLICY_EOF'); expect(script).toContain('GEMINI_SETTINGS_EOF'); }); + + test("installs Antigravity plugin configuration", () => { + expect(script).toContain("AGY_BASE="); + expect(script).toContain("plannotator.toml"); + expect(script).toContain("hooks.json"); + }); }); describe("install.ps1", () => { @@ -424,6 +430,12 @@ describe("install.ps1", () => { expect(skillsInstallIndex).toBeGreaterThan(0); expect(piUpdateCallIndex).toBeGreaterThan(skillsInstallIndex); }); + + test("installs Antigravity plugin configuration on Windows", () => { + expect(script).toContain("$agyBase"); + expect(script).toContain("plannotator.toml"); + expect(script).toContain("hooks.json"); + }); }); describe("install.cmd", () => { @@ -580,6 +592,12 @@ describe("install.cmd", () => { // Enforcement: hard-fail when opted in but gh missing expect(script).toContain("gh CLI was not found"); }); + + test("installs Antigravity plugin configuration in cmd", () => { + expect(script).toContain("AGY_BASE"); + expect(script).toContain("plannotator.toml"); + expect(script).toContain("hooks.json"); + }); }); describe("Core Plannotator skills", () => {