Skip to content

[AI-887] Google Gemini CLI ingest (CLI side)#164

Merged
realtonyyoung merged 5 commits into
kurrent-io:mainfrom
realtonyyoung:tonyyoung/ai-887-gemini-cli-ingest
Jun 18, 2026
Merged

[AI-887] Google Gemini CLI ingest (CLI side)#164
realtonyyoung merged 5 commits into
kurrent-io:mainfrom
realtonyyoung:tonyyoung/ai-887-gemini-cli-ingest

Conversation

@realtonyyoung

Copy link
Copy Markdown
Contributor

[AI-887] Google Gemini CLI ingest — CLI side

Companion to the server PR (kurrent-io/kcap-server#759). Adds Google Gemini CLI as the 6th ingest vendor, mirroring the Copilot pattern. Must merge after the server PR deploys (this PR's hooks POST to /hooks/session-{start,end}/gemini + /hooks/transcript?vendor=gemini, which the server PR adds).

Done in this PR (builds clean)

  • Core/Gemini/GeminiPaths~/.gemini layout ($GEMINI_HOME honoured; settings.json; tmp/<project>/chats/).
  • Core/Gemini/GeminiHooksParser + GeminiHooksInstaller — helpers for the SHARED ~/.gemini/settings.json hooks block (nested {hooks:[{command}]} shape; merge/detect/marker — must preserve user-authored hooks, like the Cursor installer).
  • Commands/GeminiHookCommand — self-routes on hook_event_name (Gemini provides it, unlike Copilot); POSTs lifecycle to /hooks/session-{start,end}/gemini; spawns the watcher on the payload's transcript_path with vendor=gemini; capped inline drain on SessionEnd; Notification/hooks/notification.
  • Wiring: kcap hook --gemini dispatch + KCAP_SKIP gate + usage in Program.cs; gemini added to WatchCommand.KnownVendors.

Follow-ups (this branch, before marking ready)

  • PluginCommand InstallGeminiHooks/RemoveGeminiHooks (settings.json merge) + --gemini / --skip-gemini-hooks dispatch.
  • SetupCommand / CodingAgentsStep Gemini detection + install offer.
  • GeminiImportSource : IImportSource (kcap import --gemini, walking ~/.gemini/tmp/*/chats/*.jsonl) + VendorSelection --gemini.
  • Unit tests (hooks-merge + import discovery), AOT publish check, and README.md (new --gemini surface).

Spec + design: AI-887 (and server PR #759).

🤖 Generated with Claude Code

realtonyyoung and others added 3 commits June 17, 2026 15:07
Core/Gemini: GeminiPaths (~/.gemini layout), GeminiHooksParser (settings.json
nested {hooks:[{command}]} merge helpers + kcap entry builder), GeminiHooksInstaller
(marker/detection over the shared settings.json).

Live: GeminiHookCommand self-routes on hook_event_name (Gemini provides it),
POSTs lifecycle to /hooks/session-{start,end}/gemini, spawns the watcher on the
payload's transcript_path with vendor=gemini, capped drain on SessionEnd,
Notification -> /hooks/notification. Wired kcap hook --gemini dispatch + KCAP_SKIP
gate + usage in Program.cs; gemini added to WatchCommand.KnownVendors.

Follow-ups on this branch: PluginCommand install/remove (settings.json merge) +
setup detection, GeminiImportSource + import wiring, unit tests, README.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
PluginCommand InstallGemini/RemoveGemini + InstallGeminiHooks/RemoveGeminiHooks
(merge into the shared ~/.gemini/settings.json hooks block, preserving user
hooks + other settings keys; nested {hooks:[{command}]} entries via
GeminiHooksParser.BuildKcapEntry). --gemini/--skip-gemini-hooks dispatch.
CodingAgentsStep + SetupCommand thread Gemini through DetectedAgents/Options/
Paths/Installers/Result (detect via GeminiPaths.IsInstalled || gemini on PATH).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
GeminiImportSource (IImportSource) walks ~/.gemini/tmp/*/chats/session-*.jsonl,
reads the full dashed session id from the header record, classifies vs the
server watermark (IsImportRelevantLine mirrors the normalizer skip rules), and
imports lifecycle + transcript through the same routes as live capture. Wired
--gemini into VendorSelection + the ImportCommand sources array. CodingAgentsStep
records default the new Gemini fields so existing call sites compile unchanged;
AsInstallers test helper + TestPaths updated. Fixed an AOT IL2026/IL3050 warning
(JsonArray.Add<JsonObject> -> cast to JsonNode, matching the Cursor installer).

Tests: GeminiHooksTests (merge/preserve/remove/idempotent) + GeminiImportSourceTests
(discovery + IsImportRelevantLine) — 13 new, CodingAgentsStep 29 green, AOT publish
IL-clean. README documents the --gemini surface (setup detect, plugin install/remove,
import, hooks section).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@realtonyyoung realtonyyoung marked this pull request as ready for review June 17, 2026 19:33
@qodo-code-review

Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

Comment thread src/Capacitor.Cli/Commands/PluginCommand.cs Outdated
~/.gemini/settings.json is SHARED user config, not a kcap-owned hook file. The
installer caught a JSON parse failure and fell through with root = [], then
File.WriteAllText overwrote the WHOLE file with only kcap hooks — silently
dropping the user's unrelated Gemini settings if the file was malformed or
half-written.

InstallGeminiHooks now fails closed: when settings.json exists but won't parse
into a JSON object, it returns false and leaves the file untouched (matching the
RemoveClaudePlugin 'Malformed' precedent). The install command + setup wizard
now tell the user to make settings.json valid JSON and that it was left
untouched. Cursor/Copilot are unaffected — they own their dedicated hooks file
and may safely start fresh.

Tests: install_leaves_malformed_settings_untouched and
install_leaves_non_object_settings_untouched assert false + byte-for-byte
unchanged file. Full unit suite green (1535); AOT publish clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Comment thread src/Capacitor.Cli/Commands/PluginCommand.cs
Comment thread src/Capacitor.Cli/Commands/PluginCommand.cs
Two review findings on the Gemini CLI support:

1. kcap uninstall skipped Gemini. UninstallCommand removed Claude/Codex/Cursor/
   Copilot + skills and deleted their markers, but never ran
   'plugin remove --gemini' or deleted the Gemini marker — so a user who installed
   Gemini hooks and then uninstalled would keep 'kcap hook --gemini' merged into
   ~/.gemini/settings.json, launching a removed command. Now uninstall removes the
   Gemini hooks and the .kcap-hooks-version marker (belt-and-braces, like Cursor),
   prints the Gemini line, and help-uninstall.txt documents it. Regression: the
   comprehensive uninstall test now seeds a Gemini settings.json (kcap + user hook
   + unrelated key + marker) and asserts kcap is gone, user content survives, and
   IsInstalled() is false.

2. Embedded help never advertised Gemini even though --gemini works and the README
   mentions it. Added Gemini to help-plugin (option/notes/examples), help-hook
   (--gemini dispatch), help-setup (--skip-gemini-hooks + detection + install
   example), help-import (transcript root + --gemini filter), and help-usage
   (import summary + hook line). So kcap help / plugin|hook|setup|import --help now
   surface Gemini.

Full unit suite green (1533); AOT publish clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@realtonyyoung realtonyyoung merged commit 287efe8 into kurrent-io:main Jun 18, 2026
5 checks passed
realtonyyoung added a commit that referenced this pull request Jun 18, 2026
help-usage.txt's Plugin: summary listed --codex|--cursor|--copilot|--skills but
not --gemini — #163 rewrote that line after the #164 branch point, so the 3-way
merge left Gemini off. The import line, hooks section, and full help-plugin.txt
already advertise it; this aligns the one-line summary.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
realtonyyoung added a commit that referenced this pull request Jun 18, 2026
Brings in the Gemini CLI vendor (AI-887, #164), help-text refresh (#163),
and the YAML redactor fix (#166). All conflicts were parallel-vendor
additions (Kiro vs Gemini) resolved by keeping both, Gemini before Kiro.
Build + 1567 unit tests green; NativeAOT publish clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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