gemini-skill-install 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. gemini_skill_install-0.1.1/LICENSE +21 -0
  2. gemini_skill_install-0.1.1/MANIFEST.in +12 -0
  3. gemini_skill_install-0.1.1/PKG-INFO +189 -0
  4. gemini_skill_install-0.1.1/README.md +170 -0
  5. gemini_skill_install-0.1.1/SKILL.md +37 -0
  6. gemini_skill_install-0.1.1/VERSION +1 -0
  7. gemini_skill_install-0.1.1/adapters/__init__.py +0 -0
  8. gemini_skill_install-0.1.1/adapters/data/__init__.py +0 -0
  9. gemini_skill_install-0.1.1/adapters/data/batch.py +112 -0
  10. gemini_skill_install-0.1.1/adapters/data/cache.py +122 -0
  11. gemini_skill_install-0.1.1/adapters/data/embeddings.py +68 -0
  12. gemini_skill_install-0.1.1/adapters/data/file_search.py +185 -0
  13. gemini_skill_install-0.1.1/adapters/data/files.py +185 -0
  14. gemini_skill_install-0.1.1/adapters/data/token_count.py +52 -0
  15. gemini_skill_install-0.1.1/adapters/experimental/__init__.py +0 -0
  16. gemini_skill_install-0.1.1/adapters/experimental/computer_use.py +78 -0
  17. gemini_skill_install-0.1.1/adapters/experimental/deep_research.py +126 -0
  18. gemini_skill_install-0.1.1/adapters/generation/__init__.py +0 -0
  19. gemini_skill_install-0.1.1/adapters/generation/imagen.py +222 -0
  20. gemini_skill_install-0.1.1/adapters/generation/live.py +193 -0
  21. gemini_skill_install-0.1.1/adapters/generation/multimodal.py +84 -0
  22. gemini_skill_install-0.1.1/adapters/generation/streaming.py +54 -0
  23. gemini_skill_install-0.1.1/adapters/generation/structured.py +67 -0
  24. gemini_skill_install-0.1.1/adapters/generation/text.py +119 -0
  25. gemini_skill_install-0.1.1/adapters/media/__init__.py +0 -0
  26. gemini_skill_install-0.1.1/adapters/media/image_gen.py +158 -0
  27. gemini_skill_install-0.1.1/adapters/media/music_gen.py +104 -0
  28. gemini_skill_install-0.1.1/adapters/media/video_gen.py +152 -0
  29. gemini_skill_install-0.1.1/adapters/tools/__init__.py +0 -0
  30. gemini_skill_install-0.1.1/adapters/tools/code_exec.py +73 -0
  31. gemini_skill_install-0.1.1/adapters/tools/function_calling.py +82 -0
  32. gemini_skill_install-0.1.1/adapters/tools/maps.py +78 -0
  33. gemini_skill_install-0.1.1/adapters/tools/search.py +90 -0
  34. gemini_skill_install-0.1.1/core/__init__.py +0 -0
  35. gemini_skill_install-0.1.1/core/adapter/__init__.py +0 -0
  36. gemini_skill_install-0.1.1/core/adapter/contract.py +40 -0
  37. gemini_skill_install-0.1.1/core/adapter/helpers.py +226 -0
  38. gemini_skill_install-0.1.1/core/auth/__init__.py +0 -0
  39. gemini_skill_install-0.1.1/core/auth/auth.py +166 -0
  40. gemini_skill_install-0.1.1/core/cli/__init__.py +0 -0
  41. gemini_skill_install-0.1.1/core/cli/dispatch.py +256 -0
  42. gemini_skill_install-0.1.1/core/cli/health_main.py +204 -0
  43. gemini_skill_install-0.1.1/core/cli/install_main.py +440 -0
  44. gemini_skill_install-0.1.1/core/cli/installer/__init__.py +19 -0
  45. gemini_skill_install-0.1.1/core/cli/installer/api_key_prompt.py +177 -0
  46. gemini_skill_install-0.1.1/core/cli/installer/legacy_migration.py +122 -0
  47. gemini_skill_install-0.1.1/core/cli/installer/payload.py +63 -0
  48. gemini_skill_install-0.1.1/core/cli/installer/settings_merge.py +313 -0
  49. gemini_skill_install-0.1.1/core/cli/installer/venv.py +225 -0
  50. gemini_skill_install-0.1.1/core/cli/update_main.py +104 -0
  51. gemini_skill_install-0.1.1/core/infra/__init__.py +0 -0
  52. gemini_skill_install-0.1.1/core/infra/atomic_write.py +64 -0
  53. gemini_skill_install-0.1.1/core/infra/checksums.py +233 -0
  54. gemini_skill_install-0.1.1/core/infra/client.py +103 -0
  55. gemini_skill_install-0.1.1/core/infra/config.py +259 -0
  56. gemini_skill_install-0.1.1/core/infra/cost.py +170 -0
  57. gemini_skill_install-0.1.1/core/infra/errors.py +182 -0
  58. gemini_skill_install-0.1.1/core/infra/filelock.py +112 -0
  59. gemini_skill_install-0.1.1/core/infra/mime.py +45 -0
  60. gemini_skill_install-0.1.1/core/infra/sanitize.py +77 -0
  61. gemini_skill_install-0.1.1/core/infra/timeouts.py +106 -0
  62. gemini_skill_install-0.1.1/core/routing/__init__.py +0 -0
  63. gemini_skill_install-0.1.1/core/routing/registry.py +158 -0
  64. gemini_skill_install-0.1.1/core/routing/router.py +149 -0
  65. gemini_skill_install-0.1.1/core/routing/tool_state.py +95 -0
  66. gemini_skill_install-0.1.1/core/state/__init__.py +0 -0
  67. gemini_skill_install-0.1.1/core/state/file_state.py +141 -0
  68. gemini_skill_install-0.1.1/core/state/identity.py +124 -0
  69. gemini_skill_install-0.1.1/core/state/session_state.py +145 -0
  70. gemini_skill_install-0.1.1/core/state/store_state.py +160 -0
  71. gemini_skill_install-0.1.1/core/transport/__init__.py +295 -0
  72. gemini_skill_install-0.1.1/core/transport/_validation.py +96 -0
  73. gemini_skill_install-0.1.1/core/transport/base.py +349 -0
  74. gemini_skill_install-0.1.1/core/transport/coordinator.py +677 -0
  75. gemini_skill_install-0.1.1/core/transport/normalize.py +310 -0
  76. gemini_skill_install-0.1.1/core/transport/policy.py +131 -0
  77. gemini_skill_install-0.1.1/core/transport/raw_http/__init__.py +8 -0
  78. gemini_skill_install-0.1.1/core/transport/raw_http/client.py +355 -0
  79. gemini_skill_install-0.1.1/core/transport/raw_http/transport.py +194 -0
  80. gemini_skill_install-0.1.1/core/transport/sdk/__init__.py +0 -0
  81. gemini_skill_install-0.1.1/core/transport/sdk/async_transport.py +339 -0
  82. gemini_skill_install-0.1.1/core/transport/sdk/client_factory.py +243 -0
  83. gemini_skill_install-0.1.1/core/transport/sdk/transport.py +911 -0
  84. gemini_skill_install-0.1.1/core/types.py +23 -0
  85. gemini_skill_install-0.1.1/gemini_skill_install/__init__.py +1 -0
  86. gemini_skill_install-0.1.1/gemini_skill_install/__main__.py +9 -0
  87. gemini_skill_install-0.1.1/gemini_skill_install/cli.py +90 -0
  88. gemini_skill_install-0.1.1/gemini_skill_install.egg-info/PKG-INFO +189 -0
  89. gemini_skill_install-0.1.1/gemini_skill_install.egg-info/SOURCES.txt +127 -0
  90. gemini_skill_install-0.1.1/gemini_skill_install.egg-info/dependency_links.txt +1 -0
  91. gemini_skill_install-0.1.1/gemini_skill_install.egg-info/entry_points.txt +2 -0
  92. gemini_skill_install-0.1.1/gemini_skill_install.egg-info/requires.txt +3 -0
  93. gemini_skill_install-0.1.1/gemini_skill_install.egg-info/top_level.txt +2 -0
  94. gemini_skill_install-0.1.1/pyproject.toml +3 -0
  95. gemini_skill_install-0.1.1/reference/batch.md +71 -0
  96. gemini_skill_install-0.1.1/reference/cache.md +61 -0
  97. gemini_skill_install-0.1.1/reference/code_exec.md +54 -0
  98. gemini_skill_install-0.1.1/reference/computer_use.md +64 -0
  99. gemini_skill_install-0.1.1/reference/deep_research.md +75 -0
  100. gemini_skill_install-0.1.1/reference/embed.md +56 -0
  101. gemini_skill_install-0.1.1/reference/file_search.md +71 -0
  102. gemini_skill_install-0.1.1/reference/files.md +81 -0
  103. gemini_skill_install-0.1.1/reference/function_calling.md +66 -0
  104. gemini_skill_install-0.1.1/reference/image_gen.md +94 -0
  105. gemini_skill_install-0.1.1/reference/imagen.md +61 -0
  106. gemini_skill_install-0.1.1/reference/index.md +54 -0
  107. gemini_skill_install-0.1.1/reference/live.md +53 -0
  108. gemini_skill_install-0.1.1/reference/maps.md +72 -0
  109. gemini_skill_install-0.1.1/reference/multimodal.md +57 -0
  110. gemini_skill_install-0.1.1/reference/music_gen.md +68 -0
  111. gemini_skill_install-0.1.1/reference/search.md +66 -0
  112. gemini_skill_install-0.1.1/reference/streaming.md +51 -0
  113. gemini_skill_install-0.1.1/reference/structured.md +53 -0
  114. gemini_skill_install-0.1.1/reference/text.md +51 -0
  115. gemini_skill_install-0.1.1/reference/token_count.md +54 -0
  116. gemini_skill_install-0.1.1/reference/video_gen.md +67 -0
  117. gemini_skill_install-0.1.1/registry/capabilities.json +260 -0
  118. gemini_skill_install-0.1.1/registry/models.json +148 -0
  119. gemini_skill_install-0.1.1/scripts/gemini_run.py +108 -0
  120. gemini_skill_install-0.1.1/scripts/health_check.py +21 -0
  121. gemini_skill_install-0.1.1/scripts/install_git_hooks.sh +88 -0
  122. gemini_skill_install-0.1.1/scripts/render_diagrams.sh +45 -0
  123. gemini_skill_install-0.1.1/scripts/tag_release.sh +100 -0
  124. gemini_skill_install-0.1.1/setup/install.py +208 -0
  125. gemini_skill_install-0.1.1/setup/requirements.txt +17 -0
  126. gemini_skill_install-0.1.1/setup/update.py +21 -0
  127. gemini_skill_install-0.1.1/setup.cfg +4 -0
  128. gemini_skill_install-0.1.1/setup.py +86 -0
  129. gemini_skill_install-0.1.1/tests/test_phase11_branch_fillers.py +1030 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 reshinto
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,12 @@
1
+ include README.md
2
+ include LICENSE
3
+ include VERSION
4
+ include SKILL.md
5
+ recursive-include core *.py
6
+ recursive-include adapters *.py
7
+ recursive-include reference *.md
8
+ recursive-include registry *.json
9
+ recursive-include scripts *.py *.sh
10
+ include setup/install.py
11
+ include setup/update.py
12
+ include setup/requirements.txt
@@ -0,0 +1,189 @@
1
+ Metadata-Version: 2.4
2
+ Name: gemini-skill-install
3
+ Version: 0.1.1
4
+ Summary: Bootstrap installer for the gemini Claude Code skill
5
+ Home-page: https://github.com/reshinto/gemini-skill
6
+ License: MIT
7
+ Requires-Python: >=3.9
8
+ Description-Content-Type: text/markdown
9
+ License-File: LICENSE
10
+ Requires-Dist: typing-extensions>=4.0; python_version < "3.10"
11
+ Dynamic: description
12
+ Dynamic: description-content-type
13
+ Dynamic: home-page
14
+ Dynamic: license
15
+ Dynamic: license-file
16
+ Dynamic: requires-dist
17
+ Dynamic: requires-python
18
+ Dynamic: summary
19
+
20
+ # gemini-skill
21
+
22
+ A Claude Code skill for broad Gemini REST API access — text generation, multimodal input, image/video/music generation, embeddings, caching, batch processing, search grounding, code execution, file search, and more.
23
+
24
+ ## Quick Start
25
+
26
+ 1. **Install without cloning**
27
+ ```bash
28
+ uvx --from git+https://github.com/reshinto/gemini-skill gemini-skill-install
29
+ ```
30
+ Or with `pipx`:
31
+ ```bash
32
+ pipx run --spec git+https://github.com/reshinto/gemini-skill.git gemini-skill-install
33
+ ```
34
+ Tagged releases build and publish the same bootstrap installer to PyPI. After the
35
+ first PyPI release, these simplify to:
36
+ ```bash
37
+ uvx gemini-skill-install
38
+ pipx install gemini-skill-install
39
+ ```
40
+
41
+ 2. **Fallback: install from a clone or release tarball**
42
+ ```bash
43
+ git clone https://github.com/reshinto/gemini-skill.git
44
+ cd gemini-skill
45
+ python3 setup/install.py
46
+ ```
47
+ Both installer entry points call the same core installer. They:
48
+ - Copy operational files to `~/.claude/skills/gemini/`
49
+ - Includes the runtime payload: `SKILL.md`, `VERSION`, `core`, `adapters`, `reference`, `registry`, `scripts`, and `setup/{update.py,requirements.txt}`
50
+ - Creates `~/.claude/skills/gemini/.venv` with pinned `google-genai`
51
+ - Verifies install integrity via SHA-256 checksums
52
+ - Prompts for Gemini API key (hidden input)
53
+ - Merges env block into `~/.claude/settings.json` (with conflict resolution)
54
+ - Reuses an existing skill-local `.venv` on overwrite installs
55
+
56
+ 3. **Set your Gemini API key** (get one at [aistudio.google.com/apikey](https://aistudio.google.com/apikey))
57
+
58
+ The installer prompts you interactively. If you need to manually edit, add/update the `env` block in `~/.claude/settings.json`:
59
+ ```json
60
+ {
61
+ "env": {
62
+ "GEMINI_API_KEY": "AIzaSy...",
63
+ "GEMINI_IS_SDK_PRIORITY": "true",
64
+ "GEMINI_IS_RAWHTTP_PRIORITY": "false",
65
+ "GEMINI_LIVE_TESTS": "0"
66
+ }
67
+ }
68
+ ```
69
+ Claude Code injects these values into the process env at session start.
70
+
71
+ **Do NOT edit the repo-root `.env`** — that's only for local development from a clone. For the installed skill, use `~/.claude/settings.json` exclusively.
72
+
73
+ 4. **Fully restart Claude Code** (⌘Q on macOS, not "Reload Window"). Skill discovery and env injection happen at IDE launch.
74
+
75
+ 5. **Use it in Claude Code**
76
+ ```
77
+ /gemini text "Explain quantum computing"
78
+ ```
79
+
80
+ ## Architecture
81
+
82
+ ![Dual-backend transport architecture](docs/diagrams/architecture-dual-backend.svg)
83
+
84
+ ## Features
85
+
86
+ - Text generation, multimodal input, structured output, function calling
87
+ - Image generation (Nano Banana, Imagen 3), video generation (Veo), music generation (Lyria 3)
88
+ - Embeddings, context caching, batch processing, token counting
89
+ - Google Search grounding, Google Maps grounding, code execution
90
+ - File API, File Search / hosted RAG
91
+ - Deep Research (Interactions API), Computer Use (preview)
92
+ - Live API realtime sessions (async dispatch)
93
+ - Automatic model routing by task type and complexity
94
+ - Two-phase cost tracking (pre-flight estimate + post-response)
95
+ - Multi-turn conversation sessions with Gemini
96
+ - Dual transport backend — google-genai SDK primary + urllib raw HTTP fallback, user never picks
97
+
98
+ ## Prerequisites
99
+
100
+ - Python 3.9+
101
+ - A Gemini API key
102
+ - `google-genai==1.33.0` (installed automatically by the installer into `~/.claude/skills/gemini/.venv`)
103
+
104
+ ## Documentation
105
+
106
+ **Start here:** [docs/README.md](docs/README.md) — the single index hub for every doc and reference page.
107
+
108
+ ### Most-read pages
109
+
110
+ - **[Design patterns](docs/design-patterns.md)** — what / where / why / how for every architectural decision in the codebase (Adapter, Facade, Capability registry, Coordinator, Anti-corruption layer, Atomic write, SHA-256 integrity, etc.). Read this first if you're touching the code.
111
+ - **[Security & secrets storage](docs/security.md)** — full threat model + the "How the skill stores secrets and why it's safe" section explaining where `GEMINI_API_KEY` lives, why the chosen storage location is safe, alternatives rejected, and rotation procedure.
112
+ - **[Usage tour](docs/usage-tour.md)** — 16 end-to-end examples (text, multimodal, streaming, function calling, search grounding, image gen, batch, caching, sessions, dry-run vs `--execute`, error recovery).
113
+ - **[Per-command reference](reference/index.md)** — detailed docs for all 22 commands. Every page covers what / which model(s) / why (vs alternatives) / how (concrete usage).
114
+
115
+ ### Reference catalogs (single-page lookups)
116
+
117
+ - **[Flags reference](docs/flags-reference.md)** — every CLI flag the skill accepts, grouped by category (privacy, cost, execution, I/O), with rationale.
118
+ - **[Models reference](docs/models-reference.md)** — every model in the registry with cost tier, capabilities, and "when to pick this over siblings".
119
+
120
+ ### Architecture & internals
121
+
122
+ - [Architecture](docs/architecture.md) — System design, module layout, dual-backend transport diagram, "Why SKILL.md is terse" (token optimization rationale).
123
+ - [How It Works](docs/how-it-works.md) — End-to-end execution trace.
124
+ - [Model Routing](docs/model-routing.md) — Router decision tree.
125
+ - [Capabilities](docs/capabilities.md) — Feature matrix with status and limitations.
126
+ - [Commands](docs/commands.md) — Command index by capability family.
127
+
128
+ ### Operating the skill
129
+
130
+ - [Installation](docs/install.md) — Setup, troubleshooting, API key configuration.
131
+ - [Usage](docs/usage.md) — Getting started and common workflows.
132
+ - [Update & Sync](docs/update-sync.md) — Install mechanism, release checking, rollback, and release publishing.
133
+
134
+ ### Contributors
135
+
136
+ - [Contributing](docs/contributing.md) — Adding adapters, code style, PRs, strict typing rule.
137
+ - [Testing](docs/testing.md) — Running tests, writing tests, coverage, live API smoke tests.
138
+ - [Python Design](docs/python-guide.md) — Python 3.9+ floor, no `typing.Any`, idiomatic patterns.
139
+
140
+ ### Diagrams
141
+
142
+ All diagrams are committed as both Mermaid source (`.mmd`) and rendered SVG with white background under [docs/diagrams/](docs/diagrams/):
143
+
144
+ - `architecture-dual-backend.svg` — high-level dual-backend transport
145
+ - `coordinator-decision-flow.svg` — fallback eligibility + capability gate
146
+ - `backend-priority-matrix.svg` — env flag truth table
147
+ - `auth-resolution.svg` — `GEMINI_API_KEY` precedence
148
+ - `install-flow.svg` — installer pipeline
149
+ - `secrets-flow.svg` — secret storage data flow + threat boundaries
150
+ - `design-patterns-overview.svg` — class-diagram-style pattern map
151
+ - `command-dispatch-flow.svg` — request lifecycle from `/gemini` to stdout
152
+ - `token-optimization-flow.svg` — why SKILL.md stays small
153
+
154
+ Regenerate any diagram with `bash scripts/render_diagrams.sh [name]`.
155
+
156
+ ## Releases
157
+
158
+ Tagged releases (`v*`) run [.github/workflows/release.yml](.github/workflows/release.yml). The
159
+ workflow verifies `VERSION`, builds the GitHub release tarball plus Python
160
+ wheel/sdist artifacts, writes `checksums.txt`, creates the GitHub Release, and
161
+ publishes `gemini-skill-install` to PyPI via Trusted Publishing.
162
+
163
+ Maintainers can cut a release tag from the current [VERSION](VERSION) with:
164
+
165
+ ```bash
166
+ bash scripts/tag_release.sh
167
+ ```
168
+
169
+ See [docs/update-sync.md](docs/update-sync.md) for the full release flow.
170
+
171
+ ## Backends
172
+
173
+ By default, the skill uses the **google-genai SDK as the primary backend**, with **urllib raw HTTP as the fallback**. Both backends return identical response shapes via the `normalize` layer — adapters never know which ran.
174
+
175
+ To invert backend priority (raw HTTP primary, SDK fallback), edit `~/.claude/settings.json`:
176
+ ```json
177
+ {
178
+ "env": {
179
+ "GEMINI_IS_SDK_PRIORITY": "false",
180
+ "GEMINI_IS_RAWHTTP_PRIORITY": "true"
181
+ }
182
+ }
183
+ ```
184
+
185
+ Restart Claude Code. Both flags cannot be false (ConfigError), and if both are true, SDK wins.
186
+
187
+ ## License
188
+
189
+ MIT
@@ -0,0 +1,170 @@
1
+ # gemini-skill
2
+
3
+ A Claude Code skill for broad Gemini REST API access — text generation, multimodal input, image/video/music generation, embeddings, caching, batch processing, search grounding, code execution, file search, and more.
4
+
5
+ ## Quick Start
6
+
7
+ 1. **Install without cloning**
8
+ ```bash
9
+ uvx --from git+https://github.com/reshinto/gemini-skill gemini-skill-install
10
+ ```
11
+ Or with `pipx`:
12
+ ```bash
13
+ pipx run --spec git+https://github.com/reshinto/gemini-skill.git gemini-skill-install
14
+ ```
15
+ Tagged releases build and publish the same bootstrap installer to PyPI. After the
16
+ first PyPI release, these simplify to:
17
+ ```bash
18
+ uvx gemini-skill-install
19
+ pipx install gemini-skill-install
20
+ ```
21
+
22
+ 2. **Fallback: install from a clone or release tarball**
23
+ ```bash
24
+ git clone https://github.com/reshinto/gemini-skill.git
25
+ cd gemini-skill
26
+ python3 setup/install.py
27
+ ```
28
+ Both installer entry points call the same core installer. They:
29
+ - Copy operational files to `~/.claude/skills/gemini/`
30
+ - Includes the runtime payload: `SKILL.md`, `VERSION`, `core`, `adapters`, `reference`, `registry`, `scripts`, and `setup/{update.py,requirements.txt}`
31
+ - Creates `~/.claude/skills/gemini/.venv` with pinned `google-genai`
32
+ - Verifies install integrity via SHA-256 checksums
33
+ - Prompts for Gemini API key (hidden input)
34
+ - Merges env block into `~/.claude/settings.json` (with conflict resolution)
35
+ - Reuses an existing skill-local `.venv` on overwrite installs
36
+
37
+ 3. **Set your Gemini API key** (get one at [aistudio.google.com/apikey](https://aistudio.google.com/apikey))
38
+
39
+ The installer prompts you interactively. If you need to manually edit, add/update the `env` block in `~/.claude/settings.json`:
40
+ ```json
41
+ {
42
+ "env": {
43
+ "GEMINI_API_KEY": "AIzaSy...",
44
+ "GEMINI_IS_SDK_PRIORITY": "true",
45
+ "GEMINI_IS_RAWHTTP_PRIORITY": "false",
46
+ "GEMINI_LIVE_TESTS": "0"
47
+ }
48
+ }
49
+ ```
50
+ Claude Code injects these values into the process env at session start.
51
+
52
+ **Do NOT edit the repo-root `.env`** — that's only for local development from a clone. For the installed skill, use `~/.claude/settings.json` exclusively.
53
+
54
+ 4. **Fully restart Claude Code** (⌘Q on macOS, not "Reload Window"). Skill discovery and env injection happen at IDE launch.
55
+
56
+ 5. **Use it in Claude Code**
57
+ ```
58
+ /gemini text "Explain quantum computing"
59
+ ```
60
+
61
+ ## Architecture
62
+
63
+ ![Dual-backend transport architecture](docs/diagrams/architecture-dual-backend.svg)
64
+
65
+ ## Features
66
+
67
+ - Text generation, multimodal input, structured output, function calling
68
+ - Image generation (Nano Banana, Imagen 3), video generation (Veo), music generation (Lyria 3)
69
+ - Embeddings, context caching, batch processing, token counting
70
+ - Google Search grounding, Google Maps grounding, code execution
71
+ - File API, File Search / hosted RAG
72
+ - Deep Research (Interactions API), Computer Use (preview)
73
+ - Live API realtime sessions (async dispatch)
74
+ - Automatic model routing by task type and complexity
75
+ - Two-phase cost tracking (pre-flight estimate + post-response)
76
+ - Multi-turn conversation sessions with Gemini
77
+ - Dual transport backend — google-genai SDK primary + urllib raw HTTP fallback, user never picks
78
+
79
+ ## Prerequisites
80
+
81
+ - Python 3.9+
82
+ - A Gemini API key
83
+ - `google-genai==1.33.0` (installed automatically by the installer into `~/.claude/skills/gemini/.venv`)
84
+
85
+ ## Documentation
86
+
87
+ **Start here:** [docs/README.md](docs/README.md) — the single index hub for every doc and reference page.
88
+
89
+ ### Most-read pages
90
+
91
+ - **[Design patterns](docs/design-patterns.md)** — what / where / why / how for every architectural decision in the codebase (Adapter, Facade, Capability registry, Coordinator, Anti-corruption layer, Atomic write, SHA-256 integrity, etc.). Read this first if you're touching the code.
92
+ - **[Security & secrets storage](docs/security.md)** — full threat model + the "How the skill stores secrets and why it's safe" section explaining where `GEMINI_API_KEY` lives, why the chosen storage location is safe, alternatives rejected, and rotation procedure.
93
+ - **[Usage tour](docs/usage-tour.md)** — 16 end-to-end examples (text, multimodal, streaming, function calling, search grounding, image gen, batch, caching, sessions, dry-run vs `--execute`, error recovery).
94
+ - **[Per-command reference](reference/index.md)** — detailed docs for all 22 commands. Every page covers what / which model(s) / why (vs alternatives) / how (concrete usage).
95
+
96
+ ### Reference catalogs (single-page lookups)
97
+
98
+ - **[Flags reference](docs/flags-reference.md)** — every CLI flag the skill accepts, grouped by category (privacy, cost, execution, I/O), with rationale.
99
+ - **[Models reference](docs/models-reference.md)** — every model in the registry with cost tier, capabilities, and "when to pick this over siblings".
100
+
101
+ ### Architecture & internals
102
+
103
+ - [Architecture](docs/architecture.md) — System design, module layout, dual-backend transport diagram, "Why SKILL.md is terse" (token optimization rationale).
104
+ - [How It Works](docs/how-it-works.md) — End-to-end execution trace.
105
+ - [Model Routing](docs/model-routing.md) — Router decision tree.
106
+ - [Capabilities](docs/capabilities.md) — Feature matrix with status and limitations.
107
+ - [Commands](docs/commands.md) — Command index by capability family.
108
+
109
+ ### Operating the skill
110
+
111
+ - [Installation](docs/install.md) — Setup, troubleshooting, API key configuration.
112
+ - [Usage](docs/usage.md) — Getting started and common workflows.
113
+ - [Update & Sync](docs/update-sync.md) — Install mechanism, release checking, rollback, and release publishing.
114
+
115
+ ### Contributors
116
+
117
+ - [Contributing](docs/contributing.md) — Adding adapters, code style, PRs, strict typing rule.
118
+ - [Testing](docs/testing.md) — Running tests, writing tests, coverage, live API smoke tests.
119
+ - [Python Design](docs/python-guide.md) — Python 3.9+ floor, no `typing.Any`, idiomatic patterns.
120
+
121
+ ### Diagrams
122
+
123
+ All diagrams are committed as both Mermaid source (`.mmd`) and rendered SVG with white background under [docs/diagrams/](docs/diagrams/):
124
+
125
+ - `architecture-dual-backend.svg` — high-level dual-backend transport
126
+ - `coordinator-decision-flow.svg` — fallback eligibility + capability gate
127
+ - `backend-priority-matrix.svg` — env flag truth table
128
+ - `auth-resolution.svg` — `GEMINI_API_KEY` precedence
129
+ - `install-flow.svg` — installer pipeline
130
+ - `secrets-flow.svg` — secret storage data flow + threat boundaries
131
+ - `design-patterns-overview.svg` — class-diagram-style pattern map
132
+ - `command-dispatch-flow.svg` — request lifecycle from `/gemini` to stdout
133
+ - `token-optimization-flow.svg` — why SKILL.md stays small
134
+
135
+ Regenerate any diagram with `bash scripts/render_diagrams.sh [name]`.
136
+
137
+ ## Releases
138
+
139
+ Tagged releases (`v*`) run [.github/workflows/release.yml](.github/workflows/release.yml). The
140
+ workflow verifies `VERSION`, builds the GitHub release tarball plus Python
141
+ wheel/sdist artifacts, writes `checksums.txt`, creates the GitHub Release, and
142
+ publishes `gemini-skill-install` to PyPI via Trusted Publishing.
143
+
144
+ Maintainers can cut a release tag from the current [VERSION](VERSION) with:
145
+
146
+ ```bash
147
+ bash scripts/tag_release.sh
148
+ ```
149
+
150
+ See [docs/update-sync.md](docs/update-sync.md) for the full release flow.
151
+
152
+ ## Backends
153
+
154
+ By default, the skill uses the **google-genai SDK as the primary backend**, with **urllib raw HTTP as the fallback**. Both backends return identical response shapes via the `normalize` layer — adapters never know which ran.
155
+
156
+ To invert backend priority (raw HTTP primary, SDK fallback), edit `~/.claude/settings.json`:
157
+ ```json
158
+ {
159
+ "env": {
160
+ "GEMINI_IS_SDK_PRIORITY": "false",
161
+ "GEMINI_IS_RAWHTTP_PRIORITY": "true"
162
+ }
163
+ }
164
+ ```
165
+
166
+ Restart Claude Code. Both flags cannot be false (ConfigError), and if both are true, SDK wins.
167
+
168
+ ## License
169
+
170
+ MIT
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: gemini
3
+ description: Gemini API — text generation, image/video/music generation, embeddings, search grounding, maps grounding, context caching, batch processing, code execution, function calling, file search/RAG, computer use, deep research, and more.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ ## Usage
8
+
9
+ Run: `python3 "${CLAUDE_SKILL_DIR}/scripts/gemini_run.py" <command> [args]`
10
+
11
+ The launcher self-routes: if the skill-local virtual environment exists at `${CLAUDE_SKILL_DIR}/.venv`, it re-execs into `${CLAUDE_SKILL_DIR}/.venv/bin/python` so the dual-backend SDK is loaded; otherwise it runs under whichever Python invoked it (the raw HTTP backend works without google-genai installed).
12
+
13
+ See `${CLAUDE_SKILL_DIR}/reference/index.md` for the full command map.
14
+ For commands with flags or `--execute`, read `${CLAUDE_SKILL_DIR}/reference/<command>.md` first.
15
+
16
+ ## How transport works
17
+
18
+ All commands route through `scripts/gemini_run.py` which dispatches to the right adapter. The adapter calls a single `api_call` / `stream_generate_content` / `upload_file` facade that picks the right backend automatically based on `GEMINI_IS_SDK_PRIORITY` / `GEMINI_IS_RAWHTTP_PRIORITY` environment variables. **You do not need to know which backend is active** — every command has identical CLI surface, identical output shape, and identical error format regardless of whether the SDK or raw HTTP path handled the call.
19
+
20
+ ## Rules
21
+
22
+ - Mutating operations and mutating subcommands require `--execute`. Default is dry-run.
23
+ - Privacy-sensitive commands (search grounding, maps grounding, computer use, deep research) are handled internally by dispatch; callers do not pass a separate privacy flag.
24
+ - Pass user input as single opaque argv values (quoted).
25
+ - Use stdin or temp files for complex/multiline content.
26
+ - Never reconstruct shell commands by concatenating user text.
27
+ - Multi-turn sessions: use `--session <id>` to start/continue, `--continue` for most recent.
28
+ - Large responses (>50KB) and all media generation save to a file and return only the path + metadata.
29
+
30
+ ## Quick commands
31
+
32
+ - `help` — list all commands
33
+ - `models` — list available models from registry
34
+ - `text "prompt"` — generate text
35
+ - `multimodal "prompt" --file path.pdf` — analyze files
36
+ - `embed "text"` — generate embeddings
37
+ - `image_gen "prompt" --execute` — generate an image
@@ -0,0 +1 @@
1
+ 0.1.1
File without changes
File without changes
@@ -0,0 +1,112 @@
1
+ """Batch API adapter — submit, list, get, and cancel batch jobs.
2
+
3
+ Submits multiple requests for async processing at reduced cost.
4
+ Mutating operations (create, cancel) require --execute.
5
+
6
+ Dependencies: core/infra/client.py, core/adapter/helpers.py
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import argparse
12
+
13
+ from core.adapter.helpers import add_execute_flag, build_base_parser, check_dry_run, emit_json
14
+ from core.infra.sanitize import safe_print
15
+ from core.infra.client import api_call
16
+
17
+
18
+ def get_parser() -> argparse.ArgumentParser:
19
+ """Return the argument parser for the batch adapter."""
20
+ parser = build_base_parser("Manage Gemini batch processing jobs")
21
+ sub = parser.add_subparsers(dest="action", help="Batch action")
22
+
23
+ create_p = sub.add_parser("create", help="Create a batch job")
24
+ add_execute_flag(create_p)
25
+ create_p.add_argument("--src", required=True, help="Source file URI (JSONL).")
26
+ create_p.add_argument("--dest", required=True, help="Destination file URI.")
27
+
28
+ sub.add_parser("list", help="List batch jobs")
29
+
30
+ get_p = sub.add_parser("get", help="Get batch job status")
31
+ get_p.add_argument("name", help="Batch job resource name.")
32
+
33
+ cancel_p = sub.add_parser("cancel", help="Cancel a running batch job")
34
+ add_execute_flag(cancel_p)
35
+ cancel_p.add_argument("name", help="Batch job resource name to cancel.")
36
+
37
+ return parser
38
+
39
+
40
+ def run(
41
+ action: str | None = None,
42
+ name: str | None = None,
43
+ src: str | None = None,
44
+ dest: str | None = None,
45
+ model: str | None = None,
46
+ execute: bool = False,
47
+ **kwargs: object,
48
+ ) -> None:
49
+ """Execute batch management operations."""
50
+ if action == "create":
51
+ _create(src=src, dest=dest, model=model, execute=execute)
52
+ elif action == "list":
53
+ _list_batches()
54
+ elif action == "get":
55
+ _get_batch(name=name)
56
+ elif action == "cancel":
57
+ _cancel_batch(name=name, execute=execute)
58
+ else:
59
+ safe_print("[ERROR] No action specified. Use: create, list, get, cancel")
60
+
61
+
62
+ def _create(
63
+ src: str | None,
64
+ dest: str | None,
65
+ model: str | None,
66
+ execute: bool,
67
+ ) -> None:
68
+ """Create a batch processing job."""
69
+ if not src or not dest:
70
+ safe_print("[ERROR] Both --src and --dest are required.")
71
+ return
72
+
73
+ if check_dry_run(execute, f"create batch job from {src}"):
74
+ return
75
+
76
+ body: dict[str, object] = {
77
+ "inputConfig": {"gcsSource": {"inputUri": src}},
78
+ "outputConfig": {"gcsDestination": {"outputUriPrefix": dest}},
79
+ }
80
+ if model:
81
+ body["model"] = f"models/{model}"
82
+
83
+ response = api_call("batchJobs", body=body)
84
+ emit_json(response)
85
+
86
+
87
+ def _list_batches() -> None:
88
+ """List all batch jobs."""
89
+ response = api_call("batchJobs", method="GET")
90
+ jobs_value = response.get("batchJobs")
91
+ jobs = jobs_value if isinstance(jobs_value, list) else []
92
+ emit_json({"count": len(jobs), "jobs": jobs})
93
+
94
+
95
+ def _get_batch(name: str | None) -> None:
96
+ """Get status of a batch job."""
97
+ if not name:
98
+ safe_print("[ERROR] No batch job name provided.")
99
+ return
100
+ response = api_call(name, method="GET")
101
+ emit_json(response)
102
+
103
+
104
+ def _cancel_batch(name: str | None, execute: bool) -> None:
105
+ """Cancel a running batch job."""
106
+ if not name:
107
+ safe_print("[ERROR] No batch job name provided.")
108
+ return
109
+ if check_dry_run(execute, f"cancel batch {name}"):
110
+ return
111
+ api_call(f"{name}:cancel", body={})
112
+ safe_print(f"Cancelled batch {name}")
@@ -0,0 +1,122 @@
1
+ """Context caching adapter — create, list, get, and delete caches.
2
+
3
+ Caches large content (system instructions, files) to reduce cost and
4
+ latency on repeated requests. Mutating operations require --execute.
5
+
6
+ Dependencies: core/infra/client.py, core/adapter/helpers.py
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import argparse
12
+ from pathlib import Path
13
+
14
+ from core.adapter.helpers import add_execute_flag, build_base_parser, check_dry_run, emit_json
15
+ from core.infra.sanitize import safe_print
16
+ from core.infra.client import api_call
17
+ from core.infra.config import load_config
18
+
19
+
20
+ def get_parser() -> argparse.ArgumentParser:
21
+ """Return the argument parser for the cache adapter."""
22
+ parser = build_base_parser("Manage Gemini context caches")
23
+ sub = parser.add_subparsers(dest="action", help="Cache action")
24
+
25
+ create_p = sub.add_parser("create", help="Create a cache")
26
+ add_execute_flag(create_p)
27
+ create_p.add_argument("content", help="Content to cache (text or file URI).")
28
+ create_p.add_argument("--ttl", default="3600s", help="Time-to-live (e.g., '3600s').")
29
+
30
+ sub.add_parser("list", help="List existing caches")
31
+
32
+ get_p = sub.add_parser("get", help="Get cache metadata")
33
+ get_p.add_argument("name", help="Cache resource name.")
34
+
35
+ delete_p = sub.add_parser("delete", help="Delete a cache")
36
+ add_execute_flag(delete_p)
37
+ delete_p.add_argument("name", help="Cache resource name to delete.")
38
+
39
+ return parser
40
+
41
+
42
+ def run(
43
+ action: str | None = None,
44
+ content: str | None = None,
45
+ name: str | None = None,
46
+ ttl: str = "3600s",
47
+ model: str | None = None,
48
+ execute: bool = False,
49
+ **kwargs: object,
50
+ ) -> None:
51
+ """Execute cache management operations."""
52
+ if action == "create":
53
+ _create(content=content, ttl=ttl, model=model, execute=execute)
54
+ elif action == "list":
55
+ _list_caches()
56
+ elif action == "get":
57
+ _get_cache(name=name)
58
+ elif action == "delete":
59
+ _delete_cache(name=name, execute=execute)
60
+ else:
61
+ safe_print("[ERROR] No action specified. Use: create, list, get, delete")
62
+
63
+
64
+ def _create(
65
+ content: str | None,
66
+ ttl: str,
67
+ model: str | None,
68
+ execute: bool,
69
+ ) -> None:
70
+ """Create a context cache."""
71
+ if not content:
72
+ safe_print("[ERROR] No content provided.")
73
+ return
74
+
75
+ if check_dry_run(execute, f"create cache with TTL {ttl}"):
76
+ return
77
+
78
+ from core.routing.router import Router
79
+
80
+ config = load_config()
81
+ router = Router(
82
+ root_dir=Path(__file__).parent.parent.parent,
83
+ prefer_preview=config.prefer_preview_models,
84
+ )
85
+ resolved_model = model or router.select_model("cache")
86
+
87
+ body: dict[str, object] = {
88
+ "model": f"models/{resolved_model}",
89
+ "contents": [{"role": "user", "parts": [{"text": content}]}],
90
+ "ttl": ttl,
91
+ }
92
+
93
+ response = api_call("cachedContents", body=body)
94
+ emit_json(response)
95
+
96
+
97
+ def _list_caches() -> None:
98
+ """List all context caches."""
99
+ response = api_call("cachedContents", method="GET")
100
+ caches_value = response.get("cachedContents")
101
+ caches = caches_value if isinstance(caches_value, list) else []
102
+ emit_json({"count": len(caches), "caches": caches})
103
+
104
+
105
+ def _get_cache(name: str | None) -> None:
106
+ """Get metadata for a single cache."""
107
+ if not name:
108
+ safe_print("[ERROR] No cache name provided.")
109
+ return
110
+ response = api_call(name, method="GET")
111
+ emit_json(response)
112
+
113
+
114
+ def _delete_cache(name: str | None, execute: bool) -> None:
115
+ """Delete a context cache."""
116
+ if not name:
117
+ safe_print("[ERROR] No cache name provided.")
118
+ return
119
+ if check_dry_run(execute, f"delete cache {name}"):
120
+ return
121
+ api_call(name, method="DELETE")
122
+ safe_print(f"Deleted cache {name}")