# Gemini/Antigravity CLI Extension Manifest Structure in Ponytail

> Understand the Gemini/Antigravity CLI extension manifest structure in Ponytail. Learn the four required JSON fields for loading extensions and rule sets.

- Repository: [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail)
- Tags: api-reference
- Published: 2026-09-11

---

**The Gemini/Antigravity CLI extension manifest is a minimal JSON configuration file located at the repository root that defines four required fields—`name`, `version`, `description`, and `contextFileName`—to instruct the CLI how to load the Ponytail extension and locate its always-on rule set.**

The [`gemini-extension.json`](https://github.com/DietrichGebert/ponytail/blob/main/gemini-extension.json) file serves as the entry point for the Gemini (now Antigravity) CLI to install and configure the Ponytail extension from the DietrichGebert/ponytail repository. This deliberately minimal schema ensures the CLI can quickly identify the extension, validate its version against other plugin manifests, and load the core instruction set without unnecessary complexity. Understanding the **Gemini/Antigravity CLI extension manifest structure** is essential for developers maintaining multi-platform agent configurations or extending the Ponytail framework.


## The Four Required Fields

The manifest schema is intentionally restricted to only the fields necessary for CLI operation. Each field serves a specific purpose in the extension lifecycle.

### name

The `name` field accepts a string that serves as the canonical identifier for the extension. For the Ponytail project, this value is always `"ponytail"`. This identifier tells the Gemini/Antigravity binary which extension to install and must remain consistent across all deployment targets.

### version

The `version` field requires a fully-pinned semantic version string (e.g., `"4.9.0"`). This value is strictly validated against the other plugin manifests located at [`.claude-plugin/plugin.json`](https://github.com/DietrichGebert/ponytail/blob/main/.claude-plugin/plugin.json), [`.codex-plugin/plugin.json`](https://github.com/DietrichGebert/ponytail/blob/main/.codex-plugin/plugin.json), and [`.github/plugin/plugin.json`](https://github.com/DietrichGebert/ponytail/blob/main/.github/plugin/plugin.json) to prevent supply-chain mismatches. According to the test suite in [`tests/gemini-extension.test.js`](https://github.com/DietrichGebert/ponytail/blob/main/tests/gemini-extension.test.js) (lines 52-66), the version must follow exact semver formatting without pre-release or build metadata.

### description

The `description` field provides a human-readable explanation of the extension's operational philosophy. In Ponytail's implementation, this describes the "lazy senior dev mode" approach that prioritizes YAGNI principles and standard library solutions over unnecessary abstractions.

### contextFileName

The `contextFileName` field specifies a relative path string pointing to the file containing the always-on rule set. For Gemini/Antigravity compatibility, this always points to **[`AGENTS.md`](https://github.com/DietrichGebert/ponytail/blob/main/AGENTS.md)**, which holds the core instruction set used by agents that lack skill support. The CLI loads this file on every session to ensure consistent behavior regardless of skill availability.


## How the CLI Discovers Extension Resources

Once the manifest is parsed, the Gemini/Antigravity CLI automatically discovers reusable resources based on conventional directory structures rather than explicit configuration.

### Auto-Discovered Commands and Skills

The CLI scans the repository for:

- **`commands/*.toml`** — Defines slash commands such as `/ponytail` and `/ponytail-review` (configured in [`commands/ponytail.toml`](https://github.com/DietrichGebert/ponytail/blob/main/commands/ponytail.toml) and [`commands/ponytail-review.toml`](https://github.com/DietrichGebert/ponytail/blob/main/commands/ponytail-review.toml))
- **`skills/`** — Loads skill definitions from subdirectories (e.g., [`skills/ponytail/SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail/SKILL.md))

### The Absence of Hooks Configuration

Unlike Claude or Codex manifests, [`gemini-extension.json`](https://github.com/DietrichGebert/ponytail/blob/main/gemini-extension.json) deliberately **does not reference** a [`hooks/hooks.json`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/hooks.json) file. Gemini auto-loads hooks from that path by convention; however, Ponytail's lifecycle hooks use Claude/Codex-specific event names. As verified in [`tests/gemini-extension.test.js`](https://github.com/DietrichGebert/ponytail/blob/main/tests/gemini-extension.test.js) (lines 85-91), these events are incompatible with Gemini's hook system, so they remain isolated in their host-specific manifests to prevent runtime errors.


## Validating the Manifest Programmatically

You can verify the manifest structure and cross-reference its values using standard filesystem operations.

### Installing the Extension

To install Ponytail using the Gemini or Antigravity CLI:

```bash

# Using the Gemini CLI (or Antigravity "agy" binary)

gemini extensions install https://github.com/DietrichGebert/ponytail

```

The CLI reads [`gemini-extension.json`](https://github.com/DietrichGebert/ponytail/blob/main/gemini-extension.json), verifies the pinned version, and automatically discovers the commands, skills, and context files.

### Node.js Validation Example

This script replicates the assertions found in the official test suite:

```javascript
const fs = require('fs');
const path = require('path');

const manifestPath = path.join(__dirname, '..', 'gemini-extension.json');
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));

console.assert(manifest.name === 'ponytail', 'Extension name mismatch');
console.assert(/^\d+\.\d+\.\d+$/.test(manifest.version), 'Version must be pinned semver');
console.assert(manifest.contextFileName === 'AGENTS.md', 'Context file must be AGENTS.md');

```

### Python Rule Access Example

To dynamically locate the always-on rules without hard-coding filenames:

```python
import pathlib, json

manifest = json.loads(pathlib.Path('gemini-extension.json').read_text())
rules = pathlib.Path(manifest['contextFileName']).read_text()
print(rules.splitlines()[:5])   # Preview first five rule lines

```


## Version Synchronization Across Platforms

The manifest enforces strict version parity across all distribution channels. The `version` field in [`gemini-extension.json`](https://github.com/DietrichGebert/ponytail/blob/main/gemini-extension.json) must exactly match the versions declared in:

- [`.claude-plugin/plugin.json`](https://github.com/DietrichGebert/ponytail/blob/main/.claude-plugin/plugin.json)
- [`.codex-plugin/plugin.json`](https://github.com/DietrichGebert/ponytail/blob/main/.codex-plugin/plugin.json)
- [`.github/plugin/plugin.json`](https://github.com/DietrichGebert/ponytail/blob/main/.github/plugin/plugin.json)

As implemented in DietrichGebert/ponytail, the test suite in [`tests/gemini-extension.test.js`](https://github.com/DietrichGebert/ponytail/blob/main/tests/gemini-extension.test.js) validates this synchronization to prevent scenarios where different AI agent platforms might load incompatible iterations of the extension. This cross-manifest validation occurs during the continuous integration pipeline, ensuring that a single source of truth governs all releases.


## Summary

- The **Gemini/Antigravity CLI extension manifest structure** requires exactly four fields in [`gemini-extension.json`](https://github.com/DietrichGebert/ponytail/blob/main/gemini-extension.json): `name`, `version`, `description`, and `contextFileName`.
- The `contextFileName` field must point to **[`AGENTS.md`](https://github.com/DietrichGebert/ponytail/blob/main/AGENTS.md)** to load always-on rules for agents without skill support.
- The manifest implicitly enables resource discovery for `commands/*.toml` and `skills/` directories without explicit configuration.
- Version strings must be pinned semantic versions (e.g., `"4.9.0"`) and synchronized across all plugin manifests in the repository.
- Hook configurations are intentionally excluded because Gemini's auto-discovery mechanism is incompatible with Claude/Codex-specific event names used by Ponytail.


## Frequently Asked Questions

### What filename must the Gemini/Antigravity extension manifest use?

The CLI expects a file named exactly **[`gemini-extension.json`](https://github.com/DietrichGebert/ponytail/blob/main/gemini-extension.json)** located at the repository root. This filename is hard-coded into the Gemini/Antigravity extension discovery mechanism and cannot be customized.

### Why doesn't gemini-extension.json reference hooks/hooks.json?

The manifest omits hooks configuration because Gemini auto-loads [`hooks/hooks.json`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/hooks.json) by convention. However, Ponytail's lifecycle hooks use Claude/Codex-specific event names that Gemini cannot process. Including these hooks would cause runtime errors, so they remain in host-specific manifests while [`gemini-extension.json`](https://github.com/DietrichGebert/ponytail/blob/main/gemini-extension.json) focuses solely on rules and resource discovery.

### How does the CLI locate the always-on rules for Ponytail?

The CLI reads the `contextFileName` field from [`gemini-extension.json`](https://github.com/DietrichGebert/ponytail/blob/main/gemini-extension.json), which always contains the string `"AGENTS.md"`. It then resolves this path relative to the repository root and injects the contents into the agent's context on every session initialization.

### What happens if the version field mismatches other plugin manifests?

Version mismatches trigger assertion failures in [`tests/gemini-extension.test.js`](https://github.com/DietrichGebert/ponytail/blob/main/tests/gemini-extension.test.js) (lines 52-66), causing the build to fail. This prevents the distribution of inconsistent extension states where, for example, the Gemini release might claim version `"4.9.0"` while the Claude plugin claims `"4.8.0"`, ensuring platform parity.