@every-env/compound-plugin 0.8.0 → 0.12.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 (93) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/AGENTS.md +5 -1
  3. package/CHANGELOG.md +50 -0
  4. package/CLAUDE.md +3 -3
  5. package/README.md +52 -14
  6. package/docs/plans/2026-02-14-feat-auto-detect-install-and-gemini-sync-plan.md +360 -0
  7. package/docs/plans/2026-02-25-feat-windsurf-global-scope-support-plan.md +627 -0
  8. package/docs/plans/2026-03-01-feat-ce-command-aliases-backwards-compatible-deprecation-plan.md +261 -0
  9. package/docs/plans/feature_opencode-commands-as-md-and-config-merge.md +574 -0
  10. package/docs/solutions/adding-converter-target-providers.md +692 -0
  11. package/docs/solutions/plugin-versioning-requirements.md +3 -3
  12. package/docs/specs/kiro.md +171 -0
  13. package/docs/specs/windsurf.md +477 -0
  14. package/package.json +1 -1
  15. package/plans/landing-page-launchkit-refresh.md +2 -2
  16. package/plugins/compound-engineering/.claude-plugin/plugin.json +2 -2
  17. package/plugins/compound-engineering/CHANGELOG.md +72 -1
  18. package/plugins/compound-engineering/CLAUDE.md +9 -7
  19. package/plugins/compound-engineering/README.md +10 -7
  20. package/plugins/compound-engineering/agents/research/git-history-analyzer.md +1 -1
  21. package/plugins/compound-engineering/agents/research/learnings-researcher.md +1 -1
  22. package/plugins/compound-engineering/agents/review/code-simplicity-reviewer.md +1 -1
  23. package/plugins/compound-engineering/commands/ce/brainstorm.md +145 -0
  24. package/plugins/compound-engineering/commands/ce/compound.md +240 -0
  25. package/plugins/compound-engineering/commands/ce/plan.md +636 -0
  26. package/plugins/compound-engineering/commands/ce/review.md +525 -0
  27. package/plugins/compound-engineering/commands/ce/work.md +470 -0
  28. package/plugins/compound-engineering/commands/create-agent-skill.md +1 -1
  29. package/plugins/compound-engineering/commands/deepen-plan.md +6 -6
  30. package/plugins/compound-engineering/commands/deploy-docs.md +1 -1
  31. package/plugins/compound-engineering/commands/feature-video.md +15 -6
  32. package/plugins/compound-engineering/commands/heal-skill.md +1 -1
  33. package/plugins/compound-engineering/commands/lfg.md +3 -3
  34. package/plugins/compound-engineering/commands/slfg.md +3 -3
  35. package/plugins/compound-engineering/commands/test-xcode.md +2 -2
  36. package/plugins/compound-engineering/commands/workflows/brainstorm.md +4 -123
  37. package/plugins/compound-engineering/commands/workflows/compound.md +4 -234
  38. package/plugins/compound-engineering/commands/workflows/plan.md +4 -562
  39. package/plugins/compound-engineering/commands/workflows/review.md +4 -522
  40. package/plugins/compound-engineering/commands/workflows/work.md +4 -448
  41. package/plugins/compound-engineering/skills/brainstorming/SKILL.md +3 -3
  42. package/plugins/compound-engineering/skills/document-review/SKILL.md +1 -1
  43. package/plugins/compound-engineering/skills/file-todos/SKILL.md +1 -1
  44. package/plugins/compound-engineering/skills/git-worktree/SKILL.md +5 -5
  45. package/plugins/compound-engineering/skills/proof/SKILL.md +185 -0
  46. package/plugins/compound-engineering/skills/resolve-pr-parallel/SKILL.md +1 -1
  47. package/plugins/compound-engineering/skills/setup/SKILL.md +2 -2
  48. package/src/commands/convert.ts +101 -23
  49. package/src/commands/install.ts +102 -41
  50. package/src/commands/sync.ts +58 -38
  51. package/src/converters/claude-to-kiro.ts +262 -0
  52. package/src/converters/claude-to-openclaw.ts +240 -0
  53. package/src/converters/claude-to-opencode.ts +12 -10
  54. package/src/converters/claude-to-qwen.ts +238 -0
  55. package/src/converters/claude-to-windsurf.ts +205 -0
  56. package/src/sync/gemini.ts +76 -0
  57. package/src/targets/index.ts +69 -1
  58. package/src/targets/kiro.ts +122 -0
  59. package/src/targets/openclaw.ts +96 -0
  60. package/src/targets/opencode.ts +76 -10
  61. package/src/targets/qwen.ts +64 -0
  62. package/src/targets/windsurf.ts +104 -0
  63. package/src/types/kiro.ts +44 -0
  64. package/src/types/openclaw.ts +52 -0
  65. package/src/types/opencode.ts +7 -8
  66. package/src/types/qwen.ts +48 -0
  67. package/src/types/windsurf.ts +34 -0
  68. package/src/utils/detect-tools.ts +46 -0
  69. package/src/utils/files.ts +7 -0
  70. package/src/utils/resolve-output.ts +50 -0
  71. package/src/utils/secrets.ts +24 -0
  72. package/tests/cli.test.ts +78 -0
  73. package/tests/converter.test.ts +43 -10
  74. package/tests/detect-tools.test.ts +96 -0
  75. package/tests/kiro-converter.test.ts +381 -0
  76. package/tests/kiro-writer.test.ts +273 -0
  77. package/tests/openclaw-converter.test.ts +200 -0
  78. package/tests/opencode-writer.test.ts +142 -5
  79. package/tests/qwen-converter.test.ts +238 -0
  80. package/tests/resolve-output.test.ts +131 -0
  81. package/tests/sync-gemini.test.ts +106 -0
  82. package/tests/windsurf-converter.test.ts +573 -0
  83. package/tests/windsurf-writer.test.ts +359 -0
  84. package/docs/css/docs.css +0 -675
  85. package/docs/css/style.css +0 -2886
  86. package/docs/index.html +0 -1046
  87. package/docs/js/main.js +0 -225
  88. package/docs/pages/agents.html +0 -649
  89. package/docs/pages/changelog.html +0 -534
  90. package/docs/pages/commands.html +0 -523
  91. package/docs/pages/getting-started.html +0 -582
  92. package/docs/pages/mcp-servers.html +0 -409
  93. package/docs/pages/skills.html +0 -611
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "every-marketplace",
2
+ "name": "compound-engineering-plugin",
3
3
  "owner": {
4
4
  "name": "Kieran Klaassen",
5
5
  "url": "https://github.com/kieranklaassen"
@@ -11,8 +11,8 @@
11
11
  "plugins": [
12
12
  {
13
13
  "name": "compound-engineering",
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.34.0",
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 20 skills.",
15
+ "version": "2.38.0",
16
16
  "author": {
17
17
  "name": "Kieran Klaassen",
18
18
  "url": "https://github.com/kieranklaassen",
package/AGENTS.md CHANGED
@@ -7,7 +7,7 @@ This repository contains a Bun/TypeScript CLI that converts Claude Code plugins
7
7
  - **Branching:** Create a feature branch for any non-trivial change. If already on the correct branch for the task, keep using it; do not create additional branches or worktrees unless explicitly requested.
8
8
  - **Safety:** Do not delete or overwrite user data. Avoid destructive commands.
9
9
  - **Testing:** Run `bun test` after changes that affect parsing, conversion, or output.
10
- - **Output Paths:** Keep OpenCode output at `opencode.json` and `.opencode/{agents,skills,plugins}`.
10
+ - **Output Paths:** Keep OpenCode output at `opencode.json` and `.opencode/{agents,skills,plugins}`. For OpenCode, command go to `~/.config/opencode/commands/<name>.md`; `opencode.json` is deep-merged (never overwritten wholesale).
11
11
  - **ASCII-first:** Use ASCII unless the file already contains Unicode.
12
12
 
13
13
  ## Adding a New Target Provider (e.g., Codex)
@@ -46,3 +46,7 @@ Add a new provider when at least one of these is true:
46
46
  - You can write fixtures + tests that validate the mapping.
47
47
 
48
48
  Avoid adding a provider if the target spec is unstable or undocumented.
49
+
50
+ ## Repository Docs Convention
51
+
52
+ - **Plans** live in `docs/plans/` and track implementation progress.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,56 @@ All notable changes to the `@every-env/compound-plugin` CLI tool will be documen
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
+ ## [0.12.0] - 2026-03-01
9
+
10
+ ### Added
11
+
12
+ - **Auto-detect install targets** — `install --to all` and `convert --to all` auto-detect installed AI coding tools and install to all of them in one command
13
+ - **Gemini sync** — `sync --target gemini` symlinks personal skills to `.gemini/skills/` and merges MCP servers into `.gemini/settings.json`
14
+ - **Sync all targets** — `sync --target all` syncs personal config to all detected tools
15
+ - **Tool detection utility** — Checks config directories for OpenCode, Codex, Droid, Cursor, Pi, and Gemini
16
+
17
+ ---
18
+
19
+ ## [0.11.0] - 2026-03-01
20
+
21
+ ### Added
22
+
23
+ - **OpenClaw target** — `--to openclaw` converts plugins to OpenClaw format. Agents become `.md` files, commands become `.md` files, pass-through skills copy unchanged, and MCP servers are written to `openclaw-extension.json`. Output goes to `~/.openclaw/extensions/<plugin-name>/` by default. Use `--openclaw-home` to override. ([#217](https://github.com/EveryInc/compound-engineering-plugin/pull/217)) — thanks [@TrendpilotAI](https://github.com/TrendpilotAI)!
24
+ - **Qwen Code target** — `--to qwen` converts plugins to Qwen Code extension format. Agents become `.yaml` files with Qwen-compatible fields, commands become `.md` files, MCP servers write to `qwen-extension.json`, and a `QWEN.md` context file is generated. Output goes to `~/.qwen/extensions/<plugin-name>/` by default. Use `--qwen-home` to override. ([#220](https://github.com/EveryInc/compound-engineering-plugin/pull/220)) — thanks [@rlam3](https://github.com/rlam3)!
25
+ - **Windsurf target** — `--to windsurf` converts plugins to Windsurf format. Claude agents become Windsurf skills (`skills/{name}/SKILL.md`), commands become flat workflows (`global_workflows/{name}.md` for global scope, `workflows/{name}.md` for workspace), and pass-through skills copy unchanged. MCP servers write to `mcp_config.json` (machine-readable, merged with existing config). ([#202](https://github.com/EveryInc/compound-engineering-plugin/pull/202)) — thanks [@rburnham52](https://github.com/rburnham52)!
26
+ - **Global scope support** — New `--scope global|workspace` flag (generic, Windsurf as first adopter). `--to windsurf` defaults to global scope (`~/.codeium/windsurf/`), making installed skills, workflows, and MCP servers available across all projects. Use `--scope workspace` for project-level `.windsurf/` output.
27
+ - **`mcp_config.json` integration** — Windsurf converter writes proper machine-readable MCP config supporting stdio, Streamable HTTP, and SSE transports. Merges with existing config (user entries preserved, plugin entries take precedence). Written with `0o600` permissions.
28
+ - **Shared utilities** — Extracted `resolveTargetOutputRoot` to `src/utils/resolve-output.ts` and `hasPotentialSecrets` to `src/utils/secrets.ts` to eliminate duplication.
29
+
30
+ ### Fixed
31
+
32
+ - **OpenClaw code injection** — `generateEntryPoint` now uses `JSON.stringify()` for all string interpolation (was escaping only `"`, leaving `\n`/`\\` unguarded).
33
+ - **Qwen `plugin.manifest.name`** — context file header was `# undefined` due to using `plugin.name` (which doesn't exist on `ClaudePlugin`); fixed to `plugin.manifest.name`.
34
+ - **Qwen remote MCP servers** — curl fallback removed; HTTP/SSE servers are now skipped with a warning (Qwen only supports stdio transport).
35
+ - **`--openclaw-home` / `--qwen-home` CLI flags** — wired through to `resolveTargetOutputRoot` so custom home directories are respected.
36
+
37
+ ---
38
+
39
+ ## [0.9.1] - 2026-02-20
40
+
41
+ ### Changed
42
+
43
+ - **Remove docs/reports and docs/decisions directories** — only `docs/plans/` is retained as living documents that track implementation progress
44
+ - **OpenCode commands as Markdown** — commands are now `.md` files with deep-merged config, permissions default to none ([#201](https://github.com/EveryInc/compound-engineering-plugin/pull/201)) — thanks [@0ut5ider](https://github.com/0ut5ider)!
45
+ - **Fix changelog GitHub link** ([#215](https://github.com/EveryInc/compound-engineering-plugin/pull/215)) — thanks [@XSAM](https://github.com/XSAM)!
46
+ - **Update Claude Code install command in README** ([#218](https://github.com/EveryInc/compound-engineering-plugin/pull/218)) — thanks [@ianguelman](https://github.com/ianguelman)!
47
+
48
+ ---
49
+
50
+ ## [0.9.0] - 2026-02-17
51
+
52
+ ### Added
53
+
54
+ - **Kiro CLI target** — `--to kiro` converts plugins to `.kiro/` format with custom agent JSON configs, prompt files, skills, steering files, and `mcp.json`. Only stdio MCP servers are supported ([#196](https://github.com/EveryInc/compound-engineering-plugin/pull/196)) — thanks [@krthr](https://github.com/krthr)!
55
+
56
+ ---
57
+
8
58
  ## [0.8.0] - 2026-02-17
9
59
 
10
60
  ### Added
package/CLAUDE.md CHANGED
@@ -1,11 +1,11 @@
1
- # Every Marketplace - Claude Code Plugin Marketplace
1
+ # compound-engineering-plugin - Claude Code Plugin Marketplace
2
2
 
3
3
  This repository is a Claude Code plugin marketplace that distributes the `compound-engineering` plugin to developers building with AI-powered tools.
4
4
 
5
5
  ## Repository Structure
6
6
 
7
7
  ```
8
- every-marketplace/
8
+ compound-engineering-plugin/
9
9
  ├── .claude-plugin/
10
10
  │ └── marketplace.json # Marketplace catalog (lists available plugins)
11
11
  ├── docs/ # Documentation site (GitHub Pages)
@@ -261,7 +261,7 @@ python -m http.server 8000
261
261
  1. Install the marketplace locally:
262
262
 
263
263
  ```bash
264
- claude /plugin marketplace add /Users/yourusername/every-marketplace
264
+ claude /plugin marketplace add /Users/yourusername/compound-engineering-plugin
265
265
  ```
266
266
 
267
267
  2. Install the plugin:
package/README.md CHANGED
@@ -8,7 +8,7 @@ A Claude Code plugin marketplace featuring the **Compound Engineering Plugin**
8
8
  ## Claude Code Install
9
9
 
10
10
  ```bash
11
- /plugin marketplace add https://github.com/EveryInc/compound-engineering-plugin
11
+ /plugin marketplace add EveryInc/compound-engineering-plugin
12
12
  /plugin install compound-engineering
13
13
  ```
14
14
 
@@ -18,9 +18,9 @@ A Claude Code plugin marketplace featuring the **Compound Engineering Plugin**
18
18
  /add-plugin compound-engineering
19
19
  ```
20
20
 
21
- ## OpenCode, Codex, Droid, Pi, Gemini & GitHub Copilot (experimental) Install
21
+ ## OpenCode, Codex, Droid, Pi, Gemini, Copilot, Kiro, Windsurf, OpenClaw & Qwen (experimental) Install
22
22
 
23
- This repo includes a Bun/TypeScript CLI that converts Claude Code plugins to OpenCode, Codex, Factory Droid, Pi, Gemini CLI and GitHub Copilot.
23
+ This repo includes a Bun/TypeScript CLI that converts Claude Code plugins to OpenCode, Codex, Factory Droid, Pi, Gemini CLI, GitHub Copilot, Kiro CLI, Windsurf, OpenClaw, and Qwen Code.
24
24
 
25
25
  ```bash
26
26
  # convert the compound-engineering plugin into OpenCode format
@@ -40,6 +40,24 @@ bunx @every-env/compound-plugin install compound-engineering --to gemini
40
40
 
41
41
  # convert to GitHub Copilot format
42
42
  bunx @every-env/compound-plugin install compound-engineering --to copilot
43
+
44
+ # convert to Kiro CLI format
45
+ bunx @every-env/compound-plugin install compound-engineering --to kiro
46
+
47
+ # convert to OpenClaw format
48
+ bunx @every-env/compound-plugin install compound-engineering --to openclaw
49
+
50
+ # convert to Windsurf format (global scope by default)
51
+ bunx @every-env/compound-plugin install compound-engineering --to windsurf
52
+
53
+ # convert to Windsurf workspace scope
54
+ bunx @every-env/compound-plugin install compound-engineering --to windsurf --scope workspace
55
+
56
+ # convert to Qwen Code format
57
+ bunx @every-env/compound-plugin install compound-engineering --to qwen
58
+
59
+ # auto-detect installed tools and install to all
60
+ bunx @every-env/compound-plugin install compound-engineering --to all
43
61
  ```
44
62
 
45
63
  Local dev:
@@ -48,20 +66,34 @@ Local dev:
48
66
  bun run src/index.ts install ./plugins/compound-engineering --to opencode
49
67
  ```
50
68
 
51
- OpenCode output is written to `~/.config/opencode` by default, with `opencode.json` at the root and `agents/`, `skills/`, and `plugins/` alongside it.
52
- 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).
53
- 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.
54
- Pi output is written to `~/.pi/agent/` by default with prompts, skills, extensions, and `compound-engineering/mcporter.json` for MCPorter interoperability.
55
- 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.
56
- Copilot output is written to `.github/` with agents (`.agent.md`), skills (`SKILL.md`), and `copilot-mcp-config.json`. Agents get Copilot frontmatter (`description`, `tools: ["*"]`, `infer: true`), commands are converted to agent skills, and MCP server env vars are prefixed with `COPILOT_MCP_`.
69
+ <details>
70
+ <summary>Output format details per target</summary>
71
+
72
+ | Target | Output path | Notes |
73
+ |--------|------------|-------|
74
+ | `opencode` | `~/.config/opencode/` | Commands as `.md` files; `opencode.json` MCP config deep-merged; backups made before overwriting |
75
+ | `codex` | `~/.codex/prompts` + `~/.codex/skills` | Each command becomes a prompt + skill pair; descriptions truncated to 1024 chars |
76
+ | `droid` | `~/.factory/` | Tool names mapped (`Bash`→`Execute`, `Write`→`Create`); namespace prefixes stripped |
77
+ | `pi` | `~/.pi/agent/` | Prompts, skills, extensions, and `mcporter.json` for MCPorter interoperability |
78
+ | `gemini` | `.gemini/` | Skills from agents; commands as `.toml`; namespaced commands become directories (`workflows:plan` → `commands/workflows/plan.toml`) |
79
+ | `copilot` | `.github/` | Agents as `.agent.md` with Copilot frontmatter; MCP env vars prefixed with `COPILOT_MCP_` |
80
+ | `kiro` | `.kiro/` | Agents as JSON configs + prompt `.md` files; only stdio MCP servers supported |
81
+ | `openclaw` | `~/.openclaw/extensions/<plugin>/` | Entry-point TypeScript skill file; `openclaw-extension.json` for MCP servers |
82
+ | `windsurf` | `~/.codeium/windsurf/` (global) or `.windsurf/` (workspace) | Agents become skills; commands become flat workflows; `mcp_config.json` merged |
83
+ | `qwen` | `~/.qwen/extensions/<plugin>/` | Agents as `.yaml`; env vars with placeholders extracted as settings; colon separator for nested commands |
57
84
 
58
85
  All provider targets are experimental and may change as the formats evolve.
59
86
 
87
+ </details>
88
+
60
89
  ## Sync Personal Config
61
90
 
62
- Sync your personal Claude Code config (`~/.claude/`) to other AI coding tools:
91
+ Sync your personal Claude Code config (`~/.claude/`) to other AI coding tools. Omit `--target` to sync to all detected tools automatically:
63
92
 
64
93
  ```bash
94
+ # Sync to all detected tools (default)
95
+ bunx @every-env/compound-plugin sync
96
+
65
97
  # Sync skills and MCP servers to OpenCode
66
98
  bunx @every-env/compound-plugin sync --target opencode
67
99
 
@@ -76,6 +108,12 @@ bunx @every-env/compound-plugin sync --target droid
76
108
 
77
109
  # Sync to GitHub Copilot (skills + MCP servers)
78
110
  bunx @every-env/compound-plugin sync --target copilot
111
+
112
+ # Sync to Gemini (skills + MCP servers)
113
+ bunx @every-env/compound-plugin sync --target gemini
114
+
115
+ # Sync to all detected tools
116
+ bunx @every-env/compound-plugin sync --target all
79
117
  ```
80
118
 
81
119
  This syncs:
@@ -92,10 +130,10 @@ Plan → Work → Review → Compound → Repeat
92
130
 
93
131
  | Command | Purpose |
94
132
  |---------|---------|
95
- | `/workflows:plan` | Turn feature ideas into detailed implementation plans |
96
- | `/workflows:work` | Execute plans with worktrees and task tracking |
97
- | `/workflows:review` | Multi-agent code review before merging |
98
- | `/workflows:compound` | Document learnings to make future work easier |
133
+ | `/ce:plan` | Turn feature ideas into detailed implementation plans |
134
+ | `/ce:work` | Execute plans with worktrees and task tracking |
135
+ | `/ce:review` | Multi-agent code review before merging |
136
+ | `/ce:compound` | Document learnings to make future work easier |
99
137
 
100
138
  Each cycle compounds: plans inform future plans, reviews catch more issues, patterns get documented.
101
139
 
@@ -0,0 +1,360 @@
1
+ ---
2
+ title: Auto-detect install targets and add Gemini sync
3
+ type: feat
4
+ status: completed
5
+ date: 2026-02-14
6
+ completed_date: 2026-02-14
7
+ completed_by: "Claude Opus 4.6"
8
+ actual_effort: "Completed in one session"
9
+ ---
10
+
11
+ # Auto-detect Install Targets and Add Gemini Sync
12
+
13
+ ## Overview
14
+
15
+ Two related improvements to the converter CLI:
16
+
17
+ 1. **`install --to all`** — Auto-detect which AI coding tools are installed and convert to all of them in one command
18
+ 2. **`sync --target gemini`** — Add Gemini CLI as a sync target (currently missing), then add `sync --target all` to sync personal config to every detected tool
19
+
20
+ ## Problem Statement
21
+
22
+ Users currently must run 6 separate commands to install to all targets:
23
+
24
+ ```bash
25
+ bunx @every-env/compound-plugin install compound-engineering --to opencode
26
+ bunx @every-env/compound-plugin install compound-engineering --to codex
27
+ bunx @every-env/compound-plugin install compound-engineering --to droid
28
+ bunx @every-env/compound-plugin install compound-engineering --to cursor
29
+ bunx @every-env/compound-plugin install compound-engineering --to pi
30
+ bunx @every-env/compound-plugin install compound-engineering --to gemini
31
+ ```
32
+
33
+ Similarly, sync requires separate commands per target. And Gemini sync doesn't exist yet.
34
+
35
+ ## Acceptance Criteria
36
+
37
+ ### Auto-detect install
38
+
39
+ - [x]`install --to all` detects installed tools and installs to each
40
+ - [x]Detection checks config directories and/or binaries for each tool
41
+ - [x]Prints which tools were detected and which were skipped
42
+ - [x]Tools with no detection signal are skipped (not errored)
43
+ - [x]`convert --to all` also works (same detection logic)
44
+ - [x]Existing `--to <target>` behavior unchanged
45
+ - [x]Tests for detection logic and `all` target handling
46
+
47
+ ### Gemini sync
48
+
49
+ - [x]`sync --target gemini` symlinks skills and writes MCP servers to `.gemini/settings.json`
50
+ - [x]MCP servers merged into existing `settings.json` (same pattern as writer)
51
+ - [x]`gemini` added to `validTargets` in `sync.ts`
52
+ - [x]Tests for Gemini sync
53
+
54
+ ### Sync all
55
+
56
+ - [x]`sync --target all` syncs to all detected tools
57
+ - [x]Reuses same detection logic as install
58
+ - [x]Prints summary of what was synced where
59
+
60
+ ## Implementation
61
+
62
+ ### Phase 1: Tool Detection Utility
63
+
64
+ **Create `src/utils/detect-tools.ts`**
65
+
66
+ ```typescript
67
+ import os from "os"
68
+ import path from "path"
69
+ import { pathExists } from "./files"
70
+
71
+ export type DetectedTool = {
72
+ name: string
73
+ detected: boolean
74
+ reason: string // e.g. "found ~/.codex/" or "not found"
75
+ }
76
+
77
+ export async function detectInstalledTools(): Promise<DetectedTool[]> {
78
+ const home = os.homedir()
79
+ const cwd = process.cwd()
80
+
81
+ const checks: Array<{ name: string; paths: string[] }> = [
82
+ { name: "opencode", paths: [path.join(home, ".config", "opencode"), path.join(cwd, ".opencode")] },
83
+ { name: "codex", paths: [path.join(home, ".codex")] },
84
+ { name: "droid", paths: [path.join(home, ".factory")] },
85
+ { name: "cursor", paths: [path.join(cwd, ".cursor"), path.join(home, ".cursor")] },
86
+ { name: "pi", paths: [path.join(home, ".pi")] },
87
+ { name: "gemini", paths: [path.join(cwd, ".gemini"), path.join(home, ".gemini")] },
88
+ ]
89
+
90
+ const results: DetectedTool[] = []
91
+ for (const check of checks) {
92
+ let detected = false
93
+ let reason = "not found"
94
+ for (const p of check.paths) {
95
+ if (await pathExists(p)) {
96
+ detected = true
97
+ reason = `found ${p}`
98
+ break
99
+ }
100
+ }
101
+ results.push({ name: check.name, detected, reason })
102
+ }
103
+ return results
104
+ }
105
+
106
+ export async function getDetectedTargetNames(): Promise<string[]> {
107
+ const tools = await detectInstalledTools()
108
+ return tools.filter((t) => t.detected).map((t) => t.name)
109
+ }
110
+ ```
111
+
112
+ **Detection heuristics:**
113
+
114
+ | Tool | Check paths | Notes |
115
+ |------|------------|-------|
116
+ | OpenCode | `~/.config/opencode/`, `.opencode/` | XDG config or project-local |
117
+ | Codex | `~/.codex/` | Global only |
118
+ | Droid | `~/.factory/` | Global only |
119
+ | Cursor | `.cursor/`, `~/.cursor/` | Project-local or global |
120
+ | Pi | `~/.pi/` | Global only |
121
+ | Gemini | `.gemini/`, `~/.gemini/` | Project-local or global |
122
+
123
+ ### Phase 2: Gemini Sync
124
+
125
+ **Create `src/sync/gemini.ts`**
126
+
127
+ Follow the Cursor sync pattern (`src/sync/cursor.ts`) since both use JSON config with `mcpServers` key:
128
+
129
+ ```typescript
130
+ import path from "path"
131
+ import { symlinkSkills } from "../utils/symlink"
132
+ import { backupFile, pathExists, readJson, writeJson } from "../utils/files"
133
+ import type { ClaudeMcpServer } from "../types/claude"
134
+
135
+ export async function syncToGemini(
136
+ skills: { name: string; sourceDir: string }[],
137
+ mcpServers: Record<string, ClaudeMcpServer>,
138
+ outputRoot: string,
139
+ ): Promise<void> {
140
+ const geminiDir = path.join(outputRoot, ".gemini")
141
+
142
+ // Symlink skills
143
+ if (skills.length > 0) {
144
+ const skillsDir = path.join(geminiDir, "skills")
145
+ await symlinkSkills(skills, skillsDir)
146
+ }
147
+
148
+ // Merge MCP servers into settings.json
149
+ if (Object.keys(mcpServers).length > 0) {
150
+ const settingsPath = path.join(geminiDir, "settings.json")
151
+ let existing: Record<string, unknown> = {}
152
+ if (await pathExists(settingsPath)) {
153
+ await backupFile(settingsPath)
154
+ try {
155
+ existing = await readJson<Record<string, unknown>>(settingsPath)
156
+ } catch {
157
+ console.warn("Warning: existing settings.json could not be parsed and will be replaced.")
158
+ }
159
+ }
160
+
161
+ const existingMcp = (existing.mcpServers && typeof existing.mcpServers === "object")
162
+ ? existing.mcpServers as Record<string, unknown>
163
+ : {}
164
+
165
+ const merged = { ...existing, mcpServers: { ...existingMcp, ...convertMcpServers(mcpServers) } }
166
+ await writeJson(settingsPath, merged)
167
+ }
168
+ }
169
+
170
+ function convertMcpServers(servers: Record<string, ClaudeMcpServer>) {
171
+ const result: Record<string, Record<string, unknown>> = {}
172
+ for (const [name, server] of Object.entries(servers)) {
173
+ const entry: Record<string, unknown> = {}
174
+ if (server.command) {
175
+ entry.command = server.command
176
+ if (server.args?.length) entry.args = server.args
177
+ if (server.env && Object.keys(server.env).length > 0) entry.env = server.env
178
+ } else if (server.url) {
179
+ entry.url = server.url
180
+ if (server.headers && Object.keys(server.headers).length > 0) entry.headers = server.headers
181
+ }
182
+ result[name] = entry
183
+ }
184
+ return result
185
+ }
186
+ ```
187
+
188
+ **Update `src/commands/sync.ts`:**
189
+
190
+ - Add `"gemini"` to `validTargets` array
191
+ - Import `syncToGemini` from `../sync/gemini`
192
+ - Add case in switch for `"gemini"` calling `syncToGemini(skills, mcpServers, outputRoot)`
193
+
194
+ ### Phase 3: Wire `--to all` into Install and Convert
195
+
196
+ **Modify `src/commands/install.ts`:**
197
+
198
+ ```typescript
199
+ import { detectInstalledTools } from "../utils/detect-tools"
200
+
201
+ // In args definition, update --to description:
202
+ to: {
203
+ type: "string",
204
+ default: "opencode",
205
+ description: "Target format (opencode | codex | droid | cursor | pi | gemini | all)",
206
+ },
207
+
208
+ // In run(), before the existing target lookup:
209
+ if (targetName === "all") {
210
+ const detected = await detectInstalledTools()
211
+ const activeTargets = detected.filter((t) => t.detected)
212
+
213
+ if (activeTargets.length === 0) {
214
+ console.log("No AI coding tools detected. Install at least one tool first.")
215
+ return
216
+ }
217
+
218
+ console.log(`Detected ${activeTargets.length} tools:`)
219
+ for (const tool of detected) {
220
+ console.log(` ${tool.detected ? "✓" : "✗"} ${tool.name} — ${tool.reason}`)
221
+ }
222
+
223
+ // Install to each detected target
224
+ for (const tool of activeTargets) {
225
+ const handler = targets[tool.name]
226
+ const bundle = handler.convert(plugin, options)
227
+ if (!bundle) continue
228
+ const root = resolveTargetOutputRoot(tool.name, outputRoot, codexHome, piHome, hasExplicitOutput)
229
+ await handler.write(root, bundle)
230
+ console.log(`Installed ${plugin.manifest.name} to ${tool.name} at ${root}`)
231
+ }
232
+
233
+ // Codex post-processing
234
+ if (activeTargets.some((t) => t.name === "codex")) {
235
+ await ensureCodexAgentsFile(codexHome)
236
+ }
237
+ return
238
+ }
239
+ ```
240
+
241
+ **Same change in `src/commands/convert.ts`** with its version of `resolveTargetOutputRoot`.
242
+
243
+ ### Phase 4: Wire `--target all` into Sync
244
+
245
+ **Modify `src/commands/sync.ts`:**
246
+
247
+ ```typescript
248
+ import { detectInstalledTools } from "../utils/detect-tools"
249
+
250
+ // Update validTargets:
251
+ const validTargets = ["opencode", "codex", "pi", "droid", "cursor", "gemini", "all"] as const
252
+
253
+ // In run(), handle "all":
254
+ if (targetName === "all") {
255
+ const detected = await detectInstalledTools()
256
+ const activeTargets = detected.filter((t) => t.detected).map((t) => t.name)
257
+
258
+ if (activeTargets.length === 0) {
259
+ console.log("No AI coding tools detected.")
260
+ return
261
+ }
262
+
263
+ console.log(`Syncing to ${activeTargets.length} detected tools...`)
264
+ for (const name of activeTargets) {
265
+ // call existing sync logic for each target
266
+ }
267
+ return
268
+ }
269
+ ```
270
+
271
+ ### Phase 5: Tests
272
+
273
+ **Create `tests/detect-tools.test.ts`**
274
+
275
+ - Test detection with mocked directories (create temp dirs, check detection)
276
+ - Test `getDetectedTargetNames` returns only detected tools
277
+ - Test empty detection returns empty array
278
+
279
+ **Create `tests/gemini-sync.test.ts`**
280
+
281
+ Follow `tests/sync-cursor.test.ts` pattern:
282
+
283
+ - Test skills are symlinked to `.gemini/skills/`
284
+ - Test MCP servers merged into `settings.json`
285
+ - Test existing `settings.json` is backed up
286
+ - Test empty skills/servers produce no output
287
+
288
+ **Update `tests/cli.test.ts`**
289
+
290
+ - Test `--to all` flag is accepted
291
+ - Test `sync --target all` is accepted
292
+ - Test `sync --target gemini` is accepted
293
+
294
+ ### Phase 6: Documentation
295
+
296
+ **Update `README.md`:**
297
+
298
+ Add to install section:
299
+ ```bash
300
+ # auto-detect installed tools and install to all
301
+ bunx @every-env/compound-plugin install compound-engineering --to all
302
+ ```
303
+
304
+ Add to sync section:
305
+ ```bash
306
+ # Sync to Gemini
307
+ bunx @every-env/compound-plugin sync --target gemini
308
+
309
+ # Sync to all detected tools
310
+ bunx @every-env/compound-plugin sync --target all
311
+ ```
312
+
313
+ ## What We're NOT Doing
314
+
315
+ - Not adding binary detection (`which cursor`, `which gemini`) — directory checks are sufficient and don't require shell execution
316
+ - Not adding interactive prompts ("Install to Cursor? y/n") — auto-detect is fire-and-forget
317
+ - Not adding `--exclude` flag for skipping specific targets — can use `--to X --also Y` for manual selection
318
+ - Not adding Gemini to the `sync` symlink watcher (no watcher exists for any target)
319
+
320
+ ## Complexity Assessment
321
+
322
+ **Low-medium change.** All patterns are established:
323
+ - Detection utility is new but simple (pathExists checks)
324
+ - Gemini sync follows cursor sync pattern exactly
325
+ - `--to all` is plumbing — iterate detected tools through existing handlers
326
+ - No new dependencies needed
327
+
328
+ ## References
329
+
330
+ - Cursor sync (reference pattern): `src/sync/cursor.ts`
331
+ - Gemini writer (merge pattern): `src/targets/gemini.ts`
332
+ - Install command: `src/commands/install.ts`
333
+ - Sync command: `src/commands/sync.ts`
334
+ - File utilities: `src/utils/files.ts`
335
+ - Symlink utilities: `src/utils/symlink.ts`
336
+
337
+ ## Completion Summary
338
+
339
+ ### What Was Delivered
340
+ - Tool detection utility (`src/utils/detect-tools.ts`) with `detectInstalledTools()` and `getDetectedTargetNames()`
341
+ - Gemini sync (`src/sync/gemini.ts`) following cursor sync pattern — symlinks skills, merges MCP servers into `settings.json`
342
+ - `install --to all` and `convert --to all` auto-detect and install to all detected tools
343
+ - `sync --target gemini` added to sync command
344
+ - `sync --target all` syncs to all detected tools with summary output
345
+ - 8 new tests across 2 test files (detect-tools + sync-gemini)
346
+
347
+ ### Implementation Statistics
348
+ - 4 new files, 3 modified files
349
+ - 139 tests passing (8 new + 131 existing)
350
+ - No new dependencies
351
+
352
+ ### Git Commits
353
+ - `e4d730d` feat: add detect-tools utility and Gemini sync with tests
354
+ - `bc655f7` feat: wire --to all into install/convert and --target all/gemini into sync
355
+ - `877e265` docs: add auto-detect and Gemini sync to README, bump to 0.8.0
356
+
357
+ ### Completion Details
358
+ - **Completed By:** Claude Opus 4.6
359
+ - **Date:** 2026-02-14
360
+ - **Session:** Single session, TDD approach