From 8a57679222970217711c17e3084dc1082b69f1cd Mon Sep 17 00:00:00 2001 From: Affaan Mustafa Date: Mon, 11 May 2026 02:10:36 -0400 Subject: [PATCH] fix: restore short Claude plugin slug and skill installs (#1712) --- .claude-plugin/PLUGIN_SCHEMA_NOTES.md | 1 + .claude-plugin/marketplace.json | 6 +- .claude-plugin/plugin.json | 4 +- .codex-plugin/README.md | 2 +- .codex-plugin/plugin.json | 4 +- README.md | 26 ++++----- README.zh-CN.md | 14 ++--- docs/ja-JP/README.md | 10 ++-- docs/ja-JP/skills/configure-ecc/SKILL.md | 2 +- docs/ko-KR/README.md | 18 +++--- docs/pt-BR/README.md | 18 +++--- docs/tr/README.md | 14 ++--- docs/zh-CN/README.md | 18 +++--- docs/zh-CN/skills/configure-ecc/SKILL.md | 2 +- docs/zh-TW/README.md | 10 ++-- scripts/install-apply.js | 2 + scripts/install-plan.js | 10 ++++ scripts/lib/install-manifests.js | 56 +++++++++++++++++- scripts/lib/install/request.js | 9 +++ skills/configure-ecc/SKILL.md | 2 +- tests/docs/install-identifiers.test.js | 16 +++--- tests/lib/install-manifests.test.js | 17 ++++++ tests/lib/selective-install.test.js | 73 ++++++++++++++++++++++++ tests/plugin-manifest.test.js | 19 +++--- tests/scripts/install-plan.test.js | 14 +++++ 25 files changed, 273 insertions(+), 94 deletions(-) diff --git a/.claude-plugin/PLUGIN_SCHEMA_NOTES.md b/.claude-plugin/PLUGIN_SCHEMA_NOTES.md index 7ee8f3bd..e427225f 100644 --- a/.claude-plugin/PLUGIN_SCHEMA_NOTES.md +++ b/.claude-plugin/PLUGIN_SCHEMA_NOTES.md @@ -136,6 +136,7 @@ The test `plugin.json does NOT have explicit hooks declaration` in `tests/hooks/ ECC keeps `.mcp.json` at the repository root for Codex plugin installs and manual MCP setup. Claude Code also auto-discovers plugin-root `.mcp.json` files by convention, which would bundle the same MCP servers into Claude plugin installs. +The Claude plugin slug is intentionally short (`ecc`), but this opt-out is still required because legacy installs and strict provider gateways have failed on generated names from longer plugin identifiers. Keep this field in `.claude-plugin/plugin.json`: diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 5988a009..88a90dab 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -1,5 +1,5 @@ { - "name": "everything-claude-code", + "name": "ecc", "owner": { "name": "Affaan Mustafa", "email": "me@affaanmustafa.com" @@ -9,9 +9,9 @@ }, "plugins": [ { - "name": "everything-claude-code", + "name": "ecc", "source": "./", - "description": "The most comprehensive Claude Code plugin — 48 agents, 182 skills, 68 legacy command shims, selective install profiles, and production-ready hooks for TDD, security scanning, code review, and continuous learning", + "description": "The most comprehensive Claude Code plugin — 48 agents, 185 skills, 68 legacy command shims, selective install profiles, and production-ready hooks for TDD, security scanning, code review, and continuous learning", "version": "2.0.0-rc.1", "author": { "name": "Affaan Mustafa", diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 12666847..0c959b56 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { - "name": "everything-claude-code", + "name": "ecc", "version": "2.0.0-rc.1", - "description": "Battle-tested Claude Code plugin for engineering teams — 48 agents, 182 skills, 68 legacy command shims, production-ready hooks, and selective install workflows evolved through continuous real-world use", + "description": "Battle-tested Claude Code plugin for engineering teams — 48 agents, 185 skills, 68 legacy command shims, production-ready hooks, and selective install workflows evolved through continuous real-world use", "author": { "name": "Affaan Mustafa", "url": "https://x.com/affaanmustafa" diff --git a/.codex-plugin/README.md b/.codex-plugin/README.md index 06fa236f..86544bdd 100644 --- a/.codex-plugin/README.md +++ b/.codex-plugin/README.md @@ -12,7 +12,7 @@ This directory contains the **Codex plugin manifest** for Everything Claude Code ## What This Provides -- **182 skills** from `./skills/` — reusable Codex workflows for TDD, security, +- **185 skills** from `./skills/` — reusable Codex workflows for TDD, security, code review, architecture, and more - **6 MCP servers** — GitHub, Context7, Exa, Memory, Playwright, Sequential Thinking diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index fa83648c..4da42258 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "ecc", "version": "2.0.0-rc.1", - "description": "Battle-tested Codex workflows — 182 shared ECC skills, production-ready MCP configs, and selective-install-aligned conventions for TDD, security scanning, code review, and autonomous development.", + "description": "Battle-tested Codex workflows — 185 shared ECC skills, production-ready MCP configs, and selective-install-aligned conventions for TDD, security scanning, code review, and autonomous development.", "author": { "name": "Affaan Mustafa", "email": "me@affaanmustafa.com", @@ -15,7 +15,7 @@ "mcpServers": "./.mcp.json", "interface": { "displayName": "Everything Claude Code", - "shortDescription": "182 battle-tested ECC skills plus MCP configs for TDD, security, code review, and autonomous development.", + "shortDescription": "185 battle-tested ECC skills plus MCP configs for TDD, security, code review, and autonomous development.", "longDescription": "Everything Claude Code (ECC) is a community-maintained collection of Codex-ready skills and MCP configs evolved over 10+ months of intensive daily use. It covers TDD workflows, security scanning, code review, architecture decisions, operator workflows, and more — all in one installable plugin.", "developerName": "Affaan Mustafa", "category": "Productivity", diff --git a/README.md b/README.md index e5930f4f..a991f60b 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ This repo is the raw code only. The guides explain everything. ### v2.0.0-rc.1 — Surface Refresh, Operator Workflows, and ECC 2.0 Alpha (Apr 2026) - **Dashboard GUI** — New Tkinter-based desktop application (`ecc_dashboard.py` or `npm run dashboard`) with dark/light theme toggle, font customization, and project logo in header and taskbar. -- **Public surface synced to the live repo** — metadata, catalog counts, plugin manifests, and install-facing docs now match the actual OSS surface: 48 agents, 182 skills, and 68 legacy command shims. +- **Public surface synced to the live repo** — metadata, catalog counts, plugin manifests, and install-facing docs now match the actual OSS surface: 48 agents, 185 skills, and 68 legacy command shims. - **Operator and outbound workflow expansion** — `brand-voice`, `social-graph-ranker`, `connections-optimizer`, `customer-billing-ops`, `ecc-tools-cost-audit`, `google-workspace-ops`, `project-flow-ops`, and `workspace-surface-audit` round out the operator lane. - **Media and launch tooling** — `manim-video`, `remotion-video-creation`, and upgraded social publishing surfaces make technical explainers and launch content part of the same system. - **Framework and product surface growth** — `nestjs-patterns`, richer Codex/OpenCode install surfaces, and expanded cross-harness packaging keep the repo usable beyond Claude Code alone. @@ -226,7 +226,7 @@ It returns matching components, related profiles, and preview/install commands. /plugin marketplace add https://github.com/affaan-m/everything-claude-code # Install plugin -/plugin install everything-claude-code@everything-claude-code +/plugin install ecc@ecc ``` ### Naming + Migration Note @@ -234,12 +234,12 @@ It returns matching components, related profiles, and preview/install commands. ECC now has three public identifiers, and they are not interchangeable: - GitHub source repo: `affaan-m/everything-claude-code` -- Claude marketplace/plugin identifier: `everything-claude-code@everything-claude-code` +- Claude marketplace/plugin identifier: `ecc@ecc` - npm package: `ecc-universal` -This is intentional. Anthropic marketplace/plugin installs are keyed by a canonical plugin identifier, so ECC standardized on `everything-claude-code@everything-claude-code` to keep the listing name, `/plugin install`, `/plugin list`, and repo docs aligned to one public install surface. Older posts may still show the old short-form nickname; that shorthand is deprecated. Separately, the npm package stayed on `ecc-universal`, so npm installs and marketplace installs intentionally use different names. +This is intentional. Anthropic marketplace/plugin installs are keyed by a canonical plugin identifier, so ECC uses `ecc@ecc` to keep tool names and slash-command namespaces short enough for strict Desktop/API validators. Older posts may still show the former long marketplace identifier; treat that as a legacy alias only. Separately, the npm package stayed on `ecc-universal`, so npm installs and marketplace installs intentionally use different names. -### Step 2: Install Rules (Required) +### Step 2: Install Rules Only If You Need Them > WARNING: **Important:** Claude Code plugins cannot distribute `rules` automatically. > @@ -341,13 +341,13 @@ If you stacked methods, clean up in this order: # Existing slash-style command names still work while ECC migrates off commands/. # Plugin install uses the canonical namespaced form -/everything-claude-code:plan "Add user authentication" +/ecc:plan "Add user authentication" # Manual install keeps the shorter slash form: # /plan "Add user authentication" # Check available commands -/plugin list everything-claude-code@everything-claude-code +/plugin list ecc@ecc ``` **That's it!** You now have access to 48 agents, 185 skills, and 68 legacy command shims. @@ -767,7 +767,7 @@ The easiest way to use this repo - install as a Claude Code plugin: /plugin marketplace add https://github.com/affaan-m/everything-claude-code # Install the plugin -/plugin install everything-claude-code@everything-claude-code +/plugin install ecc@ecc ``` Or add directly to your `~/.claude/settings.json`: @@ -783,7 +783,7 @@ Or add directly to your `~/.claude/settings.json`: } }, "enabledPlugins": { - "everything-claude-code@everything-claude-code": true + "ecc@ecc": true } } ``` @@ -961,8 +961,8 @@ Not sure where to start? Use this quick reference. Skills are the canonical work | I want to... | Use this surface | Agent used | |--------------|-----------------|------------| -| Plan a new feature | `/everything-claude-code:plan "Add auth"` | planner | -| Design system architecture | `/everything-claude-code:plan` + architect agent | architect | +| Plan a new feature | `/ecc:plan "Add auth"` | planner | +| Design system architecture | `/ecc:plan` + architect agent | architect | | Write code with tests first | `tdd-workflow` skill | tdd-guide | | Review code I just wrote | `/code-review` | code-reviewer | | Fix a failing build | `/build-fix` | build-error-resolver | @@ -981,7 +981,7 @@ Slash forms below are shown where they remain part of the maintained command sur **Starting a new feature:** ``` -/everything-claude-code:plan "Add user authentication with OAuth" +/ecc:plan "Add user authentication with OAuth" → planner creates implementation blueprint tdd-workflow skill → tdd-guide enforces write-tests-first /code-review → code-reviewer checks your work @@ -1009,7 +1009,7 @@ e2e-testing skill → e2e-runner: critical user flow How do I check which agents/commands are installed? ```bash -/plugin list everything-claude-code@everything-claude-code +/plugin list ecc@ecc ``` This shows all available agents, commands, and skills from the plugin. diff --git a/README.zh-CN.md b/README.zh-CN.md index 7e329d05..e56a95b3 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -102,12 +102,12 @@ /plugin marketplace add https://github.com/affaan-m/everything-claude-code # 安装插件 -/plugin install everything-claude-code@everything-claude-code +/plugin install ecc@ecc ``` -> 安装名称说明:较早的帖子里可能还会出现旧的短别名。那个旧缩写现在已经废弃。Anthropic 的 marketplace/plugin 安装是按规范化插件标识符寻址的,因此 ECC 统一为 `everything-claude-code@everything-claude-code`,这样市场条目、安装命令、`/plugin list` 输出和仓库文档都使用同一个公开名称,不再出现两个名字指向同一插件的混乱。 +> 安装名称说明:较早的帖子里可能还会出现较长的旧标识符。Anthropic 的 marketplace/plugin 安装是按规范化插件标识符寻址的,因此 ECC 现在统一为 `ecc@ecc`,让工具名和 slash command 命名空间保持简短。 -### 第二步:安装规则(必需) +### 第二步:仅在需要时安装规则 > WARNING: **重要提示:** Claude Code 插件无法自动分发 `rules`。 > @@ -151,13 +151,13 @@ Copy-Item -Recurse rules/typescript "$HOME/.claude/rules/" ```bash # 尝试一个命令(插件安装使用命名空间形式) -/everything-claude-code:plan "添加用户认证" +/ecc:plan "添加用户认证" # 手动安装(选项2)使用简短形式: # /plan "添加用户认证" # 查看可用命令 -/plugin list everything-claude-code@everything-claude-code +/plugin list ecc@ecc ``` **完成!** 你现在可以使用 48 个代理、185 个技能和 68 个命令。 @@ -546,7 +546,7 @@ Claude Code v2.1+ 会**按照约定自动加载**已安装插件中的 `hooks/ho /plugin marketplace add https://github.com/affaan-m/everything-claude-code # 安装插件 -/plugin install everything-claude-code@everything-claude-code +/plugin install ecc@ecc ``` 或直接添加到你的 `~/.claude/settings.json`: @@ -562,7 +562,7 @@ Claude Code v2.1+ 会**按照约定自动加载**已安装插件中的 `hooks/ho } }, "enabledPlugins": { - "everything-claude-code@everything-claude-code": true + "ecc@ecc": true } } ``` diff --git a/docs/ja-JP/README.md b/docs/ja-JP/README.md index d5277687..d7f1d5dd 100644 --- a/docs/ja-JP/README.md +++ b/docs/ja-JP/README.md @@ -110,7 +110,7 @@ /plugin marketplace add https://github.com/affaan-m/everything-claude-code # プラグインをインストール -/plugin install everything-claude-code +/plugin install ecc@ecc ``` ### ステップ2:ルールをインストール(必須) @@ -134,13 +134,13 @@ cp -r everything-claude-code/rules/golang/* ~/.claude/rules/ ```bash # コマンドを試す(プラグインはネームスペース形式) -/everything-claude-code:plan "ユーザー認証を追加" +/ecc:plan "ユーザー認証を追加" # 手動インストール(オプション2)は短縮形式: # /plan "ユーザー認証を追加" # 利用可能なコマンドを確認 -/plugin list everything-claude-code@everything-claude-code +/plugin list ecc@ecc ``` **完了です!** これで13のエージェント、43のスキル、31のコマンドにアクセスできます。 @@ -427,7 +427,7 @@ Duplicate hook file detected: ./hooks/hooks.json is already resolved to a loaded /plugin marketplace add https://github.com/affaan-m/everything-claude-code # プラグインをインストール -/plugin install everything-claude-code +/plugin install ecc@ecc ``` または、`~/.claude/settings.json` に直接追加: @@ -443,7 +443,7 @@ Duplicate hook file detected: ./hooks/hooks.json is already resolved to a loaded } }, "enabledPlugins": { - "everything-claude-code@everything-claude-code": true + "ecc@ecc": true } } ``` diff --git a/docs/ja-JP/skills/configure-ecc/SKILL.md b/docs/ja-JP/skills/configure-ecc/SKILL.md index e77775fc..78acf2c9 100644 --- a/docs/ja-JP/skills/configure-ecc/SKILL.md +++ b/docs/ja-JP/skills/configure-ecc/SKILL.md @@ -17,7 +17,7 @@ Everything Claude Code プロジェクトのインタラクティブなステッ ## 前提条件 このスキルは起動前に Claude Code からアクセス可能である必要があります。ブートストラップには2つの方法があります: -1. **プラグイン経由**: `/plugin install everything-claude-code@everything-claude-code` — プラグインがこのスキルを自動的にロードします +1. **プラグイン経由**: `/plugin install ecc@ecc` — プラグインがこのスキルを自動的にロードします 2. **手動**: このスキルのみを `~/.claude/skills/configure-ecc/SKILL.md` にコピーし、"configure ecc" と言って起動します --- diff --git a/docs/ko-KR/README.md b/docs/ko-KR/README.md index cf8ceecb..73df584d 100644 --- a/docs/ko-KR/README.md +++ b/docs/ko-KR/README.md @@ -115,7 +115,7 @@ /plugin marketplace add https://github.com/affaan-m/everything-claude-code # 플러그인 설치 -/plugin install everything-claude-code +/plugin install ecc@ecc ``` ### 2단계: 룰 설치 (필수) @@ -141,13 +141,13 @@ cd everything-claude-code ```bash # 커맨드 실행 (플러그인 설치 시 네임스페이스 형태 사용) -/everything-claude-code:plan "사용자 인증 추가" +/ecc:plan "사용자 인증 추가" # 수동 설치(옵션 2) 시에는 짧은 형태를 사용: # /plan "사용자 인증 추가" # 사용 가능한 커맨드 확인 -/plugin list everything-claude-code@everything-claude-code +/plugin list ecc@ecc ``` **끝!** 이제 16개 에이전트, 65개 스킬, 40개 커맨드를 사용할 수 있습니다. @@ -359,7 +359,7 @@ Claude Code v2.1+는 설치된 플러그인의 `hooks/hooks.json`을 **자동으 /plugin marketplace add https://github.com/affaan-m/everything-claude-code # 플러그인 설치 -/plugin install everything-claude-code +/plugin install ecc@ecc ``` 또는 `~/.claude/settings.json`에 직접 추가: @@ -375,7 +375,7 @@ Claude Code v2.1+는 설치된 플러그인의 `hooks/hooks.json`을 **자동으 } }, "enabledPlugins": { - "everything-claude-code@everything-claude-code": true + "ecc@ecc": true } } ``` @@ -489,8 +489,8 @@ rules/ | 하고 싶은 것 | 사용할 커맨드 | 사용되는 에이전트 | |-------------|-------------|-----------------| -| 새 기능 계획하기 | `/everything-claude-code:plan "인증 추가"` | planner | -| 시스템 아키텍처 설계 | `/everything-claude-code:plan` + architect 에이전트 | architect | +| 새 기능 계획하기 | `/ecc:plan "인증 추가"` | planner | +| 시스템 아키텍처 설계 | `/ecc:plan` + architect 에이전트 | architect | | 테스트를 먼저 작성하며 코딩 | `/tdd` | tdd-guide | | 방금 작성한 코드 리뷰 | `/code-review` | code-reviewer | | 빌드 실패 수정 | `/build-fix` | build-error-resolver | @@ -507,7 +507,7 @@ rules/ **새로운 기능 시작:** ``` -/everything-claude-code:plan "OAuth를 사용한 사용자 인증 추가" +/ecc:plan "OAuth를 사용한 사용자 인증 추가" → planner가 구현 청사진 작성 /tdd → tdd-guide가 테스트 먼저 작성 강제 /code-review → code-reviewer가 코드 검토 @@ -535,7 +535,7 @@ rules/ 설치된 에이전트/커맨드 확인은 어떻게 하나요? ```bash -/plugin list everything-claude-code@everything-claude-code +/plugin list ecc@ecc ``` 플러그인에서 사용할 수 있는 모든 에이전트, 커맨드, 스킬을 보여줍니다. diff --git a/docs/pt-BR/README.md b/docs/pt-BR/README.md index 21908aba..66b7495f 100644 --- a/docs/pt-BR/README.md +++ b/docs/pt-BR/README.md @@ -124,7 +124,7 @@ Comece em menos de 2 minutos: /plugin marketplace add https://github.com/affaan-m/everything-claude-code # Instalar plugin -/plugin install everything-claude-code@everything-claude-code +/plugin install ecc@ecc ``` ### Passo 2: Instalar as Regras (Obrigatório) @@ -161,13 +161,13 @@ npx ecc-install typescript ```bash # Experimente um comando (a instalação do plugin usa forma com namespace) -/everything-claude-code:plan "Adicionar autenticação de usuário" +/ecc:plan "Adicionar autenticação de usuário" # Instalação manual (Opção 2) usa a forma mais curta: # /plan "Adicionar autenticação de usuário" # Verificar comandos disponíveis -/plugin list everything-claude-code@everything-claude-code +/plugin list ecc@ecc ``` **Pronto!** Você agora tem acesso a 28 agentes, 116 skills e 59 comandos. @@ -313,7 +313,7 @@ claude --version /plugin marketplace add https://github.com/affaan-m/everything-claude-code # Instalar o plugin -/plugin install everything-claude-code@everything-claude-code +/plugin install ecc@ecc ``` Ou adicione diretamente ao seu `~/.claude/settings.json`: @@ -329,7 +329,7 @@ Ou adicione diretamente ao seu `~/.claude/settings.json`: } }, "enabledPlugins": { - "everything-claude-code@everything-claude-code": true + "ecc@ecc": true } } ``` @@ -408,8 +408,8 @@ Regras são diretrizes sempre seguidas, organizadas em `common/` (agnóstico à | Quero... | Use este comando | Agente usado | |----------|-----------------|--------------| -| Planejar um novo recurso | `/everything-claude-code:plan "Adicionar auth"` | planner | -| Projetar arquitetura de sistema | `/everything-claude-code:plan` + agente architect | architect | +| Planejar um novo recurso | `/ecc:plan "Adicionar auth"` | planner | +| Projetar arquitetura de sistema | `/ecc:plan` + agente architect | architect | | Escrever código com testes primeiro | `/tdd` | tdd-guide | | Revisar código que acabei de escrever | `/code-review` | code-reviewer | | Corrigir build com falha | `/build-fix` | build-error-resolver | @@ -424,7 +424,7 @@ Regras são diretrizes sempre seguidas, organizadas em `common/` (agnóstico à **Começando um novo recurso:** ``` -/everything-claude-code:plan "Adicionar autenticação de usuário com OAuth" +/ecc:plan "Adicionar autenticação de usuário com OAuth" → planner cria blueprint de implementação /tdd → tdd-guide aplica escrita de testes primeiro /code-review → code-reviewer verifica seu trabalho @@ -452,7 +452,7 @@ Regras são diretrizes sempre seguidas, organizadas em `common/` (agnóstico à Como verificar quais agentes/comandos estão instalados? ```bash -/plugin list everything-claude-code@everything-claude-code +/plugin list ecc@ecc ``` diff --git a/docs/tr/README.md b/docs/tr/README.md index 40032ee2..5d8e2fa6 100644 --- a/docs/tr/README.md +++ b/docs/tr/README.md @@ -125,7 +125,7 @@ Bu repository yalnızca ham kodu içerir. Rehberler her şeyi açıklıyor. /plugin marketplace add https://github.com/affaan-m/everything-claude-code # Plugin'i kur -/plugin install everything-claude-code +/plugin install ecc@ecc ``` ### Adım 2: Rule'ları Kurun (Gerekli) @@ -164,13 +164,13 @@ Manuel kurulum talimatları için `rules/` klasöründeki README'ye bakın. ```bash # Bir command deneyin (plugin kurulumu namespace'li form kullanır) -/everything-claude-code:plan "Kullanıcı kimlik doğrulaması ekle" +/ecc:plan "Kullanıcı kimlik doğrulaması ekle" # Manuel kurulum (Seçenek 2) daha kısa formu kullanır: # /plan "Kullanıcı kimlik doğrulaması ekle" # Mevcut command'ları kontrol edin -/plugin list everything-claude-code@everything-claude-code +/plugin list ecc@ecc ``` **Bu kadar!** Artık 28 agent, 116 skill ve 59 command'a erişiminiz var. @@ -308,8 +308,8 @@ Nereden başlayacağınızdan emin değil misiniz? Bu hızlı referansı kullan | Yapmak istediğim... | Bu command'ı kullan | Kullanılan agent | |---------------------|---------------------|------------------| -| Yeni bir feature planla | `/everything-claude-code:plan "Auth ekle"` | planner | -| Sistem mimarisi tasarla | `/everything-claude-code:plan` + architect agent | architect | +| Yeni bir feature planla | `/ecc:plan "Auth ekle"` | planner | +| Sistem mimarisi tasarla | `/ecc:plan` + architect agent | architect | | Önce testlerle kod yaz | `/tdd` | tdd-guide | | Yazdığım kodu incele | `/code-review` | code-reviewer | | Başarısız bir build'i düzelt | `/build-fix` | build-error-resolver | @@ -324,7 +324,7 @@ Nereden başlayacağınızdan emin değil misiniz? Bu hızlı referansı kullan **Yeni bir feature başlatma:** ``` -/everything-claude-code:plan "OAuth ile kullanıcı kimlik doğrulaması ekle" +/ecc:plan "OAuth ile kullanıcı kimlik doğrulaması ekle" → planner implementasyon planı oluşturur /tdd → tdd-guide önce-test-yaz'ı zorunlu kılar /code-review → code-reviewer çalışmanızı kontrol eder @@ -352,7 +352,7 @@ Nereden başlayacağınızdan emin değil misiniz? Bu hızlı referansı kullan Hangi agent/command'ların kurulu olduğunu nasıl kontrol ederim? ```bash -/plugin list everything-claude-code@everything-claude-code +/plugin list ecc@ecc ``` Bu, plugin'den mevcut tüm agent'ları, command'ları ve skill'leri gösterir. diff --git a/docs/zh-CN/README.md b/docs/zh-CN/README.md index a32f549b..314e0dc3 100644 --- a/docs/zh-CN/README.md +++ b/docs/zh-CN/README.md @@ -170,7 +170,7 @@ /plugin marketplace add https://github.com/affaan-m/everything-claude-code # Install plugin -/plugin install everything-claude-code@everything-claude-code +/plugin install ecc@ecc ``` ### 步骤 2:安装规则(必需) @@ -215,13 +215,13 @@ Copy-Item -Recurse rules/typescript "$HOME/.claude/rules/" ```bash # Try a command (plugin install uses namespaced form) -/everything-claude-code:plan "Add user authentication" +/ecc:plan "Add user authentication" # Manual install (Option 2) uses the shorter form: # /plan "Add user authentication" # Check available commands -/plugin list everything-claude-code@everything-claude-code +/plugin list ecc@ecc ``` **搞定!** 你现在可以使用 48 个智能体、185 项技能和 68 个命令了。 @@ -602,7 +602,7 @@ Claude Code v2.1+ **会自动加载** 任何已安装插件中的 `hooks/hooks.j /plugin marketplace add https://github.com/affaan-m/everything-claude-code # Install the plugin -/plugin install everything-claude-code +/plugin install ecc@ecc ``` 或者直接添加到您的 `~/.claude/settings.json`: @@ -618,7 +618,7 @@ Claude Code v2.1+ **会自动加载** 任何已安装插件中的 `hooks/hooks.j } }, "enabledPlugins": { - "everything-claude-code@everything-claude-code": true + "ecc@ecc": true } } ``` @@ -764,8 +764,8 @@ rules/ | 我想要... | 使用此表面 | 使用的智能体 | |--------------|-----------------|------------| -| 规划新功能 | `/everything-claude-code:plan "Add auth"` | planner | -| 设计系统架构 | `/everything-claude-code:plan` + architect agent | architect | +| 规划新功能 | `/ecc:plan "Add auth"` | planner | +| 设计系统架构 | `/ecc:plan` + architect agent | architect | | 先写测试再写代码 | `tdd-workflow` 技能 | tdd-guide | | 评审我刚写的代码 | `/code-review` | code-reviewer | | 修复失败的构建 | `/build-fix` | build-error-resolver | @@ -783,7 +783,7 @@ rules/ **开始新功能:** ``` -/everything-claude-code:plan "使用 OAuth 添加用户身份验证" +/ecc:plan "使用 OAuth 添加用户身份验证" → 规划器创建实现蓝图 tdd-workflow 技能 → tdd-guide 强制执行先写测试 /code-review → 代码审查员检查你的工作 @@ -813,7 +813,7 @@ e2e-testing 技能 → e2e-runner: 关键用户流 如何检查已安装的代理/命令? ```bash -/plugin list everything-claude-code@everything-claude-code +/plugin list ecc@ecc ``` 这会显示插件中所有可用的代理、命令和技能。 diff --git a/docs/zh-CN/skills/configure-ecc/SKILL.md b/docs/zh-CN/skills/configure-ecc/SKILL.md index 9b671224..9fe6b8b7 100644 --- a/docs/zh-CN/skills/configure-ecc/SKILL.md +++ b/docs/zh-CN/skills/configure-ecc/SKILL.md @@ -19,7 +19,7 @@ origin: ECC 此技能必须在激活前对 Claude Code 可访问。有两种引导方式: -1. **通过插件**: `/plugin install everything-claude-code@everything-claude-code` — 插件会自动加载此技能 +1. **通过插件**: `/plugin install ecc@ecc` — 插件会自动加载此技能 2. **手动**: 仅将此技能复制到 `~/.claude/skills/configure-ecc/SKILL.md`,然后通过说 "configure ecc" 激活 *** diff --git a/docs/zh-TW/README.md b/docs/zh-TW/README.md index acdc3a8c..bb0e3360 100644 --- a/docs/zh-TW/README.md +++ b/docs/zh-TW/README.md @@ -70,7 +70,7 @@ /plugin marketplace add https://github.com/affaan-m/everything-claude-code # 安裝外掛程式 -/plugin install everything-claude-code +/plugin install ecc@ecc ``` ### 第二步:安裝規則(必需) @@ -89,13 +89,13 @@ cp -r everything-claude-code/rules/* ~/.claude/rules/ ```bash # 嘗試一個指令(外掛安裝使用命名空間形式) -/everything-claude-code:plan "新增使用者認證" +/ecc:plan "新增使用者認證" # 手動安裝(選項2)使用簡短形式: # /plan "新增使用者認證" # 查看可用指令 -/plugin list everything-claude-code@everything-claude-code +/plugin list ecc@ecc ``` **完成!** 您現在使用 15+ 代理程式、30+ 技能和 20+ 指令。 @@ -270,7 +270,7 @@ everything-claude-code/ /plugin marketplace add https://github.com/affaan-m/everything-claude-code # 安裝外掛程式 -/plugin install everything-claude-code +/plugin install ecc@ecc ``` 或直接新增到您的 `~/.claude/settings.json`: @@ -286,7 +286,7 @@ everything-claude-code/ } }, "enabledPlugins": { - "everything-claude-code@everything-claude-code": true + "ecc@ecc": true } } ``` diff --git a/scripts/install-apply.js b/scripts/install-apply.js index c4a531b4..3acfe228 100755 --- a/scripts/install-apply.js +++ b/scripts/install-apply.js @@ -24,6 +24,7 @@ function getHelpText() { Usage: install.sh [--target <${LEGACY_INSTALL_TARGETS.join('|')}>] [--dry-run] [--json] [ ...] install.sh [--target <${SUPPORTED_INSTALL_TARGETS.join('|')}>] [--dry-run] [--json] --profile [--with ]... [--without ]... install.sh [--target <${SUPPORTED_INSTALL_TARGETS.join('|')}>] [--dry-run] [--json] --modules [--with ]... [--without ]... + install.sh [--target <${SUPPORTED_INSTALL_TARGETS.join('|')}>] [--dry-run] [--json] --skills install.sh [--dry-run] [--json] --config Targets: @@ -35,6 +36,7 @@ Options: --profile Resolve and install a manifest profile --modules Resolve and install explicit module IDs --with Include a user-facing install component + --skills Install one or more skill directories by ID, e.g. continuous-learning-v2 --without Exclude a user-facing install component --config Load install intent from ecc-install.json diff --git a/scripts/install-plan.js b/scripts/install-plan.js index 24ffd91b..0be25bc1 100644 --- a/scripts/install-plan.js +++ b/scripts/install-plan.js @@ -25,6 +25,7 @@ Usage: node scripts/install-plan.js --list-components [--family ] [--target ] [--json] node scripts/install-plan.js --profile [--with ]... [--without ]... [--target ] [--json] node scripts/install-plan.js --modules [--with ]... [--without ]... [--target ] [--json] + node scripts/install-plan.js --skills [--target ] [--json] node scripts/install-plan.js --config [--json] Options: @@ -35,6 +36,7 @@ Options: --profile Resolve an install profile --modules Resolve explicit module IDs (comma-separated) --with Include a user-facing install component + --skills Include one or more skill components by directory ID --without Exclude a user-facing install component --config Load install intent from ecc-install.json @@ -61,6 +63,11 @@ function parseArgs(argv) { listComponents: false, }; + function normalizeSkillComponentIds(rawValue) { + return [...new Set(String(rawValue || '').split(',').map(value => value.trim()).filter(Boolean))] + .map(value => (value.startsWith('skill:') ? value : `skill:${value}`)); + } + for (let index = 0; index < args.length; index += 1) { const arg = args[index]; if (arg === '--help' || arg === '-h') { @@ -89,6 +96,9 @@ function parseArgs(argv) { parsed.includeComponentIds.push(componentId.trim()); } index += 1; + } else if (arg === '--skill' || arg === '--skills') { + parsed.includeComponentIds.push(...normalizeSkillComponentIds(args[index + 1] || '')); + index += 1; } else if (arg === '--without') { const componentId = args[index + 1] || ''; if (componentId.trim()) { diff --git a/scripts/lib/install-manifests.js b/scripts/lib/install-manifests.js index 3121f7b1..631eb111 100644 --- a/scripts/lib/install-manifests.js +++ b/scripts/lib/install-manifests.js @@ -78,6 +78,56 @@ function dedupeStrings(values) { return [...new Set((Array.isArray(values) ? values : []).map(value => String(value).trim()).filter(Boolean))]; } +function listSkillDirectoryIds(repoRoot) { + const skillsRoot = path.join(repoRoot, 'skills'); + if (!fs.existsSync(skillsRoot) || !fs.statSync(skillsRoot).isDirectory()) { + return []; + } + + return fs.readdirSync(skillsRoot, { withFileTypes: true }) + .filter(entry => entry.isDirectory()) + .map(entry => entry.name) + .sort(); +} + +function addSyntheticSkillComponents({ repoRoot, modules, components }) { + const moduleIds = new Set(modules.map(module => module.id)); + const componentIds = new Set(components.map(component => component.id)); + + for (const skillId of listSkillDirectoryIds(repoRoot)) { + const componentId = `skill:${skillId}`; + if (componentIds.has(componentId)) { + continue; + } + + const moduleId = `skill-${skillId}`; + if (!moduleIds.has(moduleId)) { + modules.push({ + id: moduleId, + kind: 'skills', + description: `Single-skill install surface for ${skillId}.`, + paths: [`skills/${skillId}`], + targets: SUPPORTED_INSTALL_TARGETS.slice(), + dependencies: [], + defaultInstall: false, + cost: 'light', + stability: 'stable', + synthetic: true, + }); + moduleIds.add(moduleId); + } + + components.push({ + id: componentId, + family: 'skill', + description: `Install only the ${skillId} skill directory.`, + modules: [moduleId], + synthetic: true, + }); + componentIds.add(componentId); + } +} + function readOptionalStringOption(options, key) { if ( !Object.prototype.hasOwnProperty.call(options, key) @@ -164,11 +214,13 @@ function loadInstallManifests(options = {}) { const componentsData = fs.existsSync(componentsPath) ? readJson(componentsPath, 'install-components.json') : { version: null, components: [] }; - const modules = Array.isArray(modulesData.modules) ? modulesData.modules : []; + const modules = Array.isArray(modulesData.modules) ? modulesData.modules.slice() : []; const profiles = profilesData && typeof profilesData.profiles === 'object' ? profilesData.profiles : {}; - const components = Array.isArray(componentsData.components) ? componentsData.components : []; + const components = Array.isArray(componentsData.components) ? componentsData.components.slice() : []; + + addSyntheticSkillComponents({ repoRoot, modules, components }); for (const module of modules) { readModuleTargetsOrThrow(module); diff --git a/scripts/lib/install/request.js b/scripts/lib/install/request.js index 592e6e01..d2a8ef28 100644 --- a/scripts/lib/install/request.js +++ b/scripts/lib/install/request.js @@ -8,6 +8,12 @@ function dedupeStrings(values) { return [...new Set((Array.isArray(values) ? values : []).map(value => String(value).trim()).filter(Boolean))]; } +function normalizeSkillComponentIds(rawValue) { + return dedupeStrings(String(rawValue || '').split(',')).map(value => ( + value.startsWith('skill:') ? value : `skill:${value}` + )); +} + function parseInstallArgs(argv) { const args = argv.slice(2); const parsed = { @@ -45,6 +51,9 @@ function parseInstallArgs(argv) { parsed.includeComponentIds.push(componentId.trim()); } index += 1; + } else if (arg === '--skill' || arg === '--skills') { + parsed.includeComponentIds.push(...normalizeSkillComponentIds(args[index + 1] || '')); + index += 1; } else if (arg === '--without') { const componentId = args[index + 1] || ''; if (componentId.trim()) { diff --git a/skills/configure-ecc/SKILL.md b/skills/configure-ecc/SKILL.md index ddbc0a44..c0a63fb6 100644 --- a/skills/configure-ecc/SKILL.md +++ b/skills/configure-ecc/SKILL.md @@ -18,7 +18,7 @@ An interactive, step-by-step installation wizard for the Everything Claude Code ## Prerequisites This skill must be accessible to Claude Code before activation. Two ways to bootstrap: -1. **Via Plugin**: `/plugin install everything-claude-code` — the plugin loads this skill automatically +1. **Via Plugin**: `/plugin install ecc@ecc` — the plugin loads this skill automatically 2. **Manual**: Copy only this skill to `~/.claude/skills/configure-ecc/SKILL.md`, then activate by saying "configure ecc" --- diff --git a/tests/docs/install-identifiers.test.js b/tests/docs/install-identifiers.test.js index 2a34f595..f6160b2f 100644 --- a/tests/docs/install-identifiers.test.js +++ b/tests/docs/install-identifiers.test.js @@ -35,12 +35,12 @@ console.log('\n=== Testing public install identifiers ===\n'); for (const relativePath of publicInstallDocs) { const content = fs.readFileSync(path.join(repoRoot, relativePath), 'utf8'); - test(`${relativePath} does not use the stale ecc@ecc plugin identifier`, () => { - assert.ok(!content.includes('ecc@ecc')); + test(`${relativePath} does not use the overlong legacy marketplace plugin identifier`, () => { + assert.ok(!content.includes('everything-claude-code@everything-claude-code')); }); - test(`${relativePath} documents the canonical marketplace plugin identifier`, () => { - assert.ok(content.includes('everything-claude-code@everything-claude-code')); + test(`${relativePath} documents the short marketplace plugin identifier`, () => { + assert.ok(content.includes('ecc@ecc')); }); } @@ -86,12 +86,12 @@ for (const relativePath of publicCommandNamespaceDocs) { test(`${relativePath} uses the canonical plugin command namespace`, () => { assert.ok( - !content.includes('/ecc:'), - 'Expected docs not to advertise the unsupported /ecc: plugin alias' + !content.includes('/everything-claude-code:'), + 'Expected docs not to advertise the overlong legacy plugin command namespace' ); assert.ok( - content.includes('/everything-claude-code:plan'), - 'Expected docs to show the canonical plugin command namespace' + content.includes('/ecc:plan'), + 'Expected docs to show the short plugin command namespace' ); }); } diff --git a/tests/lib/install-manifests.test.js b/tests/lib/install-manifests.test.js index b987ab1c..7c2ee5bc 100644 --- a/tests/lib/install-manifests.test.js +++ b/tests/lib/install-manifests.test.js @@ -145,6 +145,23 @@ function runTests() { assert.match(component.description, /continuous-learning-v2/, 'Should point new installs to continuous-learning-v2'); })) passed++; else failed++; + if (test('exposes continuous-learning-v2 as a single-skill install surface', () => { + const component = getInstallComponent('skill:continuous-learning-v2'); + assert.strictEqual(component.id, 'skill:continuous-learning-v2'); + assert.deepStrictEqual(component.moduleIds, ['skill-continuous-learning-v2']); + assert.ok(component.targets.includes('claude'), 'Should support Claude installs'); + + const plan = resolveInstallPlan({ + includeComponentIds: ['skill:continuous-learning-v2'], + target: 'claude', + }); + assert.deepStrictEqual(plan.selectedModuleIds, ['skill-continuous-learning-v2']); + assert.ok( + plan.operations.some(operation => operation.sourceRelativePath === 'skills/continuous-learning-v2'), + 'Should plan only the continuous-learning-v2 skill path' + ); + })) passed++; else failed++; + if (test('lists supported legacy compatibility languages', () => { const languages = listLegacyCompatibilityLanguages(); assert.ok(languages.includes('typescript')); diff --git a/tests/lib/selective-install.test.js b/tests/lib/selective-install.test.js index 58fc363d..226d2af2 100644 --- a/tests/lib/selective-install.test.js +++ b/tests/lib/selective-install.test.js @@ -81,6 +81,25 @@ function runTests() { ]); })) passed++; else failed++; + if (test('parses --skills as skill component selections', () => { + const parsed = parseInstallArgs([ + 'node', 'install-apply.js', + '--skills', 'continuous-learning-v2,security-review', + ]); + assert.deepStrictEqual(parsed.includeComponentIds, [ + 'skill:continuous-learning-v2', + 'skill:security-review', + ]); + })) passed++; else failed++; + + if (test('parses --skill when caller already includes the skill: prefix', () => { + const parsed = parseInstallArgs([ + 'node', 'install-apply.js', + '--skill', 'skill:continuous-learning-v2', + ]); + assert.deepStrictEqual(parsed.includeComponentIds, ['skill:continuous-learning-v2']); + })) passed++; else failed++; + if (test('parses multiple --without flags', () => { const parsed = parseInstallArgs([ 'node', 'install-apply.js', @@ -244,6 +263,7 @@ function runTests() { const components = listInstallComponents({ family: 'skill' }); assert.ok(components.length > 0, 'Should have at least one skill component'); assert.ok(components.some(c => c.id === 'skill:continuous-learning'), 'Should have skill:continuous-learning'); + assert.ok(components.some(c => c.id === 'skill:continuous-learning-v2'), 'Should have skill:continuous-learning-v2'); })) passed++; else failed++; // ─── Install Plan Resolution with --with ─── @@ -430,6 +450,22 @@ function runTests() { 'Should include workflow-quality module from skill:continuous-learning'); })) passed++; else failed++; + if (test('--with skill:continuous-learning-v2 installs only that skill module', () => { + const plan = resolveInstallPlan({ + includeComponentIds: ['skill:continuous-learning-v2'], + target: 'claude', + }); + assert.deepStrictEqual(plan.selectedModuleIds, ['skill-continuous-learning-v2']); + assert.ok( + plan.operations.some(operation => operation.sourceRelativePath === 'skills/continuous-learning-v2'), + 'Should install the continuous-learning-v2 skill directory' + ); + assert.ok( + !plan.operations.some(operation => operation.sourceRelativePath === 'skills/tdd-workflow'), + 'Should not install the whole workflow-quality skill module' + ); + })) passed++; else failed++; + // ─── Help Text ─── if (test('help text documents --with and --without flags', () => { @@ -670,6 +706,43 @@ function runTests() { } })) passed++; else failed++; + if (test('end-to-end: --skills continuous-learning-v2 installs only that skill', () => { + const { execFileSync } = require('child_process'); + const scriptPath = path.join(__dirname, '..', '..', 'scripts', 'install-apply.js'); + const homeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'selective-skill-install-')); + const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'selective-skill-install-project-')); + + try { + execFileSync('node', [ + scriptPath, + '--skills', 'continuous-learning-v2', + ], { + cwd: projectDir, + env: { ...process.env, HOME: homeDir }, + encoding: 'utf8', + stdio: ['pipe', 'pipe', 'pipe'], + }); + + const claudeRoot = path.join(homeDir, '.claude'); + assert.ok( + fs.existsSync(path.join(claudeRoot, 'skills', 'ecc', 'continuous-learning-v2', 'SKILL.md')), + 'Should install continuous-learning-v2' + ); + assert.ok( + !fs.existsSync(path.join(claudeRoot, 'skills', 'ecc', 'tdd-workflow', 'SKILL.md')), + 'Should not install unrelated workflow-quality skills' + ); + + const statePath = path.join(claudeRoot, 'ecc', 'install-state.json'); + const state = JSON.parse(fs.readFileSync(statePath, 'utf8')); + assert.deepStrictEqual(state.request.includeComponents, ['skill:continuous-learning-v2']); + assert.deepStrictEqual(state.resolution.selectedModules, ['skill-continuous-learning-v2']); + } finally { + fs.rmSync(homeDir, { recursive: true, force: true }); + fs.rmSync(projectDir, { recursive: true, force: true }); + } + })) passed++; else failed++; + // ─── JSON output mode ─── if (test('end-to-end: --dry-run --json includes component selections in output', () => { diff --git a/tests/plugin-manifest.test.js b/tests/plugin-manifest.test.js index 0adcb33e..5c8a0358 100644 --- a/tests/plugin-manifest.test.js +++ b/tests/plugin-manifest.test.js @@ -206,8 +206,8 @@ test('claude plugin.json version matches package.json', () => { assert.strictEqual(claudePlugin.version, expectedVersion); }); -test('claude plugin.json uses published plugin name', () => { - assert.strictEqual(claudePlugin.name, 'everything-claude-code'); +test('claude plugin.json uses short plugin slug', () => { + assert.strictEqual(claudePlugin.name, 'ecc'); }); test('claude plugin.json does NOT have agents field (unsupported by Claude Code validator)', () => { @@ -226,7 +226,8 @@ test('claude plugin.json commands is an array', () => { }); test('claude plugin.json disables bundled MCP servers for provider tool-name compatibility', () => { - const reportedOverlongToolName = `mcp__plugin_${claudePlugin.name}_github__create_pull_request_review`; + const legacyPluginName = 'everything-claude-code'; + const reportedOverlongToolName = `mcp__plugin_${legacyPluginName}_github__create_pull_request_review`; assert.ok( reportedOverlongToolName.length > 64, @@ -270,8 +271,8 @@ test('claude marketplace.json keeps only Claude-supported top-level keys', () => test('claude marketplace.json has plugins array with the published plugin entry', () => { assert.ok(Array.isArray(claudeMarketplace.plugins) && claudeMarketplace.plugins.length > 0, 'Expected plugins array'); - assert.strictEqual(claudeMarketplace.name, 'everything-claude-code'); - assert.strictEqual(claudeMarketplace.plugins[0].name, 'everything-claude-code'); + assert.strictEqual(claudeMarketplace.name, 'ecc'); + assert.strictEqual(claudeMarketplace.plugins[0].name, 'ecc'); }); test('claude marketplace.json plugin version matches package.json', () => { @@ -466,18 +467,18 @@ test('README version row matches package.json', () => { assert.strictEqual(match[1], expectedVersion); }); -test('user-facing docs do not use deprecated ecc@ecc install commands', () => { +test('user-facing docs do not use overlong legacy marketplace install commands', () => { const markdownFiles = [ path.join(repoRoot, 'README.md'), path.join(repoRoot, 'README.zh-CN.md'), path.join(repoRoot, 'skills', 'configure-ecc', 'SKILL.md'), ...collectMarkdownFiles(path.join(repoRoot, 'docs')), - ]; + ].filter(filePath => !path.relative(repoRoot, filePath).startsWith(`docs${path.sep}drafts${path.sep}`)); const offenders = []; for (const filePath of markdownFiles) { const source = fs.readFileSync(filePath, 'utf8'); - if (/\/plugin\s+(install|list)\s+ecc@ecc\b/.test(source)) { + if (/\/plugin\s+(install|list)\s+everything-claude-code(?:@everything-claude-code)?\b/.test(source)) { offenders.push(path.relative(repoRoot, filePath)); } } @@ -485,7 +486,7 @@ test('user-facing docs do not use deprecated ecc@ecc install commands', () => { assert.deepStrictEqual( offenders, [], - `Deprecated ecc@ecc install commands must not appear in user-facing docs: ${offenders.join(', ')}`, + `Overlong legacy install commands must not appear in user-facing docs: ${offenders.join(', ')}`, ); }); diff --git a/tests/scripts/install-plan.test.js b/tests/scripts/install-plan.test.js index c0d14034..d1823024 100644 --- a/tests/scripts/install-plan.test.js +++ b/tests/scripts/install-plan.test.js @@ -109,6 +109,20 @@ function runTests() { assert.ok(parsed.operations.length > 0); })) passed++; else failed++; + if (test('emits JSON for --skills without pulling parent module', () => { + const result = run([ + '--skills', 'continuous-learning-v2', + '--target', 'claude', + '--json', + ]); + assert.strictEqual(result.code, 0); + const parsed = JSON.parse(result.stdout); + assert.deepStrictEqual(parsed.includedComponentIds, ['skill:continuous-learning-v2']); + assert.deepStrictEqual(parsed.selectedModuleIds, ['skill-continuous-learning-v2']); + assert.ok(parsed.operations.some(operation => operation.sourceRelativePath === 'skills/continuous-learning-v2')); + assert.ok(!parsed.operations.some(operation => operation.sourceRelativePath === 'skills/tdd-workflow')); + })) passed++; else failed++; + if (test('loads planning intent from ecc-install.json', () => { const configDir = path.join(__dirname, '..', 'fixtures', 'tmp-install-plan-config'); const configPath = path.join(configDir, 'ecc-install.json');