Skip to content

feat: add Gemini CLI as a host via a published extension branch [DITTO-1798] - #20

Merged
Peyton-Spencer merged 5 commits into
mainfrom
claude/ditto-1798-gemini-extension
Nov 1, 2026
Merged

Peyton-Spencer merged 5 commits into
mainfrom
claude/ditto-1798-gemini-extension

Conversation

@Peyton-Spencer

@Peyton-Spencer Peyton-Spencer commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Gemini CLI is now a target host.

  • New manifest. plugins/ditto/gemini-extension.json declares the Ditto MCP server as httpUrl: https://api.heyditto.ai/mcp. In Gemini that field means streamable HTTP; url would mean SSE.
  • OAuth. Left to Gemini's documented dynamic discovery on the server's 401. The 401 carries WWW-Authenticate: Bearer … resource_metadata=…/.well-known/oauth-protected-resource/mcp.
  • Skills. All 3 load natively from skills/.
  • Validate. gemini extensions validate ./plugins/ditto passes.
  • GitHub install. Uses a published branch, not a root manifest:
    gemini extensions install https://github.com/ditto-assistant/ditto-plugins --ref gemini-extension

Why a published branch and not a root gemini-extension.json

  • Gemini installs only from the repository root. The releasing docs say the manifest must be at "the absolute root of the repository or the release archive". extensions install takes --ref but no path. In 0.66.0, tryParseGithubUrl accepts only owner/repo, cloneFromGit clones the root, and skills load only from <extension>/skills.
  • A root manifest breaks Antigravity (tested). With a root gemini-extension.json, agy plugin install <repo> installs the repository root as a Gemini extension (source: gemini-cli) with 0 skills, where it used to install plugins/ditto.
  • A root skills/ symlink doesn't survive install (tested). Gemini's fs.cp rewrites the relative link to an absolute path into its temporary clone. Once that clone is deleted, 0 skills load.
  • Gemini supports branches as release channels. The releasing docs describe using branches with --ref for release channels. So scripts/publish_extension_ref.py commits the plugins/ditto tree unchanged as the next fast-forward commit of gemini-extension, and does nothing when the tree is unchanged. .github/workflows/gemini-extension.yml runs it on main after verify, unittest and validate. Nothing outside plugins/ditto and that branch changes for other hosts.
  • Other options rejected. GitHub Releases with an archive asset would also work. But it adds a release process, and Kimi's bare GitHub URL installs the latest release, which would pin Kimi to releases instead of main.

Other changes

  • Validator. It adds the Gemini manifest. The manifest may set only name, version, description and mcpServers, and each server only httpUrl with the hosted URL. Gemini's commands/, hooks/, policies/ and agents/ stay rejected as release files. 15 package tests plus 4 publisher tests: 19 OK. validate_package.py: 20 files.
  • Adapter. adapters/ditto-memory.md gains a Gemini CLI line (/mcp, /mcp auth ditto). The generated ditto-memory skill was regenerated.
  • Generator. scripts/shared_skills.py and the lock come from ditto-assistant/ditto-skills#16 (head b406544), which versions gemini-extension.json. verify --source passes.
  • Version. All manifests are 0.3.8. README, CONTRIBUTING and RELEASING document the Gemini install.

Host results

Each CLI ran in its own throwaway HOME, with no host sign-in and no Ditto OAuth. Branch head 1844c7c, after restacking on #19's review fixes and a full re-run.

Host (version) Validator Install source Found Result
Gemini CLI 0.66.0 (current npm latest, run via a scratch npm install) extensions validate ./plugins/ditto passes (on main: "Configuration file not found") GitHub --ref claude/ditto-1798-gemini-extension-ref. This is a test branch I published with the new script from this head. Its head 28dd191 has plugins/ditto at 1844c7c as its root tree (ca88338) 0.3.8, Type git; skills curate-music, ditto-memory, handoff enabled; MCP ditto (http) PASS
Gemini CLI 0.66.0 n/a local plugins/ditto same PASS
Gemini CLI 0.66.0 n/a extensions update ditto after a scratch commit on the test branch "successfully updated: 0.3.8 → 0.3.9" PASS
Antigravity agy 1.4.12 validate --strict passes GitHub /tree/<branch> "Found bulk plugins directory"; 3 skills, 1 MCP, 0.3.8, source: antigravity PASS
Kimi Code 2.4.1 none GitHub /tree/<branch>, plus a local path skills 3, plugin-ditto:ditto needs auth PASS
Claude Code 2.1.314 plugin --strict + marketplace pass GitHub #<branch> 0.3.8; "Needs authentication" PASS
Codex CLI 0.163.0 none GitHub --ref 0.3.8; "Not logged in" PASS
Copilot CLI 1.0.105 none GitHub .git#<branch> 3 skills, 0.3.8; Source: Plugin PASS
Grok 1.0.70 plugin validate passes fresh clone of the pushed branch (no ref option) installed PASS (local clone)
Cursor not run (signed-in account needed) n/a n/a manual

Limitations

  • The gemini-extension branch doesn't exist yet. The workflow creates it on the first main push that touches plugins/ditto, or on a manual workflow_dispatch. Until then the README command fails. The workflow itself hasn't run: I ran the same script locally against GitHub to create claude/ditto-1798-gemini-extension-ref. It needs contents: write for GITHUB_TOKEN; the repo's default workflow permissions are write. Delete the test branch after review.
  • "Needs auth" isn't directly observable in Gemini. gemini mcp list has no auth status, only Connected, Connecting, Blocked, Disabled or Disconnected, so the server shows "Disconnected". The interactive /mcp view needs a Gemini sign-in first, which I didn't do. Indirect evidence: the endpoint returns 401 with the OAuth resource metadata that Gemini's auto-discovery uses. /mcp auth ditto isn't exercised.
  • Install prompts. On a --ref install, Gemini first requests a GitHub release by that tag, gets a 404, and asks to fall back to git clone. The README says to answer yes.
  • Gemini CLI's own status. The geminicli.com reference page now says Gemini CLI was replaced by Antigravity CLI on 2026-06-18, but npm still publishes it (0.66.0 latest, 0.67 nightlies). The globally installed 0.38.2 on this Mac wasn't used.

Stack: based on #19 (DITTO-1799) → #18 (DITTO-1800). Related: ditto-assistant/ditto-skills#16.

🤖 Generated with Claude Code

@ditto-code

ditto-code Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

⏭ Ditto stopped reviewing d4305b4

review stopped because the PR changed or repository reviews were paused

Open in Ditto · 1m1s

@Peyton-Spencer
Peyton-Spencer force-pushed the claude/ditto-1798-gemini-extension branch from d4305b4 to 1844c7c Compare November 1, 2026 01:14
@ditto-code

ditto-code Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

✅ Ditto reviewed 1844c7c

See this review run → · 3 new comments · approved

Open in Ditto · 12m57s

Comment thread scripts/validate_package.py Resolved
Comment thread scripts/validate_package.py Resolved
Comment thread .github/workflows/gemini-extension.yml Resolved

@ditto-code ditto-code Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto Review

No blocking issues found · risk: medium · 7843a3e

File coverage: 1 fully reviewed, 0 reviewed briefly, 0 not reviewed.

Add Gemini CLI support with a dedicated published extension branch — Adds Gemini CLI as a Ditto host using a gemini-extension.json manifest and a dedicated gemini-extension branch that publishes plugins/ditto at the repository root. The workflow verifies the package and tests before publishing; supporting changes update host guidance, manifests, validation, skill-version tracking, and tests. Review the publisher’s fast-forward behavior and the validator’s Gemini-specific restrictions closely.

Walkthrough (15 files)
File Change
.github/workflows/gemini-extension.yml Adds a main-branch workflow that verifies the package and publishes the Ditto plugin to the Gemini extension branch.
.kimi-plugin/plugin.json Bumps the root Kimi plugin version to 0.3.8.
CONTRIBUTING.md Documents Gemini’s manifest, MCP entry, and dedicated-branch publishing approach.
README.md Adds Gemini CLI installation, authentication, update, and validation guidance.
RELEASING.md Adds Gemini CLI validation and notes that merging plugin changes republishes its branch.
adapters/ditto-memory.md Adds Gemini CLI connection and authentication instructions.
plugins/ditto/{.antigravity-plugin,.claude-plugin,.codex-plugin,.cursor-plugin,.github/plugin,.grok-plugin,.kimi-plugin}/plugin.json Bumps the Ditto plugin version to 0.3.8 across the host manifests.
plugins/ditto/gemini-extension.json Declares Ditto’s Gemini extension metadata and hosted streamable-HTTP MCP server.
plugins/ditto/shared-skills.lock.json Updates the shared-skill source commit and corresponding content hashes.
plugins/ditto/skills/ditto-memory/SKILL.md Adds Gemini CLI connection and authentication guidance to the memory skill.
scripts/publish_extension_ref.py Adds a publisher that places a plugin folder at a branch root using fast-forward commits.
scripts/shared_skills.py Includes the Gemini manifest when tracking and bumping plugin host versions.
scripts/validate_package.py Validates Gemini manifests and restricts Gemini MCP declarations to the approved hosted endpoint.
tests/test_package.py Tests Gemini manifest validation and rejects unsupported MCP fields, endpoints, and extension directories.
tests/test_publish_extension_ref.py Tests branch publication, no-op and dry-run behavior, missing-manifest rejection, and fast-forward updates.
Review details
  • Models: review z-ai/glm-5.3-flash · verify openai/gpt-6-luna
  • Findings: 0 candidates → 0 verified → 0 posted
  • Context index: 42 files · 24 changed symbols · 60 references
  • Tokens: 67282 in / 4324 out · $0.01
  • Incremental since 4c52018
  • Run: d2ec33ce-1a4e-45ee-be0c-376c8ed0c189 · engine v2.0.0 · details
  • Ditto approves or requests changes in a separate review (blocking: 🟠 High and above). Inference is billed through your Ditto Router endpoint.

Open in Ditto · reply @ditto review to re-run · @ditto fix to push fixes

@ditto-code ditto-code Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto: approved — no blocking findings (🟠 High or above) in a complete review of 1844c7c. Findings below that do not block merging.

@Peyton-Spencer
Peyton-Spencer force-pushed the claude/ditto-1798-gemini-extension branch from 6c0de35 to 577dc3a Compare November 1, 2026 21:12
@Peyton-Spencer
Peyton-Spencer force-pushed the claude/ditto-1799-kimi-github-install branch from 07559a7 to 6fcbbd4 Compare November 1, 2026 21:13
@Peyton-Spencer

Copy link
Copy Markdown
Contributor Author

Addressed all three Ditto Review findings in 6c0de35 (carried through the rebase onto main as 577dc3a, same patch-id and tree):

  • httpUrl is now accepted only in the Gemini manifest. Every other MCP file and inline manifest uses the original url/serverUrl key set, and a new test checks that .mcp.json, mcp_config.json and the Kimi manifest reject an httpUrl-only server. That test fails against the previous validator: 3 of 3 subtests.
  • The gemini-extension publish job has timeout-minutes: 15.

@ditto-code

ditto-code Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

✅ Ditto reviewed 577dc3a

See this review run → · 1 new comment · approved

Open in Ditto · 5m43s

Comment thread tests/test_publish_extension_ref.py Resolved
ditto-code[bot]
ditto-code Bot previously approved these changes Nov 1, 2026

@ditto-code ditto-code Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto: approved — no blocking findings (🟠 High or above) in a complete review of 577dc3a. Findings below that do not block merging.

@Peyton-Spencer
Peyton-Spencer changed the base branch from claude/ditto-1799-kimi-github-install to main November 1, 2026 21:36
@Peyton-Spencer
Peyton-Spencer dismissed ditto-code[bot]’s stale review November 1, 2026 21:36

The base branch was changed.

Peyton-Spencer and others added 4 commits November 1, 2026 16:36
…O-1798]

Add plugins/ditto/gemini-extension.json: the hosted Ditto MCP server as
httpUrl (Gemini reads `url` as SSE), OAuth left to Gemini's dynamic
discovery on the server's 401. Gemini loads the bundled skills natively
from skills/, so `gemini extensions validate ./plugins/ditto` passes and
a local install lists 3 skills and the ditto server.

Gemini CLI installs a GitHub repository only from its root and has no
subdirectory option, and a root gemini-extension.json makes
`agy plugin install <repo>` install the whole repository as a Gemini
extension with no skills. So instead of a root manifest,
scripts/publish_extension_ref.py commits the plugins/ditto tree unchanged
as the next fast-forward commit of a dedicated branch, and
.github/workflows/gemini-extension.yml runs it on main:

  gemini extensions install https://github.com/ditto-assistant/ditto-plugins --ref gemini-extension

The validator adds the Gemini manifest (MCP-only, httpUrl only); the
ditto-memory adapter gains a Gemini CLI section; the vendored generator
comes from ditto-skills aab3efa, which versions gemini-extension.json.
All manifests move to 0.3.8.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Restacked on the DITTO-1799 Ditto Review fixes; regenerated the lock from
ditto-skills b406544. No skill bytes change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every other host reads url or serverUrl, so an httpUrl-only declaration
there validated while installing with no working MCP server. Also bound
the gemini-extension publish job to 15 minutes so a stalled run cannot
hold the concurrency slot for hours.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Peyton-Spencer
Peyton-Spencer force-pushed the claude/ditto-1798-gemini-extension branch from 577dc3a to 4c52018 Compare November 1, 2026 21:37
@ditto-code

ditto-code Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

✅ Ditto reviewed 4c52018

See this review run → · 1 new comment · approved

Open in Ditto · 9m8s

Comment thread tests/test_publish_extension_ref.py Resolved
ditto-code[bot]
ditto-code Bot previously approved these changes Nov 1, 2026

@ditto-code ditto-code Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto: approved — no blocking findings (🟠 High or above) in a complete review of 4c52018. Findings below that do not block merging.

…1798]

A global commit.gpgsign or hooks path made the publish tests depend on the
machine running them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ditto-code

ditto-code Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

✅ Ditto reviewed 7843a3e

See this review run → · no new comments · approved

Open in Ditto · 40s

@ditto-code ditto-code Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto: approved — no blocking findings (🟠 High or above) in a complete review of 7843a3e. Findings below that do not block merging.

@Peyton-Spencer
Peyton-Spencer merged commit 5975548 into main Nov 1, 2026
2 checks passed
@Peyton-Spencer
Peyton-Spencer deleted the claude/ditto-1798-gemini-extension branch November 1, 2026 21:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant