@every-env/compound-plugin 0.5.1 → 0.7.0

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 (35) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/CHANGELOG.md +34 -0
  3. package/README.md +20 -3
  4. package/docs/plans/2026-02-14-feat-add-gemini-cli-target-provider-plan.md +370 -0
  5. package/docs/specs/gemini.md +122 -0
  6. package/package.json +1 -1
  7. package/plugins/compound-engineering/.claude-plugin/plugin.json +1 -1
  8. package/plugins/compound-engineering/CHANGELOG.md +17 -0
  9. package/plugins/compound-engineering/commands/workflows/plan.md +3 -0
  10. package/plugins/compound-engineering/commands/workflows/work.md +8 -1
  11. package/src/commands/convert.ts +14 -25
  12. package/src/commands/install.ts +28 -26
  13. package/src/commands/sync.ts +44 -21
  14. package/src/converters/claude-to-gemini.ts +193 -0
  15. package/src/converters/claude-to-opencode.ts +16 -0
  16. package/src/converters/claude-to-pi.ts +205 -0
  17. package/src/sync/cursor.ts +78 -0
  18. package/src/sync/droid.ts +21 -0
  19. package/src/sync/pi.ts +88 -0
  20. package/src/targets/gemini.ts +68 -0
  21. package/src/targets/index.ts +18 -0
  22. package/src/targets/pi.ts +131 -0
  23. package/src/templates/pi/compat-extension.ts +452 -0
  24. package/src/types/gemini.ts +29 -0
  25. package/src/types/pi.ts +40 -0
  26. package/src/utils/resolve-home.ts +17 -0
  27. package/tests/cli.test.ts +76 -0
  28. package/tests/converter.test.ts +29 -0
  29. package/tests/gemini-converter.test.ts +373 -0
  30. package/tests/gemini-writer.test.ts +181 -0
  31. package/tests/pi-converter.test.ts +116 -0
  32. package/tests/pi-writer.test.ts +99 -0
  33. package/tests/sync-cursor.test.ts +92 -0
  34. package/tests/sync-droid.test.ts +57 -0
  35. package/tests/sync-pi.test.ts +68 -0
@@ -12,7 +12,7 @@
12
12
  {
13
13
  "name": "compound-engineering",
14
14
  "description": "AI-powered development tools that get smarter with every use. Make each unit of engineering work easier than the last. Includes 29 specialized agents, 22 commands, and 19 skills.",
15
- "version": "2.33.0",
15
+ "version": "2.34.0",
16
16
  "author": {
17
17
  "name": "Kieran Klaassen",
18
18
  "url": "https://github.com/kieranklaassen",
package/CHANGELOG.md ADDED
@@ -0,0 +1,34 @@
1
+ # Changelog
2
+
3
+ All notable changes to the `@every-env/compound-plugin` CLI tool will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.6.0] - 2026-02-12
9
+
10
+ ### Added
11
+
12
+ - **Droid sync target** — `sync --target droid` symlinks personal skills to `~/.factory/skills/`
13
+ - **Cursor sync target** — `sync --target cursor` symlinks skills to `.cursor/skills/` and merges MCP servers into `.cursor/mcp.json`
14
+ - **Pi target** — First-class `--to pi` converter with MCPorter config and subagent compatibility ([#181](https://github.com/EveryInc/compound-engineering-plugin/pull/181)) — thanks [@gvkhosla](https://github.com/gvkhosla)!
15
+
16
+ ### Fixed
17
+
18
+ - **Bare Claude model alias resolution** — Fixed OpenCode converter not resolving bare model aliases like `claude-sonnet-4-5-20250514` ([#182](https://github.com/EveryInc/compound-engineering-plugin/pull/182)) — thanks [@waltbeaman](https://github.com/waltbeaman)!
19
+
20
+ ### Changed
21
+
22
+ - Extracted shared `expandHome` / `resolveTargetHome` helpers to `src/utils/resolve-home.ts`, removing duplication across `convert.ts`, `install.ts`, and `sync.ts`
23
+
24
+ ---
25
+
26
+ ## [0.5.2] - 2026-02-09
27
+
28
+ ### Fixed
29
+
30
+ - Fix cursor install defaulting to cwd instead of opencode config dir
31
+
32
+ ## [0.5.1] - 2026-02-08
33
+
34
+ - Initial npm publish
package/README.md CHANGED
@@ -12,9 +12,9 @@ A Claude Code plugin marketplace featuring the **Compound Engineering Plugin**
12
12
  /plugin install compound-engineering
13
13
  ```
14
14
 
15
- ## OpenCode, Codex, Droid & Cursor (experimental) Install
15
+ ## OpenCode, Codex, Droid, Cursor, Pi & Gemini (experimental) Install
16
16
 
17
- This repo includes a Bun/TypeScript CLI that converts Claude Code plugins to OpenCode, Codex, Factory Droid, and Cursor.
17
+ This repo includes a Bun/TypeScript CLI that converts Claude Code plugins to OpenCode, Codex, Factory Droid, Cursor, Pi, and Gemini CLI.
18
18
 
19
19
  ```bash
20
20
  # convert the compound-engineering plugin into OpenCode format
@@ -28,6 +28,12 @@ bunx @every-env/compound-plugin install compound-engineering --to droid
28
28
 
29
29
  # convert to Cursor format
30
30
  bunx @every-env/compound-plugin install compound-engineering --to cursor
31
+
32
+ # convert to Pi format
33
+ bunx @every-env/compound-plugin install compound-engineering --to pi
34
+
35
+ # convert to Gemini CLI format
36
+ bunx @every-env/compound-plugin install compound-engineering --to gemini
31
37
  ```
32
38
 
33
39
  Local dev:
@@ -40,12 +46,14 @@ OpenCode output is written to `~/.config/opencode` by default, with `opencode.js
40
46
  Codex output is written to `~/.codex/prompts` and `~/.codex/skills`, with each Claude command converted into both a prompt and a skill (the prompt instructs Codex to load the corresponding skill). Generated Codex skill descriptions are truncated to 1024 characters (Codex limit).
41
47
  Droid output is written to `~/.factory/` with commands, droids (agents), and skills. Claude tool names are mapped to Factory equivalents (`Bash` → `Execute`, `Write` → `Create`, etc.) and namespace prefixes are stripped from commands.
42
48
  Cursor output is written to `.cursor/` with rules (`.mdc`), commands, skills, and `mcp.json`. Agents become "Agent Requested" rules (`alwaysApply: false`) so Cursor's AI activates them on demand. Works with both the Cursor IDE and Cursor CLI (`cursor-agent`) — they share the same `.cursor/` config directory.
49
+ Pi output is written to `~/.pi/agent/` by default with prompts, skills, extensions, and `compound-engineering/mcporter.json` for MCPorter interoperability.
50
+ Gemini output is written to `.gemini/` with skills (from agents), commands (`.toml`), and `settings.json` (MCP servers). Namespaced commands create directory structure (`workflows:plan` → `commands/workflows/plan.toml`). Skills use the identical SKILL.md standard and pass through unchanged.
43
51
 
44
52
  All provider targets are experimental and may change as the formats evolve.
45
53
 
46
54
  ## Sync Personal Config
47
55
 
48
- Sync your personal Claude Code config (`~/.claude/`) to OpenCode or Codex:
56
+ Sync your personal Claude Code config (`~/.claude/`) to other AI coding tools:
49
57
 
50
58
  ```bash
51
59
  # Sync skills and MCP servers to OpenCode
@@ -53,6 +61,15 @@ bunx @every-env/compound-plugin sync --target opencode
53
61
 
54
62
  # Sync to Codex
55
63
  bunx @every-env/compound-plugin sync --target codex
64
+
65
+ # Sync to Pi
66
+ bunx @every-env/compound-plugin sync --target pi
67
+
68
+ # Sync to Droid (skills only)
69
+ bunx @every-env/compound-plugin sync --target droid
70
+
71
+ # Sync to Cursor (skills + MCP servers)
72
+ bunx @every-env/compound-plugin sync --target cursor
56
73
  ```
57
74
 
58
75
  This syncs:
@@ -0,0 +1,370 @@
1
+ ---
2
+ title: Add Gemini CLI as a Target Provider
3
+ type: feat
4
+ status: completed
5
+ completed_date: 2026-02-14
6
+ completed_by: "Claude Opus 4.6"
7
+ actual_effort: "Completed in one session"
8
+ date: 2026-02-14
9
+ ---
10
+
11
+ # Add Gemini CLI as a Target Provider
12
+
13
+ ## Overview
14
+
15
+ Add `gemini` as a sixth target provider in the converter CLI, alongside `opencode`, `codex`, `droid`, `cursor`, and `pi`. This enables `--to gemini` for both `convert` and `install` commands, converting Claude Code plugins into Gemini CLI-compatible format.
16
+
17
+ Gemini CLI ([google-gemini/gemini-cli](https://github.com/google-gemini/gemini-cli)) is Google's open-source AI agent for the terminal. It supports GEMINI.md context files, custom commands (TOML format), agent skills (SKILL.md standard), MCP servers, and extensions -- making it a strong conversion target with good coverage of Claude Code plugin concepts.
18
+
19
+ ## Component Mapping
20
+
21
+ | Claude Code | Gemini Equivalent | Notes |
22
+ |---|---|---|
23
+ | `agents/*.md` | `.gemini/skills/*/SKILL.md` | Agents become skills -- Gemini activates them on demand via `activate_skill` tool based on description matching |
24
+ | `commands/*.md` | `.gemini/commands/*.toml` | TOML format with `prompt` and `description` fields; namespaced via directory structure |
25
+ | `skills/*/SKILL.md` | `.gemini/skills/*/SKILL.md` | **Identical standard** -- copy directly |
26
+ | MCP servers | `settings.json` `mcpServers` | Same MCP protocol; different config location (`settings.json` vs `.mcp.json`) |
27
+ | `hooks/` | `settings.json` hooks | Gemini has hooks (`BeforeTool`, `AfterTool`, `SessionStart`, etc.) but different format; emit `console.warn` and skip for now |
28
+ | `.claude/` paths | `.gemini/` paths | Content rewriting needed |
29
+
30
+ ### Key Design Decisions
31
+
32
+ **1. Agents become skills (not GEMINI.md context)**
33
+
34
+ With 29 agents, dumping them into GEMINI.md would flood every session's context. Instead, agents convert to skills -- Gemini autonomously activates them based on the skill description when relevant. This matches how Claude Code agents are invoked on demand via the Task tool.
35
+
36
+ **2. Commands use TOML format with directory-based namespacing**
37
+
38
+ Gemini CLI commands are `.toml` files where the path determines the command name: `.gemini/commands/git/commit.toml` becomes `/git:commit`. This maps cleanly from Claude Code's colon-namespaced commands (`workflows:plan` -> `.gemini/commands/workflows/plan.toml`).
39
+
40
+ **3. Commands use `{{args}}` placeholder**
41
+
42
+ Gemini's TOML commands support `{{args}}` for argument injection, mapping from Claude Code's `argument-hint` field. Commands with `argument-hint` get `{{args}}` appended to the prompt.
43
+
44
+ **4. MCP servers go into project-level settings.json**
45
+
46
+ Gemini CLI reads MCP config from `.gemini/settings.json` under the `mcpServers` key. The format is compatible -- same `command`, `args`, `env` fields, plus Gemini-specific `cwd`, `timeout`, `trust`, `includeTools`, `excludeTools`.
47
+
48
+ **5. Skills pass through unchanged**
49
+
50
+ Gemini adopted the same SKILL.md standard (YAML frontmatter with `name` and `description`, markdown body). Skills copy directly.
51
+
52
+ ### TOML Command Format
53
+
54
+ ```toml
55
+ description = "Brief description of the command"
56
+ prompt = """
57
+ The prompt content that will be sent to Gemini.
58
+
59
+ User request: {{args}}
60
+ """
61
+ ```
62
+
63
+ - `description` (string): One-line description shown in `/help`
64
+ - `prompt` (string): The prompt sent to the model; supports `{{args}}`, `!{shell}`, `@{file}` placeholders
65
+
66
+ ### Skill (SKILL.md) Format
67
+
68
+ ```yaml
69
+ ---
70
+ name: skill-name
71
+ description: When and how Gemini should use this skill
72
+ ---
73
+
74
+ # Skill Title
75
+
76
+ Detailed instructions...
77
+ ```
78
+
79
+ Identical to Claude Code's format. The `description` field is critical -- Gemini uses it to decide when to activate the skill.
80
+
81
+ ### MCP Server Format (settings.json)
82
+
83
+ ```json
84
+ {
85
+ "mcpServers": {
86
+ "server-name": {
87
+ "command": "npx",
88
+ "args": ["-y", "package-name"],
89
+ "env": { "KEY": "value" }
90
+ }
91
+ }
92
+ }
93
+ ```
94
+
95
+ ## Acceptance Criteria
96
+
97
+ - [x] `bun run src/index.ts convert --to gemini ./plugins/compound-engineering` produces valid Gemini config
98
+ - [x] Agents convert to `.gemini/skills/*/SKILL.md` with populated `description` in frontmatter
99
+ - [x] Commands convert to `.gemini/commands/*.toml` with `prompt` and `description` fields
100
+ - [x] Namespaced commands create directory structure (`workflows:plan` -> `commands/workflows/plan.toml`)
101
+ - [x] Commands with `argument-hint` include `{{args}}` placeholder in prompt
102
+ - [x] Commands with `disable-model-invocation: true` are still included (TOML commands are prompts, not code)
103
+ - [x] Skills copied to `.gemini/skills/` (identical format)
104
+ - [x] MCP servers written to `.gemini/settings.json` under `mcpServers` key
105
+ - [x] Existing `.gemini/settings.json` is backed up before overwrite, and MCP config is merged (not clobbered)
106
+ - [x] Content transformation rewrites `.claude/` and `~/.claude/` paths to `.gemini/` and `~/.gemini/`
107
+ - [x] `/workflows:plan` transformed to `/workflows:plan` (Gemini preserves colon namespacing via directories)
108
+ - [x] `Task agent-name(args)` transformed to `Use the agent-name skill to: args`
109
+ - [x] Plugins with hooks emit `console.warn` about format differences
110
+ - [x] Writer does not double-nest `.gemini/.gemini/`
111
+ - [x] `model` and `allowedTools` fields silently dropped (no Gemini equivalent in skills/commands)
112
+ - [x] Converter and writer tests pass
113
+ - [x] Existing tests still pass (`bun test`)
114
+
115
+ ## Implementation
116
+
117
+ ### Phase 1: Types
118
+
119
+ **Create `src/types/gemini.ts`**
120
+
121
+ ```typescript
122
+ export type GeminiSkill = {
123
+ name: string
124
+ content: string // Full SKILL.md with YAML frontmatter
125
+ }
126
+
127
+ export type GeminiSkillDir = {
128
+ name: string
129
+ sourceDir: string
130
+ }
131
+
132
+ export type GeminiCommand = {
133
+ name: string // e.g. "plan" or "workflows/plan"
134
+ content: string // Full TOML content
135
+ }
136
+
137
+ export type GeminiBundle = {
138
+ generatedSkills: GeminiSkill[] // From agents
139
+ skillDirs: GeminiSkillDir[] // From skills (pass-through)
140
+ commands: GeminiCommand[]
141
+ mcpServers?: Record<string, {
142
+ command?: string
143
+ args?: string[]
144
+ env?: Record<string, string>
145
+ url?: string
146
+ headers?: Record<string, string>
147
+ }>
148
+ }
149
+ ```
150
+
151
+ ### Phase 2: Converter
152
+
153
+ **Create `src/converters/claude-to-gemini.ts`**
154
+
155
+ Core functions:
156
+
157
+ 1. **`convertClaudeToGemini(plugin, options)`** -- main entry point
158
+ - Convert each agent to a skill via `convertAgentToSkill()`
159
+ - Convert each command via `convertCommand()`
160
+ - Pass skills through as directory references
161
+ - Convert MCP servers to settings-compatible object
162
+ - Emit `console.warn` if `plugin.hooks` has entries
163
+
164
+ 2. **`convertAgentToSkill(agent)`** -- agent -> SKILL.md
165
+ - Frontmatter: `name` (from agent name), `description` (from agent description, max ~300 chars)
166
+ - Body: agent body with content transformations applied
167
+ - Prepend capabilities section if present
168
+ - Silently drop `model` field (no Gemini equivalent)
169
+ - If description is empty, generate from agent name: `"Use this skill for ${agent.name} tasks"`
170
+
171
+ 3. **`convertCommand(command, usedNames)`** -- command -> TOML file
172
+ - Preserve namespace structure: `workflows:plan` -> path `workflows/plan`
173
+ - `description` field from command description
174
+ - `prompt` field from command body with content transformations
175
+ - If command has `argument-hint`, append `\n\nUser request: {{args}}` to prompt
176
+ - Body: apply `transformContentForGemini()` transformations
177
+ - Silently drop `allowedTools` (no Gemini equivalent)
178
+
179
+ 4. **`transformContentForGemini(body)`** -- content rewriting
180
+ - `.claude/` -> `.gemini/` and `~/.claude/` -> `~/.gemini/`
181
+ - `Task agent-name(args)` -> `Use the agent-name skill to: args`
182
+ - `@agent-name` references -> `the agent-name skill`
183
+ - Skip file paths (containing `/`) and common non-command patterns
184
+
185
+ 5. **`convertMcpServers(servers)`** -- MCP config
186
+ - Map each `ClaudeMcpServer` entry to Gemini-compatible JSON
187
+ - Pass through: `command`, `args`, `env`, `url`, `headers`
188
+ - Drop `type` field (Gemini infers transport)
189
+
190
+ 6. **`toToml(description, prompt)`** -- TOML serializer
191
+ - Escape TOML strings properly
192
+ - Use multi-line strings (`"""`) for prompt field
193
+ - Simple string for description
194
+
195
+ ### Phase 3: Writer
196
+
197
+ **Create `src/targets/gemini.ts`**
198
+
199
+ Output structure:
200
+
201
+ ```
202
+ .gemini/
203
+ ├── commands/
204
+ │ ├── plan.toml
205
+ │ └── workflows/
206
+ │ └── plan.toml
207
+ ├── skills/
208
+ │ ├── agent-name-1/
209
+ │ │ └── SKILL.md
210
+ │ ├── agent-name-2/
211
+ │ │ └── SKILL.md
212
+ │ └── original-skill/
213
+ │ └── SKILL.md
214
+ └── settings.json (only mcpServers key)
215
+ ```
216
+
217
+ Core function: `writeGeminiBundle(outputRoot, bundle)`
218
+
219
+ - `resolveGeminiPaths(outputRoot)` -- detect if path already ends in `.gemini` to avoid double-nesting (follow droid writer pattern)
220
+ - Write generated skills to `skills/<name>/SKILL.md`
221
+ - Copy original skill directories to `skills/` via `copyDir()`
222
+ - Write commands to `commands/` as `.toml` files, creating subdirectories for namespaced commands
223
+ - Write `settings.json` with `{ "mcpServers": {...} }` via `writeJson()` with `backupFile()` for existing files
224
+ - If settings.json exists, read it first and merge `mcpServers` key (don't clobber other settings)
225
+
226
+ ### Phase 4: Wire into CLI
227
+
228
+ **Modify `src/targets/index.ts`**
229
+
230
+ ```typescript
231
+ import { convertClaudeToGemini } from "../converters/claude-to-gemini"
232
+ import { writeGeminiBundle } from "./gemini"
233
+ import type { GeminiBundle } from "../types/gemini"
234
+
235
+ // Add to targets:
236
+ gemini: {
237
+ name: "gemini",
238
+ implemented: true,
239
+ convert: convertClaudeToGemini as TargetHandler<GeminiBundle>["convert"],
240
+ write: writeGeminiBundle as TargetHandler<GeminiBundle>["write"],
241
+ },
242
+ ```
243
+
244
+ **Modify `src/commands/convert.ts`**
245
+
246
+ - Update `--to` description: `"Target format (opencode | codex | droid | cursor | pi | gemini)"`
247
+ - Add to `resolveTargetOutputRoot`: `if (targetName === "gemini") return path.join(outputRoot, ".gemini")`
248
+
249
+ **Modify `src/commands/install.ts`**
250
+
251
+ - Same two changes as convert.ts
252
+
253
+ ### Phase 5: Tests
254
+
255
+ **Create `tests/gemini-converter.test.ts`**
256
+
257
+ Test cases (use inline `ClaudePlugin` fixtures, following existing converter test patterns):
258
+
259
+ - Agent converts to skill with SKILL.md frontmatter (`name` and `description` populated)
260
+ - Agent with empty description gets default description text
261
+ - Agent with capabilities prepended to body
262
+ - Agent `model` field silently dropped
263
+ - Agent with empty body gets default body text
264
+ - Command converts to TOML with `prompt` and `description` fields
265
+ - Namespaced command creates correct path (`workflows:plan` -> `workflows/plan`)
266
+ - Command with `disable-model-invocation` is still included
267
+ - Command `allowedTools` silently dropped
268
+ - Command with `argument-hint` gets `{{args}}` placeholder in prompt
269
+ - Skills pass through as directory references
270
+ - MCP servers convert to settings.json-compatible config
271
+ - Content transformation: `.claude/` paths -> `.gemini/`
272
+ - Content transformation: `~/.claude/` paths -> `~/.gemini/`
273
+ - Content transformation: `Task agent(args)` -> natural language skill reference
274
+ - Hooks present -> `console.warn` emitted
275
+ - Plugin with zero agents produces empty generatedSkills array
276
+ - Plugin with only skills works correctly
277
+ - TOML output is valid (description and prompt properly escaped)
278
+
279
+ **Create `tests/gemini-writer.test.ts`**
280
+
281
+ Test cases (use temp directories, following existing writer test patterns):
282
+
283
+ - Full bundle writes skills, commands, settings.json
284
+ - Generated skills written as `skills/<name>/SKILL.md`
285
+ - Original skills copied to `skills/` directory
286
+ - Commands written as `.toml` files in `commands/` directory
287
+ - Namespaced commands create subdirectories (`commands/workflows/plan.toml`)
288
+ - MCP config written as valid JSON `settings.json` with `mcpServers` key
289
+ - Existing `settings.json` is backed up before overwrite
290
+ - Output root already ending in `.gemini` does NOT double-nest
291
+ - Empty bundle produces no output
292
+
293
+ ### Phase 6: Documentation
294
+
295
+ **Create `docs/specs/gemini.md`**
296
+
297
+ Document the Gemini CLI spec as reference, following existing `docs/specs/codex.md` pattern:
298
+
299
+ - GEMINI.md context file format
300
+ - Custom commands format (TOML with `prompt`, `description`)
301
+ - Skills format (identical SKILL.md standard)
302
+ - MCP server configuration (`settings.json`)
303
+ - Extensions system (for reference, not converted)
304
+ - Hooks system (for reference, format differences noted)
305
+ - Config file locations (user-level `~/.gemini/` vs project-level `.gemini/`)
306
+ - Directory layout conventions
307
+
308
+ **Update `README.md`**
309
+
310
+ Add `gemini` to the supported targets in the CLI usage section.
311
+
312
+ ## What We're NOT Doing
313
+
314
+ - Not converting hooks (Gemini has hooks but different format -- `BeforeTool`/`AfterTool` with matchers -- warn and skip)
315
+ - Not generating full `settings.json` (only `mcpServers` key -- user-specific settings like `model`, `tools.sandbox` are out of scope)
316
+ - Not creating extensions (extension format is for distributing packages, not for converted plugins)
317
+ - Not using `@{file}` or `!{shell}` placeholders in converted commands (would require analyzing command intent)
318
+ - Not transforming content inside copied SKILL.md files (known limitation -- skills may reference `.claude/` paths internally)
319
+ - Not clearing old output before writing (matches existing target behavior)
320
+ - Not merging into existing settings.json intelligently beyond `mcpServers` key (too risky to modify user config)
321
+
322
+ ## Complexity Assessment
323
+
324
+ This is a **medium change**. The converter architecture is well-established with five existing targets, so this is mostly pattern-following. The key novelties are:
325
+
326
+ 1. The TOML command format (unique among all targets -- need simple TOML serializer)
327
+ 2. Agents map to skills rather than a direct 1:1 concept (but this is the same pattern as codex)
328
+ 3. Namespaced commands use directory structure (new approach vs flattening in cursor/codex)
329
+ 4. MCP config goes into a broader `settings.json` file (need to merge, not clobber)
330
+
331
+ Skills being identical across platforms simplifies things significantly. The TOML serialization is simple (only two fields: `description` string and `prompt` multi-line string).
332
+
333
+ ## References
334
+
335
+ - [Gemini CLI Repository](https://github.com/google-gemini/gemini-cli)
336
+ - [Gemini CLI Configuration](https://geminicli.com/docs/get-started/configuration/)
337
+ - [Custom Commands (TOML)](https://geminicli.com/docs/cli/custom-commands/)
338
+ - [Agent Skills](https://geminicli.com/docs/cli/skills/)
339
+ - [Creating Skills](https://geminicli.com/docs/cli/creating-skills/)
340
+ - [Extensions](https://geminicli.com/docs/extensions/writing-extensions/)
341
+ - [MCP Servers](https://google-gemini.github.io/gemini-cli/docs/tools/mcp-server.html)
342
+ - Existing cursor plan: `docs/plans/2026-02-12-feat-add-cursor-cli-target-provider-plan.md`
343
+ - Existing codex converter: `src/converters/claude-to-codex.ts` (has `uniqueName()` and skill generation patterns)
344
+ - Existing droid writer: `src/targets/droid.ts` (has double-nesting guard pattern)
345
+ - Target registry: `src/targets/index.ts`
346
+
347
+ ## Completion Summary
348
+
349
+ ### What Was Delivered
350
+ - [x] Phase 1: Types (`src/types/gemini.ts`)
351
+ - [x] Phase 2: Converter (`src/converters/claude-to-gemini.ts`)
352
+ - [x] Phase 3: Writer (`src/targets/gemini.ts`)
353
+ - [x] Phase 4: CLI wiring (`src/targets/index.ts`, `src/commands/convert.ts`, `src/commands/install.ts`)
354
+ - [x] Phase 5: Tests (`tests/gemini-converter.test.ts`, `tests/gemini-writer.test.ts`)
355
+ - [x] Phase 6: Documentation (`docs/specs/gemini.md`, `README.md`)
356
+
357
+ ### Implementation Statistics
358
+ - 10 files changed
359
+ - 27 new tests added (129 total, all passing)
360
+ - 148 output files generated from compound-engineering plugin conversion
361
+ - 0 dependencies added
362
+
363
+ ### Git Commits
364
+ - `201ad6d` feat(gemini): add Gemini CLI as sixth target provider
365
+ - `8351851` docs: add Gemini CLI spec and update README with gemini target
366
+
367
+ ### Completion Details
368
+ - **Completed By:** Claude Opus 4.6
369
+ - **Date:** 2026-02-14
370
+ - **Session:** Single session
@@ -0,0 +1,122 @@
1
+ # Gemini CLI Spec (GEMINI.md, Commands, Skills, MCP, Settings)
2
+
3
+ Last verified: 2026-02-14
4
+
5
+ ## Primary sources
6
+
7
+ ```
8
+ https://github.com/google-gemini/gemini-cli
9
+ https://geminicli.com/docs/get-started/configuration/
10
+ https://geminicli.com/docs/cli/custom-commands/
11
+ https://geminicli.com/docs/cli/skills/
12
+ https://geminicli.com/docs/cli/creating-skills/
13
+ https://geminicli.com/docs/extensions/writing-extensions/
14
+ https://google-gemini.github.io/gemini-cli/docs/tools/mcp-server.html
15
+ ```
16
+
17
+ ## Config locations
18
+
19
+ - User-level config: `~/.gemini/settings.json`
20
+ - Project-level config: `.gemini/settings.json`
21
+ - Project-level takes precedence over user-level for most settings.
22
+ - GEMINI.md context file lives at project root (similar to CLAUDE.md).
23
+
24
+ ## GEMINI.md context file
25
+
26
+ - A markdown file at project root loaded into every session's context.
27
+ - Used for project-wide instructions, coding standards, and conventions.
28
+ - Equivalent to Claude Code's CLAUDE.md.
29
+
30
+ ## Custom commands (TOML format)
31
+
32
+ - Custom commands are TOML files stored in `.gemini/commands/`.
33
+ - Command name is derived from the file path: `.gemini/commands/git/commit.toml` becomes `/git:commit`.
34
+ - Directory-based namespacing: subdirectories create namespaced commands.
35
+ - Each command file has two fields:
36
+ - `description` (string): One-line description shown in `/help`
37
+ - `prompt` (string): The prompt sent to the model
38
+ - Supports placeholders:
39
+ - `{{args}}` — user-provided arguments
40
+ - `!{shell}` — output of a shell command
41
+ - `@{file}` — contents of a file
42
+ - Example:
43
+
44
+ ```toml
45
+ description = "Create a git commit with a good message"
46
+ prompt = """
47
+ Look at the current git diff and create a commit with a descriptive message.
48
+
49
+ User request: {{args}}
50
+ """
51
+ ```
52
+
53
+ ## Skills (SKILL.md standard)
54
+
55
+ - A skill is a folder containing `SKILL.md` plus optional supporting files.
56
+ - Skills live in `.gemini/skills/`.
57
+ - `SKILL.md` uses YAML frontmatter with `name` and `description` fields.
58
+ - Gemini activates skills on demand via `activate_skill` tool based on description matching.
59
+ - The `description` field is critical — Gemini uses it to decide when to activate the skill.
60
+ - Format is identical to Claude Code's SKILL.md standard.
61
+ - Example:
62
+
63
+ ```yaml
64
+ ---
65
+ name: security-reviewer
66
+ description: Review code for security vulnerabilities and OWASP compliance
67
+ ---
68
+
69
+ # Security Reviewer
70
+
71
+ Detailed instructions for security review...
72
+ ```
73
+
74
+ ## MCP server configuration
75
+
76
+ - MCP servers are configured in `settings.json` under the `mcpServers` key.
77
+ - Same MCP protocol as Claude Code; different config location.
78
+ - Supports `command`, `args`, `env` for stdio transport.
79
+ - Supports `url`, `headers` for HTTP/SSE transport.
80
+ - Additional Gemini-specific fields: `cwd`, `timeout`, `trust`, `includeTools`, `excludeTools`.
81
+ - Example:
82
+
83
+ ```json
84
+ {
85
+ "mcpServers": {
86
+ "context7": {
87
+ "url": "https://mcp.context7.com/mcp"
88
+ },
89
+ "playwright": {
90
+ "command": "npx",
91
+ "args": ["-y", "@anthropic/mcp-playwright"]
92
+ }
93
+ }
94
+ }
95
+ ```
96
+
97
+ ## Hooks
98
+
99
+ - Gemini supports hooks: `BeforeTool`, `AfterTool`, `SessionStart`, etc.
100
+ - Hooks use a different format from Claude Code hooks (matchers-based).
101
+ - Not converted by the plugin converter — a warning is emitted.
102
+
103
+ ## Extensions
104
+
105
+ - Extensions are distributable packages for Gemini CLI.
106
+ - They extend functionality with custom tools, hooks, and commands.
107
+ - Not used for plugin conversion (different purpose from Claude Code plugins).
108
+
109
+ ## Settings.json structure
110
+
111
+ ```json
112
+ {
113
+ "model": "gemini-2.5-pro",
114
+ "mcpServers": { ... },
115
+ "tools": {
116
+ "sandbox": true
117
+ }
118
+ }
119
+ ```
120
+
121
+ - Only the `mcpServers` key is written during plugin conversion.
122
+ - Other settings (model, tools, sandbox) are user-specific and out of scope.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@every-env/compound-plugin",
3
- "version": "0.5.1",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "compound-engineering",
3
- "version": "2.33.0",
3
+ "version": "2.34.0",
4
4
  "description": "AI-powered development tools. 29 agents, 22 commands, 19 skills, 1 MCP server for code review, research, design, and workflow automation.",
5
5
  "author": {
6
6
  "name": "Kieran Klaassen",
@@ -5,6 +5,23 @@ All notable changes to the compound-engineering plugin will be documented in thi
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [2.34.0] - 2026-02-14
9
+
10
+ ### Added
11
+
12
+ - **Gemini CLI target** — New converter target for [Gemini CLI](https://github.com/google-gemini/gemini-cli). Install with `--to gemini` to convert agents to `.gemini/skills/*/SKILL.md`, commands to `.gemini/commands/*.toml` (TOML format with `description` + `prompt`), and MCP servers to `.gemini/settings.json`. Skills pass through unchanged (identical SKILL.md standard). Namespaced commands create directory structure (`workflows:plan` → `commands/workflows/plan.toml`). 29 new tests. ([#190](https://github.com/EveryInc/compound-engineering-plugin/pull/190))
13
+
14
+ ---
15
+
16
+ ## [2.33.1] - 2026-02-13
17
+
18
+ ### Changed
19
+
20
+ - **`/workflows:plan` command** - All plan templates now include `status: active` in YAML frontmatter. Plans are created with `status: active` and marked `status: completed` when work finishes.
21
+ - **`/workflows:work` command** - Phase 4 now updates plan frontmatter from `status: active` to `status: completed` after shipping. Agents can grep for status to distinguish current vs historical plans.
22
+
23
+ ---
24
+
8
25
  ## [2.33.0] - 2026-02-12
9
26
 
10
27
  ### Added
@@ -178,6 +178,7 @@ Select how comprehensive you want the issue to be, simpler is mostly better.
178
178
  ---
179
179
  title: [Issue Title]
180
180
  type: [feat|fix|refactor]
181
+ status: active
181
182
  date: YYYY-MM-DD
182
183
  ---
183
184
 
@@ -230,6 +231,7 @@ end
230
231
  ---
231
232
  title: [Issue Title]
232
233
  type: [feat|fix|refactor]
234
+ status: active
233
235
  date: YYYY-MM-DD
234
236
  ---
235
237
 
@@ -294,6 +296,7 @@ date: YYYY-MM-DD
294
296
  ---
295
297
  title: [Issue Title]
296
298
  type: [feat|fix|refactor]
299
+ status: active
297
300
  date: YYYY-MM-DD
298
301
  ---
299
302
 
@@ -297,7 +297,14 @@ This command takes a work document (plan, specification, or todo file) and execu
297
297
  )"
298
298
  ```
299
299
 
300
- 4. **Notify User**
300
+ 4. **Update Plan Status**
301
+
302
+ If the input document has YAML frontmatter with a `status` field, update it to `completed`:
303
+ ```
304
+ status: active → status: completed
305
+ ```
306
+
307
+ 5. **Notify User**
301
308
  - Summarize what was completed
302
309
  - Link to PR
303
310
  - Note any follow-up work needed