Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
61 changes: 61 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,67 @@ The CLI authenticates via the system keyring, falling back to Google Sign-In if

---

## Customization

### Custom Status Line

By default, the CLI displays a minimal status bar showing only `? for shortcuts` and the current model name. You can replace it with a fully dynamic status line that shows agent state, context window usage, Git branch, active subagents, and more.

**Quick setup** — automatically copy and configure the statusline script:

```bash
bash examples/statusline/setup.sh
```

Or configure it manually in your settings (accessible via `/settings` in the CLI, or by editing the settings file directly):

```json
{
"statusLine": {
"command": "/absolute/path/to/statusline.sh",
"enabled": true
}
}
```

> [!TIP]
> The settings file location varies by platform:
> - **Linux**: `~/.gemini/antigravity-cli/settings.json`
> - **macOS**: `~/Library/Application Support/antigravity-cli/settings.json`
> - **Windows**: `%APPDATA%\antigravity-cli\settings.json`
>
> You can also open settings interactively by typing `/settings` inside the CLI.

The script receives a JSON payload on stdin with the current agent state and outputs formatted ANSI text. See [`examples/statusline/`](examples/statusline/) for the full reference implementation.

### Custom Window Title

Similarly, you can set a dynamic terminal window title that reflects the agent's current state (thinking, tool use, idle) and workspace.

**Quick setup** — automatically copy and configure the title script:

```bash
bash examples/title/setup.sh
```

Or configure it manually in your settings:

```json
{
"title": {
"command": "/absolute/path/to/title.sh",
"enabled": true
}
}
```

See [`examples/title/`](examples/title/) for details.

> [!NOTE]
> Both scripts require [`jq`](https://jqlang.org/) to be installed. Most Linux distributions include it by default; on macOS, install via `brew install jq`.

---

## Terms of Service & Data Use

> [!WARNING]
Expand Down
126 changes: 116 additions & 10 deletions examples/statusline/README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,131 @@
# CLI Statusline Example
# Custom Status Line

This directory contains an example script (`statusline.sh`) that demonstrates how to create a custom, dynamic statusline for the Antigravity CLI.
This directory contains reference implementations for a custom, dynamic status line for the Antigravity CLI across different shell environments:

For more details on how to use and configure the statusline script, please refer to the official public documentation:
[https://antigravity.google/docs/cli-statusline](https://antigravity.google/docs/cli-statusline)
1. **`statusline.sh`** (Bash/Zsh - Linux/macOS)
2. **`statusline.js`** (Node.js - Cross-platform: Windows/Linux/macOS)
3. **`statusline.ps1`** (PowerShell - Windows PowerShell or PowerShell Core `pwsh`)
4. **`statusline.fish`** (Fish shell - Linux/macOS)

## Quick Start

### Option 1: Automatic Setup (Recommended for Bash/Zsh)

Run the included setup script from the root of the repository:

```bash
bash examples/statusline/setup.sh
```

This script will automatically:
1. Copy `statusline.sh` to your platform's global settings directory (so it stays configured even if you move or delete this repository).
2. Configure and enable it in your global `settings.json` file.

### Option 2: Manual configuration

1. Copy the script corresponding to your shell to a directory of your choice.
2. Edit your `settings.json` file to point `statusLine.command` to the absolute path of the script and set `statusLine.enabled` to `true`:

#### Bash/Zsh (Linux/macOS)
```json
{
"statusLine": {
"command": "/absolute/path/to/statusline.sh",
"enabled": true
}
}
```

#### Node.js (Cross-platform)
```json
{
"statusLine": {
"command": "node /absolute/path/to/statusline.js",
"enabled": true
}
}
```

#### PowerShell (Windows / pwsh)
```json
{
"statusLine": {
"command": "powershell.exe -ExecutionPolicy Bypass -File C:\\absolute\\path\\to\\statusline.ps1",
"enabled": true
}
}
```
*For PowerShell Core, use `pwsh.exe` or `pwsh` instead of `powershell.exe`.*

#### Fish Shell
```json
{
"statusLine": {
"command": "/absolute/path/to/statusline.fish",
"enabled": true
}
}
```

**Settings file locations:**

| Platform | Path |
| :--- | :--- |
| Linux | `~/.gemini/antigravity-cli/settings.json` |
| macOS | `~/Library/Application Support/antigravity-cli/settings.json` |
| Windows | `%APPDATA%\antigravity-cli\settings.json` |

> [!IMPORTANT]
> The `command` field must be an **absolute path** to the script. Relative paths and `~` expansion are not supported.

After saving, restart `agy` for changes to take effect.

## How it works

The `statusline.sh` script reads a JSON payload from standard input, containing various state information from the CLI. It then:
1. Extracts multiple fields like `agent_state`, `vcs` info, context usage, and terminal dimensions using `jq`.
2. Computes visual indicators, such as a Unicode progress bar for context window usage.
3. Formats the data with standard ANSI 16-color codes for visual distinction.
4. Dynamically adjusts the layout to be 1 or 2 lines based on the available terminal width.
The CLI pipes a JSON payload into the script's stdin on each state change. The script:

1. Extracts fields like `agent_state`, `vcs` info, `context_window` usage, and `terminal_width`.
2. Computes visual indicators (e.g., a Unicode progress bar for context window usage).
3. Formats the output using standard ANSI 16-color codes.
4. Dynamically adjusts the layout based on the available terminal width (single-line for wide terminals, two-line for narrower ones).

### JSON payload fields

| Field | Type | Description |
| :--- | :--- | :--- |
| `agent_state` | string | Current state: `idle`, `thinking`, `working`, `tool_use` |
| `context_window.used_percentage` | number | Context window utilization (0–100) |
| `vcs.branch` | string | Current Git branch name |
| `vcs.dirty` | boolean | Whether the working tree has uncommitted changes |
| `sandbox.enabled` | boolean | Whether sandbox mode is active |
| `artifact_count` | number | Number of artifacts in the current session |
| `subagents` | array | List of active subagents |
| `task_count` | number | Number of background tasks |
| `model.display_name` | string | Human-readable model name |
| `terminal_width` | number | Current terminal width in columns |

### Prerequisites

- **Bash (`statusline.sh`) & Fish (`statusline.fish`)**: Require [`jq`](https://jqlang.org/) to be installed and available in `$PATH`.
- **Node.js (`statusline.js`) & PowerShell (`statusline.ps1`)**: Have **zero external dependencies** and work out-of-the-box.

## Examples

### Default Statusline
### Default Status Line
![Default Statusline](images/statusline-default.png)

### Review Mode
![Review Mode Statusline](images/statusline-review.png)

### Tool Execution
![Tool Execution Statusline](images/statusline-tool.png)

## Writing your own

You can use any of the provided scripts as a starting point. The only contract is:

1. Read JSON from stdin.
2. Write one or more lines of ANSI-formatted text to stdout.
3. Exit with code 0.

For the official documentation, see [antigravity.google/docs/cli-statusline](https://antigravity.google/docs/cli-statusline).
98 changes: 98 additions & 0 deletions examples/statusline/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/bin/bash
# setup.sh - Installs and enables the custom statusline for Antigravity CLI

set -euo pipefail

# 1. Determine the settings directory
OS="$(uname -s)"
case "${OS}" in
Darwin*)
CONFIG_DIR="$HOME/Library/Application Support/antigravity-cli"
;;
Linux*)
CONFIG_DIR="$HOME/.gemini/antigravity-cli"
;;
CYGWIN*|MINGW*|MSYS*)
# Windows environments (Git Bash, MSYS)
if [ -n "${APPDATA:-}" ]; then
CONFIG_DIR="${APPDATA}/antigravity-cli"
else
CONFIG_DIR="$HOME/AppData/Roaming/antigravity-cli"
fi
;;
*)
# Default fallback to Linux path
CONFIG_DIR="$HOME/.gemini/antigravity-cli"
;;
esac

# Convert config dir to absolute path if needed
mkdir -p "$CONFIG_DIR"
CONFIG_DIR="$(cd "$CONFIG_DIR" && pwd)"

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SOURCE_SCRIPT="$SCRIPT_DIR/statusline.sh"
TARGET_SCRIPT="$CONFIG_DIR/statusline.sh"

echo "Installing statusline script to: $TARGET_SCRIPT"
cp "$SOURCE_SCRIPT" "$TARGET_SCRIPT"
chmod +x "$TARGET_SCRIPT"

SETTINGS_FILE="$CONFIG_DIR/settings.json"
echo "Configuring settings file at: $SETTINGS_FILE"

# Make sure settings.json exists
if [ ! -f "$SETTINGS_FILE" ]; then
echo "{}" > "$SETTINGS_FILE"
fi

# Update settings.json using python if available, otherwise fallback to jq
if command -v python3 >/dev/null 2>&1; then
python3 -c '
import json, sys
file_path, script_path = sys.argv[1], sys.argv[2]
try:
with open(file_path, "r") as f:
data = json.load(f)
except Exception:
data = {}
if "statusLine" not in data or not isinstance(data["statusLine"], dict):
data["statusLine"] = {}
data["statusLine"]["command"] = script_path
data["statusLine"]["enabled"] = True
with open(file_path, "w") as f:
json.dump(data, f, indent=2)
' "$SETTINGS_FILE" "$TARGET_SCRIPT"
elif command -v python >/dev/null 2>&1; then
python -c '
import json, sys
file_path, script_path = sys.argv[1], sys.argv[2]
try:
with open(file_path, "r") as f:
data = json.load(f)
except Exception:
data = {}
if "statusLine" not in data or not isinstance(data["statusLine"], dict):
data["statusLine"] = {}
data["statusLine"]["command"] = script_path
data["statusLine"]["enabled"] = True
with open(file_path, "w") as f:
json.dump(data, f, indent=2)
' "$SETTINGS_FILE" "$TARGET_SCRIPT"
elif command -v jq >/dev/null 2>&1; then
TEMP_FILE=$(mktemp)
jq --arg cmd "$TARGET_SCRIPT" '.statusLine = ((.statusLine // {}) + {command: $cmd, enabled: true})' "$SETTINGS_FILE" > "$TEMP_FILE"
mv "$TEMP_FILE" "$SETTINGS_FILE"
else
echo "Error: Neither python3, python, nor jq is installed. Please manually add the following to your $SETTINGS_FILE:"
echo "{"
echo " \"statusLine\": {"
echo " \"command\": \"$TARGET_SCRIPT\","
echo " \"enabled\": true"
echo " }"
echo "}"
exit 1
fi

echo "Status line successfully installed and enabled!"
echo "Please restart Antigravity CLI (agy) to see the changes."
Loading