mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-10 17:59:43 +08:00
fix: shorten plugin slug to ecc
This commit is contained in:
parent
908116d736
commit
1346f83b08
@ -1,11 +1,11 @@
|
|||||||
{
|
{
|
||||||
"name": "everything-claude-code",
|
"name": "ecc",
|
||||||
"interface": {
|
"interface": {
|
||||||
"displayName": "Everything Claude Code"
|
"displayName": "Everything Claude Code"
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
"name": "everything-claude-code",
|
"name": "ecc",
|
||||||
"source": {
|
"source": {
|
||||||
"source": "local",
|
"source": "local",
|
||||||
"path": "../.."
|
"path": "../.."
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
|
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
|
||||||
"name": "everything-claude-code",
|
"name": "ecc",
|
||||||
"description": "Battle-tested Claude Code configurations from an Anthropic hackathon winner — agents, skills, hooks, rules, and legacy command shims evolved over 10+ months of intensive daily use",
|
"description": "Battle-tested Claude Code configurations from an Anthropic hackathon winner — agents, skills, hooks, rules, and legacy command shims evolved over 10+ months of intensive daily use",
|
||||||
"owner": {
|
"owner": {
|
||||||
"name": "Affaan Mustafa",
|
"name": "Affaan Mustafa",
|
||||||
@ -11,7 +11,7 @@
|
|||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
"name": "everything-claude-code",
|
"name": "ecc",
|
||||||
"source": "./",
|
"source": "./",
|
||||||
"description": "The most comprehensive Claude Code plugin — 38 agents, 156 skills, 72 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 — 38 agents, 156 skills, 72 legacy command shims, selective install profiles, and production-ready hooks for TDD, security scanning, code review, and continuous learning",
|
||||||
"version": "1.10.0",
|
"version": "1.10.0",
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "everything-claude-code",
|
"name": "ecc",
|
||||||
"version": "1.10.0",
|
"version": "1.10.0",
|
||||||
"description": "Battle-tested Claude Code plugin for engineering teams — 38 agents, 156 skills, 72 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 — 38 agents, 156 skills, 72 legacy command shims, production-ready hooks, and selective install workflows evolved through continuous real-world use",
|
||||||
"author": {
|
"author": {
|
||||||
|
|||||||
@ -30,6 +30,9 @@ codex plugin install ./
|
|||||||
Run this from the repository root so `./` points to the repo root and `.mcp.json` resolves correctly.
|
Run this from the repository root so `./` points to the repo root and `.mcp.json` resolves correctly.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The installed plugin registers under the short slug `ecc` so tool and command names
|
||||||
|
stay below provider length limits.
|
||||||
|
|
||||||
## MCP Servers Included
|
## MCP Servers Included
|
||||||
|
|
||||||
| Server | Purpose |
|
| Server | Purpose |
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "everything-claude-code",
|
"name": "ecc",
|
||||||
"version": "1.10.0",
|
"version": "1.10.0",
|
||||||
"description": "Battle-tested Codex workflows — 156 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 — 156 shared ECC skills, production-ready MCP configs, and selective-install-aligned conventions for TDD, security scanning, code review, and autonomous development.",
|
||||||
"author": {
|
"author": {
|
||||||
|
|||||||
20
README.md
20
README.md
@ -173,7 +173,7 @@ Get up and running in under 2 minutes:
|
|||||||
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
||||||
|
|
||||||
# Install plugin
|
# Install plugin
|
||||||
/plugin install everything-claude-code@everything-claude-code
|
/plugin install ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 2: Install Rules (Required)
|
### Step 2: Install Rules (Required)
|
||||||
@ -227,13 +227,13 @@ For manual install instructions see the README in the `rules/` folder. When copy
|
|||||||
# Existing slash-style command names still work while ECC migrates off commands/.
|
# Existing slash-style command names still work while ECC migrates off commands/.
|
||||||
|
|
||||||
# Plugin install uses the namespaced form
|
# Plugin install uses the namespaced form
|
||||||
/everything-claude-code:plan "Add user authentication"
|
/ecc:plan "Add user authentication"
|
||||||
|
|
||||||
# Manual install keeps the shorter slash form:
|
# Manual install keeps the shorter slash form:
|
||||||
# /plan "Add user authentication"
|
# /plan "Add user authentication"
|
||||||
|
|
||||||
# Check available commands
|
# Check available commands
|
||||||
/plugin list everything-claude-code@everything-claude-code
|
/plugin list ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
**That's it!** You now have access to 38 agents, 159 skills, and 72 legacy command shims.
|
**That's it!** You now have access to 38 agents, 159 skills, and 72 legacy command shims.
|
||||||
@ -621,7 +621,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
|
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
||||||
|
|
||||||
# Install the plugin
|
# Install the plugin
|
||||||
/plugin install everything-claude-code@everything-claude-code
|
/plugin install ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
Or add directly to your `~/.claude/settings.json`:
|
Or add directly to your `~/.claude/settings.json`:
|
||||||
@ -629,7 +629,7 @@ Or add directly to your `~/.claude/settings.json`:
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"extraKnownMarketplaces": {
|
"extraKnownMarketplaces": {
|
||||||
"everything-claude-code": {
|
"ecc": {
|
||||||
"source": {
|
"source": {
|
||||||
"source": "github",
|
"source": "github",
|
||||||
"repo": "affaan-m/everything-claude-code"
|
"repo": "affaan-m/everything-claude-code"
|
||||||
@ -637,7 +637,7 @@ Or add directly to your `~/.claude/settings.json`:
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"enabledPlugins": {
|
"enabledPlugins": {
|
||||||
"everything-claude-code@everything-claude-code": true
|
"ecc@ecc": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -781,8 +781,8 @@ Not sure where to start? Use this quick reference. Skills are the canonical work
|
|||||||
|
|
||||||
| I want to... | Use this command | Agent used |
|
| I want to... | Use this command | Agent used |
|
||||||
|--------------|-----------------|------------|
|
|--------------|-----------------|------------|
|
||||||
| Plan a new feature | `/everything-claude-code:plan "Add auth"` | planner |
|
| Plan a new feature | `/ecc:plan "Add auth"` | planner |
|
||||||
| Design system architecture | `/everything-claude-code:plan` + architect agent | architect |
|
| Design system architecture | `/ecc:plan` + architect agent | architect |
|
||||||
| Write code with tests first | `/tdd` | tdd-guide |
|
| Write code with tests first | `/tdd` | tdd-guide |
|
||||||
| Review code I just wrote | `/code-review` | code-reviewer |
|
| Review code I just wrote | `/code-review` | code-reviewer |
|
||||||
| Fix a failing build | `/build-fix` | build-error-resolver |
|
| Fix a failing build | `/build-fix` | build-error-resolver |
|
||||||
@ -801,7 +801,7 @@ Slash forms below are shown because they are still the fastest familiar entrypoi
|
|||||||
|
|
||||||
**Starting a new feature:**
|
**Starting a new feature:**
|
||||||
```
|
```
|
||||||
/everything-claude-code:plan "Add user authentication with OAuth"
|
/ecc:plan "Add user authentication with OAuth"
|
||||||
→ planner creates implementation blueprint
|
→ planner creates implementation blueprint
|
||||||
/tdd → tdd-guide enforces write-tests-first
|
/tdd → tdd-guide enforces write-tests-first
|
||||||
/code-review → code-reviewer checks your work
|
/code-review → code-reviewer checks your work
|
||||||
@ -829,7 +829,7 @@ Slash forms below are shown because they are still the fastest familiar entrypoi
|
|||||||
<summary><b>How do I check which agents/commands are installed?</b></summary>
|
<summary><b>How do I check which agents/commands are installed?</b></summary>
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/plugin list everything-claude-code@everything-claude-code
|
/plugin list ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
This shows all available agents, commands, and skills from the plugin.
|
This shows all available agents, commands, and skills from the plugin.
|
||||||
|
|||||||
@ -71,7 +71,7 @@
|
|||||||
/plugin marketplace add affaan-m/everything-claude-code
|
/plugin marketplace add affaan-m/everything-claude-code
|
||||||
|
|
||||||
# 安装插件
|
# 安装插件
|
||||||
/plugin install everything-claude-code@everything-claude-code
|
/plugin install ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
### 第二步:安装规则(必需)
|
### 第二步:安装规则(必需)
|
||||||
@ -97,13 +97,13 @@ cp -r everything-claude-code/rules/perl ~/.claude/rules/
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 尝试一个命令(插件安装使用命名空间形式)
|
# 尝试一个命令(插件安装使用命名空间形式)
|
||||||
/everything-claude-code:plan "添加用户认证"
|
/ecc:plan "添加用户认证"
|
||||||
|
|
||||||
# 手动安装(选项2)使用简短形式:
|
# 手动安装(选项2)使用简短形式:
|
||||||
# /plan "添加用户认证"
|
# /plan "添加用户认证"
|
||||||
|
|
||||||
# 查看可用命令
|
# 查看可用命令
|
||||||
/plugin list everything-claude-code@everything-claude-code
|
/plugin list ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
**完成!** 你现在可以使用 38 个代理、159 个技能和 72 个命令。
|
**完成!** 你现在可以使用 38 个代理、159 个技能和 72 个命令。
|
||||||
@ -339,7 +339,7 @@ everything-claude-code/
|
|||||||
/plugin marketplace add affaan-m/everything-claude-code
|
/plugin marketplace add affaan-m/everything-claude-code
|
||||||
|
|
||||||
# 安装插件
|
# 安装插件
|
||||||
/plugin install everything-claude-code@everything-claude-code
|
/plugin install ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
或直接添加到你的 `~/.claude/settings.json`:
|
或直接添加到你的 `~/.claude/settings.json`:
|
||||||
@ -347,7 +347,7 @@ everything-claude-code/
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"extraKnownMarketplaces": {
|
"extraKnownMarketplaces": {
|
||||||
"everything-claude-code": {
|
"ecc": {
|
||||||
"source": {
|
"source": {
|
||||||
"source": "github",
|
"source": "github",
|
||||||
"repo": "affaan-m/everything-claude-code"
|
"repo": "affaan-m/everything-claude-code"
|
||||||
@ -355,7 +355,7 @@ everything-claude-code/
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"enabledPlugins": {
|
"enabledPlugins": {
|
||||||
"everything-claude-code@everything-claude-code": true
|
"ecc@ecc": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@ -370,7 +370,7 @@ chmod -R u+rwX,go+rX ~/.claude/homunculus
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Install plugin dependencies
|
# Install plugin dependencies
|
||||||
cd ~/.claude/plugins/cache/everything-claude-code
|
cd ~/.claude/plugins/cache/ecc
|
||||||
npm install
|
npm install
|
||||||
|
|
||||||
# Or for manual install
|
# Or for manual install
|
||||||
|
|||||||
@ -11,6 +11,7 @@ Public ECC plugin repo for agents, skills, commands, hooks, rules, install surfa
|
|||||||
- Default branch: `main`
|
- Default branch: `main`
|
||||||
- Public release surface is aligned at `v1.10.0`
|
- Public release surface is aligned at `v1.10.0`
|
||||||
- Public catalog truth is `38` agents, `72` commands, and `159` skills
|
- Public catalog truth is `38` agents, `72` commands, and `159` skills
|
||||||
|
- Public plugin slug is now `ecc`; legacy `everything-claude-code` install paths remain supported for compatibility
|
||||||
- Release discussion: `#1272`
|
- Release discussion: `#1272`
|
||||||
- ECC 2.0 exists in-tree and builds, but it is still alpha rather than GA
|
- ECC 2.0 exists in-tree and builds, but it is still alpha rather than GA
|
||||||
- Main active operational work:
|
- Main active operational work:
|
||||||
|
|||||||
@ -110,7 +110,7 @@
|
|||||||
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
||||||
|
|
||||||
# プラグインをインストール
|
# プラグインをインストール
|
||||||
/plugin install everything-claude-code@everything-claude-code
|
/plugin install ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
### ステップ2:ルールをインストール(必須)
|
### ステップ2:ルールをインストール(必須)
|
||||||
@ -134,13 +134,13 @@ cp -r everything-claude-code/rules/golang/* ~/.claude/rules/
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# コマンドを試す(プラグインはネームスペース形式)
|
# コマンドを試す(プラグインはネームスペース形式)
|
||||||
/everything-claude-code:plan "ユーザー認証を追加"
|
/ecc:plan "ユーザー認証を追加"
|
||||||
|
|
||||||
# 手動インストール(オプション2)は短縮形式:
|
# 手動インストール(オプション2)は短縮形式:
|
||||||
# /plan "ユーザー認証を追加"
|
# /plan "ユーザー認証を追加"
|
||||||
|
|
||||||
# 利用可能なコマンドを確認
|
# 利用可能なコマンドを確認
|
||||||
/plugin list everything-claude-code@everything-claude-code
|
/plugin list ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
**完了です!** これで13のエージェント、43のスキル、31のコマンドにアクセスできます。
|
**完了です!** これで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 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` に直接追加:
|
または、`~/.claude/settings.json` に直接追加:
|
||||||
@ -435,7 +435,7 @@ Duplicate hook file detected: ./hooks/hooks.json is already resolved to a loaded
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"extraKnownMarketplaces": {
|
"extraKnownMarketplaces": {
|
||||||
"everything-claude-code": {
|
"ecc": {
|
||||||
"source": {
|
"source": {
|
||||||
"source": "github",
|
"source": "github",
|
||||||
"repo": "affaan-m/everything-claude-code"
|
"repo": "affaan-m/everything-claude-code"
|
||||||
@ -443,7 +443,7 @@ Duplicate hook file detected: ./hooks/hooks.json is already resolved to a loaded
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"enabledPlugins": {
|
"enabledPlugins": {
|
||||||
"everything-claude-code@everything-claude-code": true
|
"ecc@ecc": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@ -17,7 +17,7 @@ Everything Claude Code プロジェクトのインタラクティブなステッ
|
|||||||
## 前提条件
|
## 前提条件
|
||||||
|
|
||||||
このスキルは起動前に Claude Code からアクセス可能である必要があります。ブートストラップには2つの方法があります:
|
このスキルは起動前に Claude Code からアクセス可能である必要があります。ブートストラップには2つの方法があります:
|
||||||
1. **プラグイン経由**: `/plugin install everything-claude-code` — プラグインがこのスキルを自動的にロードします
|
1. **プラグイン経由**: `/plugin install ecc@ecc` — プラグインがこのスキルを自動的にロードします
|
||||||
2. **手動**: このスキルのみを `~/.claude/skills/configure-ecc/SKILL.md` にコピーし、"configure ecc" と言って起動します
|
2. **手動**: このスキルのみを `~/.claude/skills/configure-ecc/SKILL.md` にコピーし、"configure ecc" と言って起動します
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@ -115,7 +115,7 @@
|
|||||||
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
||||||
|
|
||||||
# 플러그인 설치
|
# 플러그인 설치
|
||||||
/plugin install everything-claude-code@everything-claude-code
|
/plugin install ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2단계: 룰 설치 (필수)
|
### 2단계: 룰 설치 (필수)
|
||||||
@ -141,13 +141,13 @@ cd everything-claude-code
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 커맨드 실행 (플러그인 설치 시 네임스페이스 형태 사용)
|
# 커맨드 실행 (플러그인 설치 시 네임스페이스 형태 사용)
|
||||||
/everything-claude-code:plan "사용자 인증 추가"
|
/ecc:plan "사용자 인증 추가"
|
||||||
|
|
||||||
# 수동 설치(옵션 2) 시에는 짧은 형태를 사용:
|
# 수동 설치(옵션 2) 시에는 짧은 형태를 사용:
|
||||||
# /plan "사용자 인증 추가"
|
# /plan "사용자 인증 추가"
|
||||||
|
|
||||||
# 사용 가능한 커맨드 확인
|
# 사용 가능한 커맨드 확인
|
||||||
/plugin list everything-claude-code@everything-claude-code
|
/plugin list ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
**끝!** 이제 16개 에이전트, 65개 스킬, 40개 커맨드를 사용할 수 있습니다.
|
**끝!** 이제 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 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`에 직접 추가:
|
또는 `~/.claude/settings.json`에 직접 추가:
|
||||||
@ -367,7 +367,7 @@ Claude Code v2.1+는 설치된 플러그인의 `hooks/hooks.json`을 **자동으
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"extraKnownMarketplaces": {
|
"extraKnownMarketplaces": {
|
||||||
"everything-claude-code": {
|
"ecc": {
|
||||||
"source": {
|
"source": {
|
||||||
"source": "github",
|
"source": "github",
|
||||||
"repo": "affaan-m/everything-claude-code"
|
"repo": "affaan-m/everything-claude-code"
|
||||||
@ -375,7 +375,7 @@ Claude Code v2.1+는 설치된 플러그인의 `hooks/hooks.json`을 **자동으
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"enabledPlugins": {
|
"enabledPlugins": {
|
||||||
"everything-claude-code@everything-claude-code": true
|
"ecc@ecc": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -489,8 +489,8 @@ rules/
|
|||||||
|
|
||||||
| 하고 싶은 것 | 사용할 커맨드 | 사용되는 에이전트 |
|
| 하고 싶은 것 | 사용할 커맨드 | 사용되는 에이전트 |
|
||||||
|-------------|-------------|-----------------|
|
|-------------|-------------|-----------------|
|
||||||
| 새 기능 계획하기 | `/everything-claude-code:plan "인증 추가"` | planner |
|
| 새 기능 계획하기 | `/ecc:plan "인증 추가"` | planner |
|
||||||
| 시스템 아키텍처 설계 | `/everything-claude-code:plan` + architect 에이전트 | architect |
|
| 시스템 아키텍처 설계 | `/ecc:plan` + architect 에이전트 | architect |
|
||||||
| 테스트를 먼저 작성하며 코딩 | `/tdd` | tdd-guide |
|
| 테스트를 먼저 작성하며 코딩 | `/tdd` | tdd-guide |
|
||||||
| 방금 작성한 코드 리뷰 | `/code-review` | code-reviewer |
|
| 방금 작성한 코드 리뷰 | `/code-review` | code-reviewer |
|
||||||
| 빌드 실패 수정 | `/build-fix` | build-error-resolver |
|
| 빌드 실패 수정 | `/build-fix` | build-error-resolver |
|
||||||
@ -507,7 +507,7 @@ rules/
|
|||||||
|
|
||||||
**새로운 기능 시작:**
|
**새로운 기능 시작:**
|
||||||
```
|
```
|
||||||
/everything-claude-code:plan "OAuth를 사용한 사용자 인증 추가"
|
/ecc:plan "OAuth를 사용한 사용자 인증 추가"
|
||||||
→ planner가 구현 청사진 작성
|
→ planner가 구현 청사진 작성
|
||||||
/tdd → tdd-guide가 테스트 먼저 작성 강제
|
/tdd → tdd-guide가 테스트 먼저 작성 강제
|
||||||
/code-review → code-reviewer가 코드 검토
|
/code-review → code-reviewer가 코드 검토
|
||||||
@ -535,7 +535,7 @@ rules/
|
|||||||
<summary><b>설치된 에이전트/커맨드 확인은 어떻게 하나요?</b></summary>
|
<summary><b>설치된 에이전트/커맨드 확인은 어떻게 하나요?</b></summary>
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/plugin list everything-claude-code@everything-claude-code
|
/plugin list ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
플러그인에서 사용할 수 있는 모든 에이전트, 커맨드, 스킬을 보여줍니다.
|
플러그인에서 사용할 수 있는 모든 에이전트, 커맨드, 스킬을 보여줍니다.
|
||||||
|
|||||||
@ -115,7 +115,7 @@ Comece em menos de 2 minutos:
|
|||||||
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
||||||
|
|
||||||
# Instalar plugin
|
# Instalar plugin
|
||||||
/plugin install everything-claude-code@everything-claude-code
|
/plugin install ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
### Passo 2: Instalar as Regras (Obrigatório)
|
### Passo 2: Instalar as Regras (Obrigatório)
|
||||||
@ -152,13 +152,13 @@ npx ecc-install typescript
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Experimente um comando (a instalação do plugin usa forma com namespace)
|
# 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:
|
# Instalação manual (Opção 2) usa a forma mais curta:
|
||||||
# /plan "Adicionar autenticação de usuário"
|
# /plan "Adicionar autenticação de usuário"
|
||||||
|
|
||||||
# Verificar comandos disponíveis
|
# 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.
|
**Pronto!** Você agora tem acesso a 28 agentes, 116 skills e 59 comandos.
|
||||||
@ -304,7 +304,7 @@ claude --version
|
|||||||
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
||||||
|
|
||||||
# Instalar o plugin
|
# Instalar o plugin
|
||||||
/plugin install everything-claude-code@everything-claude-code
|
/plugin install ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
Ou adicione diretamente ao seu `~/.claude/settings.json`:
|
Ou adicione diretamente ao seu `~/.claude/settings.json`:
|
||||||
@ -312,7 +312,7 @@ Ou adicione diretamente ao seu `~/.claude/settings.json`:
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"extraKnownMarketplaces": {
|
"extraKnownMarketplaces": {
|
||||||
"everything-claude-code": {
|
"ecc": {
|
||||||
"source": {
|
"source": {
|
||||||
"source": "github",
|
"source": "github",
|
||||||
"repo": "affaan-m/everything-claude-code"
|
"repo": "affaan-m/everything-claude-code"
|
||||||
@ -320,7 +320,7 @@ Ou adicione diretamente ao seu `~/.claude/settings.json`:
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"enabledPlugins": {
|
"enabledPlugins": {
|
||||||
"everything-claude-code@everything-claude-code": true
|
"ecc@ecc": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -399,8 +399,8 @@ Regras são diretrizes sempre seguidas, organizadas em `common/` (agnóstico à
|
|||||||
|
|
||||||
| Quero... | Use este comando | Agente usado |
|
| Quero... | Use este comando | Agente usado |
|
||||||
|----------|-----------------|--------------|
|
|----------|-----------------|--------------|
|
||||||
| Planejar um novo recurso | `/everything-claude-code:plan "Adicionar auth"` | planner |
|
| Planejar um novo recurso | `/ecc:plan "Adicionar auth"` | planner |
|
||||||
| Projetar arquitetura de sistema | `/everything-claude-code:plan` + agente architect | architect |
|
| Projetar arquitetura de sistema | `/ecc:plan` + agente architect | architect |
|
||||||
| Escrever código com testes primeiro | `/tdd` | tdd-guide |
|
| Escrever código com testes primeiro | `/tdd` | tdd-guide |
|
||||||
| Revisar código que acabei de escrever | `/code-review` | code-reviewer |
|
| Revisar código que acabei de escrever | `/code-review` | code-reviewer |
|
||||||
| Corrigir build com falha | `/build-fix` | build-error-resolver |
|
| Corrigir build com falha | `/build-fix` | build-error-resolver |
|
||||||
@ -415,7 +415,7 @@ Regras são diretrizes sempre seguidas, organizadas em `common/` (agnóstico à
|
|||||||
|
|
||||||
**Começando um novo recurso:**
|
**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
|
→ planner cria blueprint de implementação
|
||||||
/tdd → tdd-guide aplica escrita de testes primeiro
|
/tdd → tdd-guide aplica escrita de testes primeiro
|
||||||
/code-review → code-reviewer verifica seu trabalho
|
/code-review → code-reviewer verifica seu trabalho
|
||||||
@ -443,7 +443,7 @@ Regras são diretrizes sempre seguidas, organizadas em `common/` (agnóstico à
|
|||||||
<summary><b>Como verificar quais agentes/comandos estão instalados?</b></summary>
|
<summary><b>Como verificar quais agentes/comandos estão instalados?</b></summary>
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/plugin list everything-claude-code@everything-claude-code
|
/plugin list ecc@ecc
|
||||||
```
|
```
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|||||||
@ -116,7 +116,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 marketplace add https://github.com/affaan-m/everything-claude-code
|
||||||
|
|
||||||
# Plugin'i kur
|
# Plugin'i kur
|
||||||
/plugin install everything-claude-code@everything-claude-code
|
/plugin install ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
### Adım 2: Rule'ları Kurun (Gerekli)
|
### Adım 2: Rule'ları Kurun (Gerekli)
|
||||||
@ -155,13 +155,13 @@ Manuel kurulum talimatları için `rules/` klasöründeki README'ye bakın.
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Bir command deneyin (plugin kurulumu namespace'li form kullanır)
|
# 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:
|
# Manuel kurulum (Seçenek 2) daha kısa formu kullanır:
|
||||||
# /plan "Kullanıcı kimlik doğrulaması ekle"
|
# /plan "Kullanıcı kimlik doğrulaması ekle"
|
||||||
|
|
||||||
# Mevcut command'ları kontrol edin
|
# 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.
|
**Bu kadar!** Artık 28 agent, 116 skill ve 59 command'a erişiminiz var.
|
||||||
@ -299,8 +299,8 @@ Nereden başlayacağınızdan emin değil misiniz? Bu hızlı referansı kullan
|
|||||||
|
|
||||||
| Yapmak istediğim... | Bu command'ı kullan | Kullanılan agent |
|
| Yapmak istediğim... | Bu command'ı kullan | Kullanılan agent |
|
||||||
|---------------------|---------------------|------------------|
|
|---------------------|---------------------|------------------|
|
||||||
| Yeni bir feature planla | `/everything-claude-code:plan "Auth ekle"` | planner |
|
| Yeni bir feature planla | `/ecc:plan "Auth ekle"` | planner |
|
||||||
| Sistem mimarisi tasarla | `/everything-claude-code:plan` + architect agent | architect |
|
| Sistem mimarisi tasarla | `/ecc:plan` + architect agent | architect |
|
||||||
| Önce testlerle kod yaz | `/tdd` | tdd-guide |
|
| Önce testlerle kod yaz | `/tdd` | tdd-guide |
|
||||||
| Yazdığım kodu incele | `/code-review` | code-reviewer |
|
| Yazdığım kodu incele | `/code-review` | code-reviewer |
|
||||||
| Başarısız bir build'i düzelt | `/build-fix` | build-error-resolver |
|
| Başarısız bir build'i düzelt | `/build-fix` | build-error-resolver |
|
||||||
@ -315,7 +315,7 @@ Nereden başlayacağınızdan emin değil misiniz? Bu hızlı referansı kullan
|
|||||||
|
|
||||||
**Yeni bir feature başlatma:**
|
**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
|
→ planner implementasyon planı oluşturur
|
||||||
/tdd → tdd-guide önce-test-yaz'ı zorunlu kılar
|
/tdd → tdd-guide önce-test-yaz'ı zorunlu kılar
|
||||||
/code-review → code-reviewer çalışmanızı kontrol eder
|
/code-review → code-reviewer çalışmanızı kontrol eder
|
||||||
@ -343,7 +343,7 @@ Nereden başlayacağınızdan emin değil misiniz? Bu hızlı referansı kullan
|
|||||||
<summary><b>Hangi agent/command'ların kurulu olduğunu nasıl kontrol ederim?</b></summary>
|
<summary><b>Hangi agent/command'ların kurulu olduğunu nasıl kontrol ederim?</b></summary>
|
||||||
|
|
||||||
```bash
|
```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.
|
Bu, plugin'den mevcut tüm agent'ları, command'ları ve skill'leri gösterir.
|
||||||
|
|||||||
@ -370,7 +370,7 @@ chmod -R u+rwX,go+rX ~/.claude/homunculus
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Eklenti bağımlılıklarını kur
|
# Eklenti bağımlılıklarını kur
|
||||||
cd ~/.claude/plugins/cache/everything-claude-code
|
cd ~/.claude/plugins/cache/ecc
|
||||||
npm install
|
npm install
|
||||||
|
|
||||||
# Veya manuel kurulum için
|
# Veya manuel kurulum için
|
||||||
|
|||||||
@ -161,7 +161,7 @@
|
|||||||
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
||||||
|
|
||||||
# Install plugin
|
# Install plugin
|
||||||
/plugin install everything-claude-code@everything-claude-code
|
/plugin install ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
### 步骤 2:安装规则(必需)
|
### 步骤 2:安装规则(必需)
|
||||||
@ -200,13 +200,13 @@ npx ecc-install typescript
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Try a command (plugin install uses namespaced form)
|
# 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:
|
# Manual install (Option 2) uses the shorter form:
|
||||||
# /plan "Add user authentication"
|
# /plan "Add user authentication"
|
||||||
|
|
||||||
# Check available commands
|
# Check available commands
|
||||||
/plugin list everything-claude-code@everything-claude-code
|
/plugin list ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
**搞定!** 你现在可以使用 38 个智能体、159 项技能和 72 个命令了。
|
**搞定!** 你现在可以使用 38 个智能体、159 项技能和 72 个命令了。
|
||||||
@ -585,7 +585,7 @@ Claude Code v2.1+ **会自动加载** 任何已安装插件中的 `hooks/hooks.j
|
|||||||
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
||||||
|
|
||||||
# Install the plugin
|
# Install the plugin
|
||||||
/plugin install everything-claude-code@everything-claude-code
|
/plugin install ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
或者直接添加到您的 `~/.claude/settings.json`:
|
或者直接添加到您的 `~/.claude/settings.json`:
|
||||||
@ -593,7 +593,7 @@ Claude Code v2.1+ **会自动加载** 任何已安装插件中的 `hooks/hooks.j
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"extraKnownMarketplaces": {
|
"extraKnownMarketplaces": {
|
||||||
"everything-claude-code": {
|
"ecc": {
|
||||||
"source": {
|
"source": {
|
||||||
"source": "github",
|
"source": "github",
|
||||||
"repo": "affaan-m/everything-claude-code"
|
"repo": "affaan-m/everything-claude-code"
|
||||||
@ -601,7 +601,7 @@ Claude Code v2.1+ **会自动加载** 任何已安装插件中的 `hooks/hooks.j
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"enabledPlugins": {
|
"enabledPlugins": {
|
||||||
"everything-claude-code@everything-claude-code": true
|
"ecc@ecc": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -744,8 +744,8 @@ rules/
|
|||||||
|
|
||||||
| 我想要... | 使用此命令 | 使用的智能体 |
|
| 我想要... | 使用此命令 | 使用的智能体 |
|
||||||
|--------------|-----------------|------------|
|
|--------------|-----------------|------------|
|
||||||
| 规划新功能 | `/everything-claude-code:plan "Add auth"` | planner |
|
| 规划新功能 | `/ecc:plan "Add auth"` | planner |
|
||||||
| 设计系统架构 | `/everything-claude-code:plan` + architect agent | architect |
|
| 设计系统架构 | `/ecc:plan` + architect agent | architect |
|
||||||
| 先写测试再写代码 | `/tdd` | tdd-guide |
|
| 先写测试再写代码 | `/tdd` | tdd-guide |
|
||||||
| 评审我刚写的代码 | `/code-review` | code-reviewer |
|
| 评审我刚写的代码 | `/code-review` | code-reviewer |
|
||||||
| 修复失败的构建 | `/build-fix` | build-error-resolver |
|
| 修复失败的构建 | `/build-fix` | build-error-resolver |
|
||||||
@ -763,7 +763,7 @@ rules/
|
|||||||
**开始新功能:**
|
**开始新功能:**
|
||||||
|
|
||||||
```
|
```
|
||||||
/everything-claude-code:plan "使用 OAuth 添加用户身份验证"
|
/ecc:plan "使用 OAuth 添加用户身份验证"
|
||||||
→ 规划器创建实现蓝图
|
→ 规划器创建实现蓝图
|
||||||
/tdd → tdd-guide 强制执行先写测试
|
/tdd → tdd-guide 强制执行先写测试
|
||||||
/code-review → 代码审查员检查你的工作
|
/code-review → 代码审查员检查你的工作
|
||||||
@ -793,7 +793,7 @@ rules/
|
|||||||
<summary><b>如何检查已安装的代理/命令?</b></summary>
|
<summary><b>如何检查已安装的代理/命令?</b></summary>
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
/plugin list everything-claude-code@everything-claude-code
|
/plugin list ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
这会显示插件中所有可用的代理、命令和技能。
|
这会显示插件中所有可用的代理、命令和技能。
|
||||||
|
|||||||
@ -394,7 +394,7 @@ chmod -R u+rwX,go+rX ~/.claude/homunculus
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Install plugin dependencies
|
# Install plugin dependencies
|
||||||
cd ~/.claude/plugins/cache/everything-claude-code
|
cd ~/.claude/plugins/cache/ecc
|
||||||
npm install
|
npm install
|
||||||
|
|
||||||
# Or for manual install
|
# Or for manual install
|
||||||
|
|||||||
@ -19,7 +19,7 @@ origin: ECC
|
|||||||
|
|
||||||
此技能必须在激活前对 Claude Code 可访问。有两种引导方式:
|
此技能必须在激活前对 Claude Code 可访问。有两种引导方式:
|
||||||
|
|
||||||
1. **通过插件**: `/plugin install everything-claude-code` — 插件会自动加载此技能
|
1. **通过插件**: `/plugin install ecc@ecc` — 插件会自动加载此技能
|
||||||
2. **手动**: 仅将此技能复制到 `~/.claude/skills/configure-ecc/SKILL.md`,然后通过说 "configure ecc" 激活
|
2. **手动**: 仅将此技能复制到 `~/.claude/skills/configure-ecc/SKILL.md`,然后通过说 "configure ecc" 激活
|
||||||
|
|
||||||
***
|
***
|
||||||
|
|||||||
@ -70,7 +70,7 @@
|
|||||||
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
||||||
|
|
||||||
# 安裝外掛程式
|
# 安裝外掛程式
|
||||||
/plugin install everything-claude-code@everything-claude-code
|
/plugin install ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
### 第二步:安裝規則(必需)
|
### 第二步:安裝規則(必需)
|
||||||
@ -89,13 +89,13 @@ cp -r everything-claude-code/rules/* ~/.claude/rules/
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 嘗試一個指令(外掛安裝使用命名空間形式)
|
# 嘗試一個指令(外掛安裝使用命名空間形式)
|
||||||
/everything-claude-code:plan "新增使用者認證"
|
/ecc:plan "新增使用者認證"
|
||||||
|
|
||||||
# 手動安裝(選項2)使用簡短形式:
|
# 手動安裝(選項2)使用簡短形式:
|
||||||
# /plan "新增使用者認證"
|
# /plan "新增使用者認證"
|
||||||
|
|
||||||
# 查看可用指令
|
# 查看可用指令
|
||||||
/plugin list everything-claude-code@everything-claude-code
|
/plugin list ecc@ecc
|
||||||
```
|
```
|
||||||
|
|
||||||
**完成!** 您現在使用 15+ 代理程式、30+ 技能和 20+ 指令。
|
**完成!** 您現在使用 15+ 代理程式、30+ 技能和 20+ 指令。
|
||||||
@ -270,7 +270,7 @@ everything-claude-code/
|
|||||||
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
/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`:
|
或直接新增到您的 `~/.claude/settings.json`:
|
||||||
@ -278,7 +278,7 @@ everything-claude-code/
|
|||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"extraKnownMarketplaces": {
|
"extraKnownMarketplaces": {
|
||||||
"everything-claude-code": {
|
"ecc": {
|
||||||
"source": {
|
"source": {
|
||||||
"source": "github",
|
"source": "github",
|
||||||
"repo": "affaan-m/everything-claude-code"
|
"repo": "affaan-m/everything-claude-code"
|
||||||
@ -286,7 +286,7 @@ everything-claude-code/
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"enabledPlugins": {
|
"enabledPlugins": {
|
||||||
"everything-claude-code@everything-claude-code": true
|
"ecc@ecc": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@ -305,7 +305,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const fs=require('fs');const path=require('path');const {spawnSync}=require('child_process');const raw=fs.readFileSync(0,'utf8');const rel=path.join('scripts','hooks','run-with-flags.js');const hasRunnerRoot=candidate=>{const value=typeof candidate==='string'?candidate.trim():'';return value.length>0&&fs.existsSync(path.join(path.resolve(value),rel));};const root=(()=>{const envRoot=process.env.CLAUDE_PLUGIN_ROOT||'';if(hasRunnerRoot(envRoot))return path.resolve(envRoot.trim());const home=require('os').homedir();const claudeDir=path.join(home,'.claude');if(hasRunnerRoot(claudeDir))return claudeDir;for(const candidate of [path.join(claudeDir,'plugins','everything-claude-code'),path.join(claudeDir,'plugins','everything-claude-code@everything-claude-code'),path.join(claudeDir,'plugins','marketplace','everything-claude-code')]){if(hasRunnerRoot(candidate))return candidate;}try{const cacheBase=path.join(claudeDir,'plugins','cache','everything-claude-code');for(const org of fs.readdirSync(cacheBase,{withFileTypes:true})){if(!org.isDirectory())continue;for(const version of fs.readdirSync(path.join(cacheBase,org.name),{withFileTypes:true})){if(!version.isDirectory())continue;const candidate=path.join(cacheBase,org.name,version.name);if(hasRunnerRoot(candidate))return candidate;}}}catch{}return claudeDir;})();const script=path.join(root,rel);if(fs.existsSync(script)){const result=spawnSync(process.execPath,[script,'stop:format-typecheck','scripts/hooks/stop-format-typecheck.js','standard,strict'],{input:raw,encoding:'utf8',env:process.env,cwd:process.cwd(),timeout:300000});const stdout=typeof result.stdout==='string'?result.stdout:'';if(stdout)process.stdout.write(stdout);else process.stdout.write(raw);if(result.stderr)process.stderr.write(result.stderr);if(result.error||result.status===null||result.signal){const reason=result.error?result.error.message:(result.signal?'signal '+result.signal:'missing exit status');process.stderr.write('[Stop] ERROR: hook runner failed: '+reason+String.fromCharCode(10));process.exit(1);}process.exit(Number.isInteger(result.status)?result.status:0);}process.stderr.write('[Stop] WARNING: could not resolve ECC plugin root; skipping hook'+String.fromCharCode(10));process.stdout.write(raw);\"",
|
"command": "node -e \"const fs=require('fs');const path=require('path');const {spawnSync}=require('child_process');const raw=fs.readFileSync(0,'utf8');const rel=path.join('scripts','hooks','run-with-flags.js');const hasRunnerRoot=candidate=>{const value=typeof candidate==='string'?candidate.trim():'';return value.length>0&&fs.existsSync(path.join(path.resolve(value),rel));};const root=(()=>{const envRoot=process.env.CLAUDE_PLUGIN_ROOT||'';if(hasRunnerRoot(envRoot))return path.resolve(envRoot.trim());const home=require('os').homedir();const claudeDir=path.join(home,'.claude');if(hasRunnerRoot(claudeDir))return claudeDir;for(const candidate of [path.join(claudeDir,'plugins','ecc'),path.join(claudeDir,'plugins','ecc@ecc'),path.join(claudeDir,'plugins','marketplace','ecc'),path.join(claudeDir,'plugins','everything-claude-code'),path.join(claudeDir,'plugins','everything-claude-code@everything-claude-code'),path.join(claudeDir,'plugins','marketplace','everything-claude-code')]){if(hasRunnerRoot(candidate))return candidate;}try{for(const slug of ['ecc','everything-claude-code']){const cacheBase=path.join(claudeDir,'plugins','cache',slug);for(const org of fs.readdirSync(cacheBase,{withFileTypes:true})){if(!org.isDirectory())continue;for(const version of fs.readdirSync(path.join(cacheBase,org.name),{withFileTypes:true})){if(!version.isDirectory())continue;const candidate=path.join(cacheBase,org.name,version.name);if(hasRunnerRoot(candidate))return candidate;}}}}catch{}return claudeDir;})();const script=path.join(root,rel);if(fs.existsSync(script)){const result=spawnSync(process.execPath,[script,'stop:format-typecheck','scripts/hooks/stop-format-typecheck.js','standard,strict'],{input:raw,encoding:'utf8',env:process.env,cwd:process.cwd(),timeout:300000});const stdout=typeof result.stdout==='string'?result.stdout:'';if(stdout)process.stdout.write(stdout);else process.stdout.write(raw);if(result.stderr)process.stderr.write(result.stderr);if(result.error||result.status===null||result.signal){const reason=result.error?result.error.message:(result.signal?'signal '+result.signal:'missing exit status');process.stderr.write('[Stop] ERROR: hook runner failed: '+reason+String.fromCharCode(10));process.exit(1);}process.exit(Number.isInteger(result.status)?result.status:0);}process.stderr.write('[Stop] WARNING: could not resolve ECC plugin root; skipping hook'+String.fromCharCode(10));process.stdout.write(raw);\"",
|
||||||
"timeout": 300
|
"timeout": 300
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@ -317,7 +317,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const fs=require('fs');const path=require('path');const {spawnSync}=require('child_process');const raw=fs.readFileSync(0,'utf8');const rel=path.join('scripts','hooks','run-with-flags.js');const hasRunnerRoot=candidate=>{const value=typeof candidate==='string'?candidate.trim():'';return value.length>0&&fs.existsSync(path.join(path.resolve(value),rel));};const root=(()=>{const envRoot=process.env.CLAUDE_PLUGIN_ROOT||'';if(hasRunnerRoot(envRoot))return path.resolve(envRoot.trim());const home=require('os').homedir();const claudeDir=path.join(home,'.claude');if(hasRunnerRoot(claudeDir))return claudeDir;for(const candidate of [path.join(claudeDir,'plugins','everything-claude-code'),path.join(claudeDir,'plugins','everything-claude-code@everything-claude-code'),path.join(claudeDir,'plugins','marketplace','everything-claude-code')]){if(hasRunnerRoot(candidate))return candidate;}try{const cacheBase=path.join(claudeDir,'plugins','cache','everything-claude-code');for(const org of fs.readdirSync(cacheBase,{withFileTypes:true})){if(!org.isDirectory())continue;for(const version of fs.readdirSync(path.join(cacheBase,org.name),{withFileTypes:true})){if(!version.isDirectory())continue;const candidate=path.join(cacheBase,org.name,version.name);if(hasRunnerRoot(candidate))return candidate;}}}catch{}return claudeDir;})();const script=path.join(root,rel);if(fs.existsSync(script)){const result=spawnSync(process.execPath,[script,'stop:check-console-log','scripts/hooks/check-console-log.js','standard,strict'],{input:raw,encoding:'utf8',env:process.env,cwd:process.cwd(),timeout:30000});const stdout=typeof result.stdout==='string'?result.stdout:'';if(stdout)process.stdout.write(stdout);else process.stdout.write(raw);if(result.stderr)process.stderr.write(result.stderr);if(result.error||result.status===null||result.signal){const reason=result.error?result.error.message:(result.signal?'signal '+result.signal:'missing exit status');process.stderr.write('[Stop] ERROR: hook runner failed: '+reason+String.fromCharCode(10));process.exit(1);}process.exit(Number.isInteger(result.status)?result.status:0);}process.stderr.write('[Stop] WARNING: could not resolve ECC plugin root; skipping hook'+String.fromCharCode(10));process.stdout.write(raw);\""
|
"command": "node -e \"const fs=require('fs');const path=require('path');const {spawnSync}=require('child_process');const raw=fs.readFileSync(0,'utf8');const rel=path.join('scripts','hooks','run-with-flags.js');const hasRunnerRoot=candidate=>{const value=typeof candidate==='string'?candidate.trim():'';return value.length>0&&fs.existsSync(path.join(path.resolve(value),rel));};const root=(()=>{const envRoot=process.env.CLAUDE_PLUGIN_ROOT||'';if(hasRunnerRoot(envRoot))return path.resolve(envRoot.trim());const home=require('os').homedir();const claudeDir=path.join(home,'.claude');if(hasRunnerRoot(claudeDir))return claudeDir;for(const candidate of [path.join(claudeDir,'plugins','ecc'),path.join(claudeDir,'plugins','ecc@ecc'),path.join(claudeDir,'plugins','marketplace','ecc'),path.join(claudeDir,'plugins','everything-claude-code'),path.join(claudeDir,'plugins','everything-claude-code@everything-claude-code'),path.join(claudeDir,'plugins','marketplace','everything-claude-code')]){if(hasRunnerRoot(candidate))return candidate;}try{for(const slug of ['ecc','everything-claude-code']){const cacheBase=path.join(claudeDir,'plugins','cache',slug);for(const org of fs.readdirSync(cacheBase,{withFileTypes:true})){if(!org.isDirectory())continue;for(const version of fs.readdirSync(path.join(cacheBase,org.name),{withFileTypes:true})){if(!version.isDirectory())continue;const candidate=path.join(cacheBase,org.name,version.name);if(hasRunnerRoot(candidate))return candidate;}}}}catch{}return claudeDir;})();const script=path.join(root,rel);if(fs.existsSync(script)){const result=spawnSync(process.execPath,[script,'stop:check-console-log','scripts/hooks/check-console-log.js','standard,strict'],{input:raw,encoding:'utf8',env:process.env,cwd:process.cwd(),timeout:30000});const stdout=typeof result.stdout==='string'?result.stdout:'';if(stdout)process.stdout.write(stdout);else process.stdout.write(raw);if(result.stderr)process.stderr.write(result.stderr);if(result.error||result.status===null||result.signal){const reason=result.error?result.error.message:(result.signal?'signal '+result.signal:'missing exit status');process.stderr.write('[Stop] ERROR: hook runner failed: '+reason+String.fromCharCode(10));process.exit(1);}process.exit(Number.isInteger(result.status)?result.status:0);}process.stderr.write('[Stop] WARNING: could not resolve ECC plugin root; skipping hook'+String.fromCharCode(10));process.stdout.write(raw);\""
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Check for console.log in modified files after each response",
|
"description": "Check for console.log in modified files after each response",
|
||||||
@ -328,7 +328,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const fs=require('fs');const path=require('path');const {spawnSync}=require('child_process');const raw=fs.readFileSync(0,'utf8');const rel=path.join('scripts','hooks','run-with-flags.js');const hasRunnerRoot=candidate=>{const value=typeof candidate==='string'?candidate.trim():'';return value.length>0&&fs.existsSync(path.join(path.resolve(value),rel));};const root=(()=>{const envRoot=process.env.CLAUDE_PLUGIN_ROOT||'';if(hasRunnerRoot(envRoot))return path.resolve(envRoot.trim());const home=require('os').homedir();const claudeDir=path.join(home,'.claude');if(hasRunnerRoot(claudeDir))return claudeDir;for(const candidate of [path.join(claudeDir,'plugins','everything-claude-code'),path.join(claudeDir,'plugins','everything-claude-code@everything-claude-code'),path.join(claudeDir,'plugins','marketplace','everything-claude-code')]){if(hasRunnerRoot(candidate))return candidate;}try{const cacheBase=path.join(claudeDir,'plugins','cache','everything-claude-code');for(const org of fs.readdirSync(cacheBase,{withFileTypes:true})){if(!org.isDirectory())continue;for(const version of fs.readdirSync(path.join(cacheBase,org.name),{withFileTypes:true})){if(!version.isDirectory())continue;const candidate=path.join(cacheBase,org.name,version.name);if(hasRunnerRoot(candidate))return candidate;}}}catch{}return claudeDir;})();const script=path.join(root,rel);if(fs.existsSync(script)){const result=spawnSync(process.execPath,[script,'stop:session-end','scripts/hooks/session-end.js','minimal,standard,strict'],{input:raw,encoding:'utf8',env:process.env,cwd:process.cwd(),timeout:30000});const stdout=typeof result.stdout==='string'?result.stdout:'';if(stdout)process.stdout.write(stdout);else process.stdout.write(raw);if(result.stderr)process.stderr.write(result.stderr);if(result.error||result.status===null||result.signal){const reason=result.error?result.error.message:(result.signal?'signal '+result.signal:'missing exit status');process.stderr.write('[Stop] ERROR: hook runner failed: '+reason+String.fromCharCode(10));process.exit(1);}process.exit(Number.isInteger(result.status)?result.status:0);}process.stderr.write('[Stop] WARNING: could not resolve ECC plugin root; skipping hook'+String.fromCharCode(10));process.stdout.write(raw);\"",
|
"command": "node -e \"const fs=require('fs');const path=require('path');const {spawnSync}=require('child_process');const raw=fs.readFileSync(0,'utf8');const rel=path.join('scripts','hooks','run-with-flags.js');const hasRunnerRoot=candidate=>{const value=typeof candidate==='string'?candidate.trim():'';return value.length>0&&fs.existsSync(path.join(path.resolve(value),rel));};const root=(()=>{const envRoot=process.env.CLAUDE_PLUGIN_ROOT||'';if(hasRunnerRoot(envRoot))return path.resolve(envRoot.trim());const home=require('os').homedir();const claudeDir=path.join(home,'.claude');if(hasRunnerRoot(claudeDir))return claudeDir;for(const candidate of [path.join(claudeDir,'plugins','ecc'),path.join(claudeDir,'plugins','ecc@ecc'),path.join(claudeDir,'plugins','marketplace','ecc'),path.join(claudeDir,'plugins','everything-claude-code'),path.join(claudeDir,'plugins','everything-claude-code@everything-claude-code'),path.join(claudeDir,'plugins','marketplace','everything-claude-code')]){if(hasRunnerRoot(candidate))return candidate;}try{for(const slug of ['ecc','everything-claude-code']){const cacheBase=path.join(claudeDir,'plugins','cache',slug);for(const org of fs.readdirSync(cacheBase,{withFileTypes:true})){if(!org.isDirectory())continue;for(const version of fs.readdirSync(path.join(cacheBase,org.name),{withFileTypes:true})){if(!version.isDirectory())continue;const candidate=path.join(cacheBase,org.name,version.name);if(hasRunnerRoot(candidate))return candidate;}}}}catch{}return claudeDir;})();const script=path.join(root,rel);if(fs.existsSync(script)){const result=spawnSync(process.execPath,[script,'stop:session-end','scripts/hooks/session-end.js','minimal,standard,strict'],{input:raw,encoding:'utf8',env:process.env,cwd:process.cwd(),timeout:30000});const stdout=typeof result.stdout==='string'?result.stdout:'';if(stdout)process.stdout.write(stdout);else process.stdout.write(raw);if(result.stderr)process.stderr.write(result.stderr);if(result.error||result.status===null||result.signal){const reason=result.error?result.error.message:(result.signal?'signal '+result.signal:'missing exit status');process.stderr.write('[Stop] ERROR: hook runner failed: '+reason+String.fromCharCode(10));process.exit(1);}process.exit(Number.isInteger(result.status)?result.status:0);}process.stderr.write('[Stop] WARNING: could not resolve ECC plugin root; skipping hook'+String.fromCharCode(10));process.stdout.write(raw);\"",
|
||||||
"async": true,
|
"async": true,
|
||||||
"timeout": 10
|
"timeout": 10
|
||||||
}
|
}
|
||||||
@ -341,7 +341,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const fs=require('fs');const path=require('path');const {spawnSync}=require('child_process');const raw=fs.readFileSync(0,'utf8');const rel=path.join('scripts','hooks','run-with-flags.js');const hasRunnerRoot=candidate=>{const value=typeof candidate==='string'?candidate.trim():'';return value.length>0&&fs.existsSync(path.join(path.resolve(value),rel));};const root=(()=>{const envRoot=process.env.CLAUDE_PLUGIN_ROOT||'';if(hasRunnerRoot(envRoot))return path.resolve(envRoot.trim());const home=require('os').homedir();const claudeDir=path.join(home,'.claude');if(hasRunnerRoot(claudeDir))return claudeDir;for(const candidate of [path.join(claudeDir,'plugins','everything-claude-code'),path.join(claudeDir,'plugins','everything-claude-code@everything-claude-code'),path.join(claudeDir,'plugins','marketplace','everything-claude-code')]){if(hasRunnerRoot(candidate))return candidate;}try{const cacheBase=path.join(claudeDir,'plugins','cache','everything-claude-code');for(const org of fs.readdirSync(cacheBase,{withFileTypes:true})){if(!org.isDirectory())continue;for(const version of fs.readdirSync(path.join(cacheBase,org.name),{withFileTypes:true})){if(!version.isDirectory())continue;const candidate=path.join(cacheBase,org.name,version.name);if(hasRunnerRoot(candidate))return candidate;}}}catch{}return claudeDir;})();const script=path.join(root,rel);if(fs.existsSync(script)){const result=spawnSync(process.execPath,[script,'stop:evaluate-session','scripts/hooks/evaluate-session.js','minimal,standard,strict'],{input:raw,encoding:'utf8',env:process.env,cwd:process.cwd(),timeout:30000});const stdout=typeof result.stdout==='string'?result.stdout:'';if(stdout)process.stdout.write(stdout);else process.stdout.write(raw);if(result.stderr)process.stderr.write(result.stderr);if(result.error||result.status===null||result.signal){const reason=result.error?result.error.message:(result.signal?'signal '+result.signal:'missing exit status');process.stderr.write('[Stop] ERROR: hook runner failed: '+reason+String.fromCharCode(10));process.exit(1);}process.exit(Number.isInteger(result.status)?result.status:0);}process.stderr.write('[Stop] WARNING: could not resolve ECC plugin root; skipping hook'+String.fromCharCode(10));process.stdout.write(raw);\"",
|
"command": "node -e \"const fs=require('fs');const path=require('path');const {spawnSync}=require('child_process');const raw=fs.readFileSync(0,'utf8');const rel=path.join('scripts','hooks','run-with-flags.js');const hasRunnerRoot=candidate=>{const value=typeof candidate==='string'?candidate.trim():'';return value.length>0&&fs.existsSync(path.join(path.resolve(value),rel));};const root=(()=>{const envRoot=process.env.CLAUDE_PLUGIN_ROOT||'';if(hasRunnerRoot(envRoot))return path.resolve(envRoot.trim());const home=require('os').homedir();const claudeDir=path.join(home,'.claude');if(hasRunnerRoot(claudeDir))return claudeDir;for(const candidate of [path.join(claudeDir,'plugins','ecc'),path.join(claudeDir,'plugins','ecc@ecc'),path.join(claudeDir,'plugins','marketplace','ecc'),path.join(claudeDir,'plugins','everything-claude-code'),path.join(claudeDir,'plugins','everything-claude-code@everything-claude-code'),path.join(claudeDir,'plugins','marketplace','everything-claude-code')]){if(hasRunnerRoot(candidate))return candidate;}try{for(const slug of ['ecc','everything-claude-code']){const cacheBase=path.join(claudeDir,'plugins','cache',slug);for(const org of fs.readdirSync(cacheBase,{withFileTypes:true})){if(!org.isDirectory())continue;for(const version of fs.readdirSync(path.join(cacheBase,org.name),{withFileTypes:true})){if(!version.isDirectory())continue;const candidate=path.join(cacheBase,org.name,version.name);if(hasRunnerRoot(candidate))return candidate;}}}}catch{}return claudeDir;})();const script=path.join(root,rel);if(fs.existsSync(script)){const result=spawnSync(process.execPath,[script,'stop:evaluate-session','scripts/hooks/evaluate-session.js','minimal,standard,strict'],{input:raw,encoding:'utf8',env:process.env,cwd:process.cwd(),timeout:30000});const stdout=typeof result.stdout==='string'?result.stdout:'';if(stdout)process.stdout.write(stdout);else process.stdout.write(raw);if(result.stderr)process.stderr.write(result.stderr);if(result.error||result.status===null||result.signal){const reason=result.error?result.error.message:(result.signal?'signal '+result.signal:'missing exit status');process.stderr.write('[Stop] ERROR: hook runner failed: '+reason+String.fromCharCode(10));process.exit(1);}process.exit(Number.isInteger(result.status)?result.status:0);}process.stderr.write('[Stop] WARNING: could not resolve ECC plugin root; skipping hook'+String.fromCharCode(10));process.stdout.write(raw);\"",
|
||||||
"async": true,
|
"async": true,
|
||||||
"timeout": 10
|
"timeout": 10
|
||||||
}
|
}
|
||||||
@ -354,7 +354,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const fs=require('fs');const path=require('path');const {spawnSync}=require('child_process');const raw=fs.readFileSync(0,'utf8');const rel=path.join('scripts','hooks','run-with-flags.js');const hasRunnerRoot=candidate=>{const value=typeof candidate==='string'?candidate.trim():'';return value.length>0&&fs.existsSync(path.join(path.resolve(value),rel));};const root=(()=>{const envRoot=process.env.CLAUDE_PLUGIN_ROOT||'';if(hasRunnerRoot(envRoot))return path.resolve(envRoot.trim());const home=require('os').homedir();const claudeDir=path.join(home,'.claude');if(hasRunnerRoot(claudeDir))return claudeDir;for(const candidate of [path.join(claudeDir,'plugins','everything-claude-code'),path.join(claudeDir,'plugins','everything-claude-code@everything-claude-code'),path.join(claudeDir,'plugins','marketplace','everything-claude-code')]){if(hasRunnerRoot(candidate))return candidate;}try{const cacheBase=path.join(claudeDir,'plugins','cache','everything-claude-code');for(const org of fs.readdirSync(cacheBase,{withFileTypes:true})){if(!org.isDirectory())continue;for(const version of fs.readdirSync(path.join(cacheBase,org.name),{withFileTypes:true})){if(!version.isDirectory())continue;const candidate=path.join(cacheBase,org.name,version.name);if(hasRunnerRoot(candidate))return candidate;}}}catch{}return claudeDir;})();const script=path.join(root,rel);if(fs.existsSync(script)){const result=spawnSync(process.execPath,[script,'stop:cost-tracker','scripts/hooks/cost-tracker.js','minimal,standard,strict'],{input:raw,encoding:'utf8',env:process.env,cwd:process.cwd(),timeout:30000});const stdout=typeof result.stdout==='string'?result.stdout:'';if(stdout)process.stdout.write(stdout);else process.stdout.write(raw);if(result.stderr)process.stderr.write(result.stderr);if(result.error||result.status===null||result.signal){const reason=result.error?result.error.message:(result.signal?'signal '+result.signal:'missing exit status');process.stderr.write('[Stop] ERROR: hook runner failed: '+reason+String.fromCharCode(10));process.exit(1);}process.exit(Number.isInteger(result.status)?result.status:0);}process.stderr.write('[Stop] WARNING: could not resolve ECC plugin root; skipping hook'+String.fromCharCode(10));process.stdout.write(raw);\"",
|
"command": "node -e \"const fs=require('fs');const path=require('path');const {spawnSync}=require('child_process');const raw=fs.readFileSync(0,'utf8');const rel=path.join('scripts','hooks','run-with-flags.js');const hasRunnerRoot=candidate=>{const value=typeof candidate==='string'?candidate.trim():'';return value.length>0&&fs.existsSync(path.join(path.resolve(value),rel));};const root=(()=>{const envRoot=process.env.CLAUDE_PLUGIN_ROOT||'';if(hasRunnerRoot(envRoot))return path.resolve(envRoot.trim());const home=require('os').homedir();const claudeDir=path.join(home,'.claude');if(hasRunnerRoot(claudeDir))return claudeDir;for(const candidate of [path.join(claudeDir,'plugins','ecc'),path.join(claudeDir,'plugins','ecc@ecc'),path.join(claudeDir,'plugins','marketplace','ecc'),path.join(claudeDir,'plugins','everything-claude-code'),path.join(claudeDir,'plugins','everything-claude-code@everything-claude-code'),path.join(claudeDir,'plugins','marketplace','everything-claude-code')]){if(hasRunnerRoot(candidate))return candidate;}try{for(const slug of ['ecc','everything-claude-code']){const cacheBase=path.join(claudeDir,'plugins','cache',slug);for(const org of fs.readdirSync(cacheBase,{withFileTypes:true})){if(!org.isDirectory())continue;for(const version of fs.readdirSync(path.join(cacheBase,org.name),{withFileTypes:true})){if(!version.isDirectory())continue;const candidate=path.join(cacheBase,org.name,version.name);if(hasRunnerRoot(candidate))return candidate;}}}}catch{}return claudeDir;})();const script=path.join(root,rel);if(fs.existsSync(script)){const result=spawnSync(process.execPath,[script,'stop:cost-tracker','scripts/hooks/cost-tracker.js','minimal,standard,strict'],{input:raw,encoding:'utf8',env:process.env,cwd:process.cwd(),timeout:30000});const stdout=typeof result.stdout==='string'?result.stdout:'';if(stdout)process.stdout.write(stdout);else process.stdout.write(raw);if(result.stderr)process.stderr.write(result.stderr);if(result.error||result.status===null||result.signal){const reason=result.error?result.error.message:(result.signal?'signal '+result.signal:'missing exit status');process.stderr.write('[Stop] ERROR: hook runner failed: '+reason+String.fromCharCode(10));process.exit(1);}process.exit(Number.isInteger(result.status)?result.status:0);}process.stderr.write('[Stop] WARNING: could not resolve ECC plugin root; skipping hook'+String.fromCharCode(10));process.stdout.write(raw);\"",
|
||||||
"async": true,
|
"async": true,
|
||||||
"timeout": 10
|
"timeout": 10
|
||||||
}
|
}
|
||||||
@ -367,7 +367,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const fs=require('fs');const path=require('path');const {spawnSync}=require('child_process');const raw=fs.readFileSync(0,'utf8');const rel=path.join('scripts','hooks','run-with-flags.js');const hasRunnerRoot=candidate=>{const value=typeof candidate==='string'?candidate.trim():'';return value.length>0&&fs.existsSync(path.join(path.resolve(value),rel));};const root=(()=>{const envRoot=process.env.CLAUDE_PLUGIN_ROOT||'';if(hasRunnerRoot(envRoot))return path.resolve(envRoot.trim());const home=require('os').homedir();const claudeDir=path.join(home,'.claude');if(hasRunnerRoot(claudeDir))return claudeDir;for(const candidate of [path.join(claudeDir,'plugins','everything-claude-code'),path.join(claudeDir,'plugins','everything-claude-code@everything-claude-code'),path.join(claudeDir,'plugins','marketplace','everything-claude-code')]){if(hasRunnerRoot(candidate))return candidate;}try{const cacheBase=path.join(claudeDir,'plugins','cache','everything-claude-code');for(const org of fs.readdirSync(cacheBase,{withFileTypes:true})){if(!org.isDirectory())continue;for(const version of fs.readdirSync(path.join(cacheBase,org.name),{withFileTypes:true})){if(!version.isDirectory())continue;const candidate=path.join(cacheBase,org.name,version.name);if(hasRunnerRoot(candidate))return candidate;}}}catch{}return claudeDir;})();const script=path.join(root,rel);if(fs.existsSync(script)){const result=spawnSync(process.execPath,[script,'stop:desktop-notify','scripts/hooks/desktop-notify.js','standard,strict'],{input:raw,encoding:'utf8',env:process.env,cwd:process.cwd(),timeout:30000});const stdout=typeof result.stdout==='string'?result.stdout:'';if(stdout)process.stdout.write(stdout);else process.stdout.write(raw);if(result.stderr)process.stderr.write(result.stderr);if(result.error||result.status===null||result.signal){const reason=result.error?result.error.message:(result.signal?'signal '+result.signal:'missing exit status');process.stderr.write('[Stop] ERROR: hook runner failed: '+reason+String.fromCharCode(10));process.exit(1);}process.exit(Number.isInteger(result.status)?result.status:0);}process.stderr.write('[Stop] WARNING: could not resolve ECC plugin root; skipping hook'+String.fromCharCode(10));process.stdout.write(raw);\"",
|
"command": "node -e \"const fs=require('fs');const path=require('path');const {spawnSync}=require('child_process');const raw=fs.readFileSync(0,'utf8');const rel=path.join('scripts','hooks','run-with-flags.js');const hasRunnerRoot=candidate=>{const value=typeof candidate==='string'?candidate.trim():'';return value.length>0&&fs.existsSync(path.join(path.resolve(value),rel));};const root=(()=>{const envRoot=process.env.CLAUDE_PLUGIN_ROOT||'';if(hasRunnerRoot(envRoot))return path.resolve(envRoot.trim());const home=require('os').homedir();const claudeDir=path.join(home,'.claude');if(hasRunnerRoot(claudeDir))return claudeDir;for(const candidate of [path.join(claudeDir,'plugins','ecc'),path.join(claudeDir,'plugins','ecc@ecc'),path.join(claudeDir,'plugins','marketplace','ecc'),path.join(claudeDir,'plugins','everything-claude-code'),path.join(claudeDir,'plugins','everything-claude-code@everything-claude-code'),path.join(claudeDir,'plugins','marketplace','everything-claude-code')]){if(hasRunnerRoot(candidate))return candidate;}try{for(const slug of ['ecc','everything-claude-code']){const cacheBase=path.join(claudeDir,'plugins','cache',slug);for(const org of fs.readdirSync(cacheBase,{withFileTypes:true})){if(!org.isDirectory())continue;for(const version of fs.readdirSync(path.join(cacheBase,org.name),{withFileTypes:true})){if(!version.isDirectory())continue;const candidate=path.join(cacheBase,org.name,version.name);if(hasRunnerRoot(candidate))return candidate;}}}}catch{}return claudeDir;})();const script=path.join(root,rel);if(fs.existsSync(script)){const result=spawnSync(process.execPath,[script,'stop:desktop-notify','scripts/hooks/desktop-notify.js','standard,strict'],{input:raw,encoding:'utf8',env:process.env,cwd:process.cwd(),timeout:30000});const stdout=typeof result.stdout==='string'?result.stdout:'';if(stdout)process.stdout.write(stdout);else process.stdout.write(raw);if(result.stderr)process.stderr.write(result.stderr);if(result.error||result.status===null||result.signal){const reason=result.error?result.error.message:(result.signal?'signal '+result.signal:'missing exit status');process.stderr.write('[Stop] ERROR: hook runner failed: '+reason+String.fromCharCode(10));process.exit(1);}process.exit(Number.isInteger(result.status)?result.status:0);}process.stderr.write('[Stop] WARNING: could not resolve ECC plugin root; skipping hook'+String.fromCharCode(10));process.stdout.write(raw);\"",
|
||||||
"async": true,
|
"async": true,
|
||||||
"timeout": 10
|
"timeout": 10
|
||||||
}
|
}
|
||||||
@ -382,7 +382,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const fs=require('fs');const path=require('path');const {spawnSync}=require('child_process');const raw=fs.readFileSync(0,'utf8');const rel=path.join('scripts','hooks','run-with-flags.js');const hasRunnerRoot=candidate=>{const value=typeof candidate==='string'?candidate.trim():'';return value.length>0&&fs.existsSync(path.join(path.resolve(value),rel));};const root=(()=>{const envRoot=process.env.CLAUDE_PLUGIN_ROOT||'';if(hasRunnerRoot(envRoot))return path.resolve(envRoot.trim());const home=require('os').homedir();const claudeDir=path.join(home,'.claude');if(hasRunnerRoot(claudeDir))return claudeDir;for(const candidate of [path.join(claudeDir,'plugins','everything-claude-code'),path.join(claudeDir,'plugins','everything-claude-code@everything-claude-code'),path.join(claudeDir,'plugins','marketplace','everything-claude-code')]){if(hasRunnerRoot(candidate))return candidate;}try{const cacheBase=path.join(claudeDir,'plugins','cache','everything-claude-code');for(const org of fs.readdirSync(cacheBase,{withFileTypes:true})){if(!org.isDirectory())continue;for(const version of fs.readdirSync(path.join(cacheBase,org.name),{withFileTypes:true})){if(!version.isDirectory())continue;const candidate=path.join(cacheBase,org.name,version.name);if(hasRunnerRoot(candidate))return candidate;}}}catch{}return claudeDir;})();const script=path.join(root,rel);if(fs.existsSync(script)){const result=spawnSync(process.execPath,[script,'session:end:marker','scripts/hooks/session-end-marker.js','minimal,standard,strict'],{input:raw,encoding:'utf8',env:process.env,cwd:process.cwd(),timeout:30000});const stdout=typeof result.stdout==='string'?result.stdout:'';if(stdout)process.stdout.write(stdout);else process.stdout.write(raw);if(result.stderr)process.stderr.write(result.stderr);if(result.error||result.status===null||result.signal){const reason=result.error?result.error.message:(result.signal?'signal '+result.signal:'missing exit status');process.stderr.write('[SessionEnd] ERROR: hook runner failed: '+reason+String.fromCharCode(10));process.exit(1);}process.exit(Number.isInteger(result.status)?result.status:0);}process.stderr.write('[SessionEnd] WARNING: could not resolve ECC plugin root; skipping hook'+String.fromCharCode(10));process.stdout.write(raw);\"",
|
"command": "node -e \"const fs=require('fs');const path=require('path');const {spawnSync}=require('child_process');const raw=fs.readFileSync(0,'utf8');const rel=path.join('scripts','hooks','run-with-flags.js');const hasRunnerRoot=candidate=>{const value=typeof candidate==='string'?candidate.trim():'';return value.length>0&&fs.existsSync(path.join(path.resolve(value),rel));};const root=(()=>{const envRoot=process.env.CLAUDE_PLUGIN_ROOT||'';if(hasRunnerRoot(envRoot))return path.resolve(envRoot.trim());const home=require('os').homedir();const claudeDir=path.join(home,'.claude');if(hasRunnerRoot(claudeDir))return claudeDir;for(const candidate of [path.join(claudeDir,'plugins','ecc'),path.join(claudeDir,'plugins','ecc@ecc'),path.join(claudeDir,'plugins','marketplace','ecc'),path.join(claudeDir,'plugins','everything-claude-code'),path.join(claudeDir,'plugins','everything-claude-code@everything-claude-code'),path.join(claudeDir,'plugins','marketplace','everything-claude-code')]){if(hasRunnerRoot(candidate))return candidate;}try{for(const slug of ['ecc','everything-claude-code']){const cacheBase=path.join(claudeDir,'plugins','cache',slug);for(const org of fs.readdirSync(cacheBase,{withFileTypes:true})){if(!org.isDirectory())continue;for(const version of fs.readdirSync(path.join(cacheBase,org.name),{withFileTypes:true})){if(!version.isDirectory())continue;const candidate=path.join(cacheBase,org.name,version.name);if(hasRunnerRoot(candidate))return candidate;}}}}catch{}return claudeDir;})();const script=path.join(root,rel);if(fs.existsSync(script)){const result=spawnSync(process.execPath,[script,'session:end:marker','scripts/hooks/session-end-marker.js','minimal,standard,strict'],{input:raw,encoding:'utf8',env:process.env,cwd:process.cwd(),timeout:30000});const stdout=typeof result.stdout==='string'?result.stdout:'';if(stdout)process.stdout.write(stdout);else process.stdout.write(raw);if(result.stderr)process.stderr.write(result.stderr);if(result.error||result.status===null||result.signal){const reason=result.error?result.error.message:(result.signal?'signal '+result.signal:'missing exit status');process.stderr.write('[SessionEnd] ERROR: hook runner failed: '+reason+String.fromCharCode(10));process.exit(1);}process.exit(Number.isInteger(result.status)?result.status:0);}process.stderr.write('[SessionEnd] WARNING: could not resolve ECC plugin root; skipping hook'+String.fromCharCode(10));process.stdout.write(raw);\"",
|
||||||
"async": true,
|
"async": true,
|
||||||
"timeout": 10
|
"timeout": 10
|
||||||
}
|
}
|
||||||
|
|||||||
@ -188,12 +188,22 @@ function detectTargetMode(rootDir) {
|
|||||||
|
|
||||||
function findPluginInstall(rootDir) {
|
function findPluginInstall(rootDir) {
|
||||||
const homeDir = process.env.HOME || '';
|
const homeDir = process.env.HOME || '';
|
||||||
const candidates = [
|
const pluginDirs = [
|
||||||
path.join(rootDir, '.claude', 'plugins', 'everything-claude-code', '.claude-plugin', 'plugin.json'),
|
'ecc',
|
||||||
path.join(rootDir, '.claude', 'plugins', 'everything-claude-code', 'plugin.json'),
|
'ecc@ecc',
|
||||||
homeDir && path.join(homeDir, '.claude', 'plugins', 'everything-claude-code', '.claude-plugin', 'plugin.json'),
|
'everything-claude-code',
|
||||||
homeDir && path.join(homeDir, '.claude', 'plugins', 'everything-claude-code', 'plugin.json'),
|
'everything-claude-code@everything-claude-code',
|
||||||
|
];
|
||||||
|
const candidateRoots = [
|
||||||
|
path.join(rootDir, '.claude', 'plugins'),
|
||||||
|
homeDir && path.join(homeDir, '.claude', 'plugins'),
|
||||||
].filter(Boolean);
|
].filter(Boolean);
|
||||||
|
const candidates = candidateRoots.flatMap((pluginsDir) =>
|
||||||
|
pluginDirs.flatMap((pluginDir) => [
|
||||||
|
path.join(pluginsDir, pluginDir, '.claude-plugin', 'plugin.json'),
|
||||||
|
path.join(pluginsDir, pluginDir, 'plugin.json'),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
return candidates.find(candidate => fs.existsSync(candidate)) || null;
|
return candidates.find(candidate => fs.existsSync(candidate)) || null;
|
||||||
}
|
}
|
||||||
@ -480,7 +490,7 @@ function getConsumerChecks(rootDir) {
|
|||||||
category: 'Tool Coverage',
|
category: 'Tool Coverage',
|
||||||
points: 4,
|
points: 4,
|
||||||
scopes: ['repo'],
|
scopes: ['repo'],
|
||||||
path: '~/.claude/plugins/everything-claude-code/',
|
path: '~/.claude/plugins/ecc/ (legacy everything-claude-code paths also supported)',
|
||||||
description: 'Everything Claude Code is installed for the active user or project',
|
description: 'Everything Claude Code is installed for the active user or project',
|
||||||
pass: Boolean(pluginInstall),
|
pass: Boolean(pluginInstall),
|
||||||
fix: 'Install the ECC plugin for this user or project before auditing project-specific harness quality.',
|
fix: 'Install the ECC plugin for this user or project before auditing project-specific harness quality.',
|
||||||
|
|||||||
@ -30,6 +30,18 @@ const fs = require('fs');
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const { spawnSync } = require('child_process');
|
const { spawnSync } = require('child_process');
|
||||||
|
|
||||||
|
const CURRENT_PLUGIN_SLUG = 'ecc';
|
||||||
|
const LEGACY_PLUGIN_SLUG = 'everything-claude-code';
|
||||||
|
const KNOWN_PLUGIN_PATHS = [
|
||||||
|
[CURRENT_PLUGIN_SLUG],
|
||||||
|
[`${CURRENT_PLUGIN_SLUG}@${CURRENT_PLUGIN_SLUG}`],
|
||||||
|
['marketplace', CURRENT_PLUGIN_SLUG],
|
||||||
|
[LEGACY_PLUGIN_SLUG],
|
||||||
|
[`${LEGACY_PLUGIN_SLUG}@${LEGACY_PLUGIN_SLUG}`],
|
||||||
|
['marketplace', LEGACY_PLUGIN_SLUG],
|
||||||
|
];
|
||||||
|
const CACHE_PLUGIN_SLUGS = [CURRENT_PLUGIN_SLUG, LEGACY_PLUGIN_SLUG];
|
||||||
|
|
||||||
// Read the raw JSON event from stdin
|
// Read the raw JSON event from stdin
|
||||||
const raw = fs.readFileSync(0, 'utf8');
|
const raw = fs.readFileSync(0, 'utf8');
|
||||||
|
|
||||||
@ -52,8 +64,8 @@ function hasRunnerRoot(candidate) {
|
|||||||
* Resolves the ECC plugin root using the following priority order:
|
* Resolves the ECC plugin root using the following priority order:
|
||||||
* 1. CLAUDE_PLUGIN_ROOT environment variable
|
* 1. CLAUDE_PLUGIN_ROOT environment variable
|
||||||
* 2. ~/.claude (direct install)
|
* 2. ~/.claude (direct install)
|
||||||
* 3. Several well-known plugin sub-paths under ~/.claude/plugins/
|
* 3. Several well-known plugin sub-paths under ~/.claude/plugins/ (current + legacy)
|
||||||
* 4. Versioned cache directories under ~/.claude/plugins/cache/everything-claude-code/
|
* 4. Versioned cache directories under ~/.claude/plugins/cache/{ecc,everything-claude-code}/
|
||||||
* 5. Falls back to ~/.claude if nothing else matches
|
* 5. Falls back to ~/.claude if nothing else matches
|
||||||
*
|
*
|
||||||
* @returns {string}
|
* @returns {string}
|
||||||
@ -71,11 +83,9 @@ function resolvePluginRoot() {
|
|||||||
return claudeDir;
|
return claudeDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
const knownPaths = [
|
const knownPaths = KNOWN_PLUGIN_PATHS.map((segments) =>
|
||||||
path.join(claudeDir, 'plugins', 'everything-claude-code'),
|
path.join(claudeDir, 'plugins', ...segments)
|
||||||
path.join(claudeDir, 'plugins', 'everything-claude-code@everything-claude-code'),
|
);
|
||||||
path.join(claudeDir, 'plugins', 'marketplace', 'everything-claude-code'),
|
|
||||||
];
|
|
||||||
|
|
||||||
for (const candidate of knownPaths) {
|
for (const candidate of knownPaths) {
|
||||||
if (hasRunnerRoot(candidate)) {
|
if (hasRunnerRoot(candidate)) {
|
||||||
@ -83,16 +93,18 @@ function resolvePluginRoot() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Walk versioned cache: ~/.claude/plugins/cache/everything-claude-code/<org>/<version>/
|
// Walk versioned cache: ~/.claude/plugins/cache/{ecc,everything-claude-code}/<org>/<version>/
|
||||||
try {
|
try {
|
||||||
const cacheBase = path.join(claudeDir, 'plugins', 'cache', 'everything-claude-code');
|
for (const slug of CACHE_PLUGIN_SLUGS) {
|
||||||
for (const org of fs.readdirSync(cacheBase, { withFileTypes: true })) {
|
const cacheBase = path.join(claudeDir, 'plugins', 'cache', slug);
|
||||||
if (!org.isDirectory()) continue;
|
for (const org of fs.readdirSync(cacheBase, { withFileTypes: true })) {
|
||||||
for (const version of fs.readdirSync(path.join(cacheBase, org.name), { withFileTypes: true })) {
|
if (!org.isDirectory()) continue;
|
||||||
if (!version.isDirectory()) continue;
|
for (const version of fs.readdirSync(path.join(cacheBase, org.name), { withFileTypes: true })) {
|
||||||
const candidate = path.join(cacheBase, org.name, version.name);
|
if (!version.isDirectory()) continue;
|
||||||
if (hasRunnerRoot(candidate)) {
|
const candidate = path.join(cacheBase, org.name, version.name);
|
||||||
return candidate;
|
if (hasRunnerRoot(candidate)) {
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,14 +4,28 @@ const fs = require('fs');
|
|||||||
const path = require('path');
|
const path = require('path');
|
||||||
const os = require('os');
|
const os = require('os');
|
||||||
|
|
||||||
|
const CURRENT_PLUGIN_SLUG = 'ecc';
|
||||||
|
const LEGACY_PLUGIN_SLUG = 'everything-claude-code';
|
||||||
|
const CURRENT_PLUGIN_HANDLE = `${CURRENT_PLUGIN_SLUG}@${CURRENT_PLUGIN_SLUG}`;
|
||||||
|
const LEGACY_PLUGIN_HANDLE = `${LEGACY_PLUGIN_SLUG}@${LEGACY_PLUGIN_SLUG}`;
|
||||||
|
const PLUGIN_CACHE_SLUGS = [CURRENT_PLUGIN_SLUG, LEGACY_PLUGIN_SLUG];
|
||||||
|
const PLUGIN_ROOT_SEGMENTS = [
|
||||||
|
[CURRENT_PLUGIN_SLUG],
|
||||||
|
[CURRENT_PLUGIN_HANDLE],
|
||||||
|
['marketplace', CURRENT_PLUGIN_SLUG],
|
||||||
|
[LEGACY_PLUGIN_SLUG],
|
||||||
|
[LEGACY_PLUGIN_HANDLE],
|
||||||
|
['marketplace', LEGACY_PLUGIN_SLUG],
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve the ECC source root directory.
|
* Resolve the ECC source root directory.
|
||||||
*
|
*
|
||||||
* Tries, in order:
|
* Tries, in order:
|
||||||
* 1. CLAUDE_PLUGIN_ROOT env var (set by Claude Code for hooks, or by user)
|
* 1. CLAUDE_PLUGIN_ROOT env var (set by Claude Code for hooks, or by user)
|
||||||
* 2. Standard install location (~/.claude/) — when scripts exist there
|
* 2. Standard install location (~/.claude/) — when scripts exist there
|
||||||
* 3. Exact legacy plugin roots under ~/.claude/plugins/
|
* 3. Known plugin roots under ~/.claude/plugins/ (current + legacy slugs)
|
||||||
* 4. Plugin cache auto-detection — scans ~/.claude/plugins/cache/everything-claude-code/
|
* 4. Plugin cache auto-detection — scans ~/.claude/plugins/cache/{ecc,everything-claude-code}/
|
||||||
* 5. Fallback to ~/.claude/ (original behaviour)
|
* 5. Fallback to ~/.claude/ (original behaviour)
|
||||||
*
|
*
|
||||||
* @param {object} [options]
|
* @param {object} [options]
|
||||||
@ -41,11 +55,9 @@ function resolveEccRoot(options = {}) {
|
|||||||
|
|
||||||
// Exact legacy plugin install locations. These preserve backwards
|
// Exact legacy plugin install locations. These preserve backwards
|
||||||
// compatibility without scanning arbitrary plugin trees.
|
// compatibility without scanning arbitrary plugin trees.
|
||||||
const legacyPluginRoots = [
|
const legacyPluginRoots = PLUGIN_ROOT_SEGMENTS.map((segments) =>
|
||||||
path.join(claudeDir, 'plugins', 'everything-claude-code'),
|
path.join(claudeDir, 'plugins', ...segments)
|
||||||
path.join(claudeDir, 'plugins', 'everything-claude-code@everything-claude-code'),
|
);
|
||||||
path.join(claudeDir, 'plugins', 'marketplace', 'everything-claude-code')
|
|
||||||
];
|
|
||||||
|
|
||||||
for (const candidate of legacyPluginRoots) {
|
for (const candidate of legacyPluginRoots) {
|
||||||
if (fs.existsSync(path.join(candidate, probe))) {
|
if (fs.existsSync(path.join(candidate, probe))) {
|
||||||
@ -56,25 +68,27 @@ function resolveEccRoot(options = {}) {
|
|||||||
// Plugin cache — Claude Code stores marketplace plugins under
|
// Plugin cache — Claude Code stores marketplace plugins under
|
||||||
// ~/.claude/plugins/cache/<plugin-name>/<org>/<version>/
|
// ~/.claude/plugins/cache/<plugin-name>/<org>/<version>/
|
||||||
try {
|
try {
|
||||||
const cacheBase = path.join(claudeDir, 'plugins', 'cache', 'everything-claude-code');
|
for (const slug of PLUGIN_CACHE_SLUGS) {
|
||||||
const orgDirs = fs.readdirSync(cacheBase, { withFileTypes: true });
|
const cacheBase = path.join(claudeDir, 'plugins', 'cache', slug);
|
||||||
|
const orgDirs = fs.readdirSync(cacheBase, { withFileTypes: true });
|
||||||
|
|
||||||
for (const orgEntry of orgDirs) {
|
for (const orgEntry of orgDirs) {
|
||||||
if (!orgEntry.isDirectory()) continue;
|
if (!orgEntry.isDirectory()) continue;
|
||||||
const orgPath = path.join(cacheBase, orgEntry.name);
|
const orgPath = path.join(cacheBase, orgEntry.name);
|
||||||
|
|
||||||
let versionDirs;
|
let versionDirs;
|
||||||
try {
|
try {
|
||||||
versionDirs = fs.readdirSync(orgPath, { withFileTypes: true });
|
versionDirs = fs.readdirSync(orgPath, { withFileTypes: true });
|
||||||
} catch {
|
} catch {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const verEntry of versionDirs) {
|
for (const verEntry of versionDirs) {
|
||||||
if (!verEntry.isDirectory()) continue;
|
if (!verEntry.isDirectory()) continue;
|
||||||
const candidate = path.join(orgPath, verEntry.name);
|
const candidate = path.join(orgPath, verEntry.name);
|
||||||
if (fs.existsSync(path.join(candidate, probe))) {
|
if (fs.existsSync(path.join(candidate, probe))) {
|
||||||
return candidate;
|
return candidate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,7 +110,7 @@ function resolveEccRoot(options = {}) {
|
|||||||
* const _r = <paste INLINE_RESOLVE>;
|
* const _r = <paste INLINE_RESOLVE>;
|
||||||
* const sm = require(_r + '/scripts/lib/session-manager');
|
* const sm = require(_r + '/scripts/lib/session-manager');
|
||||||
*/
|
*/
|
||||||
const INLINE_RESOLVE = `(()=>{var e=process.env.CLAUDE_PLUGIN_ROOT;if(e&&e.trim())return e.trim();var p=require('path'),f=require('fs'),h=require('os').homedir(),d=p.join(h,'.claude'),q=p.join('scripts','lib','utils.js');if(f.existsSync(p.join(d,q)))return d;for(var l of [p.join(d,'plugins','everything-claude-code'),p.join(d,'plugins','everything-claude-code@everything-claude-code'),p.join(d,'plugins','marketplace','everything-claude-code')])if(f.existsSync(p.join(l,q)))return l;try{var b=p.join(d,'plugins','cache','everything-claude-code');for(var o of f.readdirSync(b,{withFileTypes:true})){if(!o.isDirectory())continue;for(var v of f.readdirSync(p.join(b,o.name),{withFileTypes:true})){if(!v.isDirectory())continue;var c=p.join(b,o.name,v.name);if(f.existsSync(p.join(c,q)))return c}}}catch(x){}return d})()`;
|
const INLINE_RESOLVE = `(()=>{var e=process.env.CLAUDE_PLUGIN_ROOT;if(e&&e.trim())return e.trim();var p=require('path'),f=require('fs'),h=require('os').homedir(),d=p.join(h,'.claude'),q=p.join('scripts','lib','utils.js');if(f.existsSync(p.join(d,q)))return d;for(var s of ${JSON.stringify(PLUGIN_ROOT_SEGMENTS)}){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ${JSON.stringify(PLUGIN_CACHE_SLUGS)}){var b=p.join(d,'plugins','cache',g);for(var o of f.readdirSync(b,{withFileTypes:true})){if(!o.isDirectory())continue;for(var v of f.readdirSync(p.join(b,o.name),{withFileTypes:true})){if(!v.isDirectory())continue;var c=p.join(b,o.name,v.name);if(f.existsSync(p.join(c,q)))return c}}}}catch(x){}return d})()`;
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
resolveEccRoot,
|
resolveEccRoot,
|
||||||
|
|||||||
@ -18,7 +18,7 @@ An interactive, step-by-step installation wizard for the Everything Claude Code
|
|||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
This skill must be accessible to Claude Code before activation. Two ways to bootstrap:
|
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"
|
2. **Manual**: Copy only this skill to `~/.claude/skills/configure-ecc/SKILL.md`, then activate by saying "configure ecc"
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@ -47,10 +47,10 @@ function setupLegacyPluginInstall(homeDir, segments) {
|
|||||||
fs.writeFileSync(path.join(scriptDir, 'utils.js'), '// stub');
|
fs.writeFileSync(path.join(scriptDir, 'utils.js'), '// stub');
|
||||||
return legacyDir;
|
return legacyDir;
|
||||||
}
|
}
|
||||||
function setupPluginCache(homeDir, orgName, version) {
|
function setupPluginCache(homeDir, pluginSlug, orgName, version) {
|
||||||
const cacheDir = path.join(
|
const cacheDir = path.join(
|
||||||
homeDir, '.claude', 'plugins', 'cache',
|
homeDir, '.claude', 'plugins', 'cache',
|
||||||
'everything-claude-code', orgName, version
|
pluginSlug, orgName, version
|
||||||
);
|
);
|
||||||
const scriptDir = path.join(cacheDir, 'scripts', 'lib');
|
const scriptDir = path.join(cacheDir, 'scripts', 'lib');
|
||||||
fs.mkdirSync(scriptDir, { recursive: true });
|
fs.mkdirSync(scriptDir, { recursive: true });
|
||||||
@ -111,6 +111,28 @@ function runTests() {
|
|||||||
}
|
}
|
||||||
})) passed++; else failed++;
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('finds current plugin install at ~/.claude/plugins/ecc', () => {
|
||||||
|
const homeDir = createTempDir();
|
||||||
|
try {
|
||||||
|
const expected = setupLegacyPluginInstall(homeDir, ['ecc']);
|
||||||
|
const result = resolveEccRoot({ envRoot: '', homeDir });
|
||||||
|
assert.strictEqual(result, expected);
|
||||||
|
} finally {
|
||||||
|
fs.rmSync(homeDir, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('finds current plugin install at ~/.claude/plugins/ecc@ecc', () => {
|
||||||
|
const homeDir = createTempDir();
|
||||||
|
try {
|
||||||
|
const expected = setupLegacyPluginInstall(homeDir, ['ecc@ecc']);
|
||||||
|
const result = resolveEccRoot({ envRoot: '', homeDir });
|
||||||
|
assert.strictEqual(result, expected);
|
||||||
|
} finally {
|
||||||
|
fs.rmSync(homeDir, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
if (test('finds exact legacy plugin install at ~/.claude/plugins/everything-claude-code', () => {
|
if (test('finds exact legacy plugin install at ~/.claude/plugins/everything-claude-code', () => {
|
||||||
const homeDir = createTempDir();
|
const homeDir = createTempDir();
|
||||||
try {
|
try {
|
||||||
@ -133,6 +155,17 @@ function runTests() {
|
|||||||
}
|
}
|
||||||
})) passed++; else failed++;
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('finds marketplace current plugin install at ~/.claude/plugins/marketplace/ecc', () => {
|
||||||
|
const homeDir = createTempDir();
|
||||||
|
try {
|
||||||
|
const expected = setupLegacyPluginInstall(homeDir, ['marketplace', 'ecc']);
|
||||||
|
const result = resolveEccRoot({ envRoot: '', homeDir });
|
||||||
|
assert.strictEqual(result, expected);
|
||||||
|
} finally {
|
||||||
|
fs.rmSync(homeDir, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
if (test('finds marketplace legacy plugin install at ~/.claude/plugins/marketplace/everything-claude-code', () => {
|
if (test('finds marketplace legacy plugin install at ~/.claude/plugins/marketplace/everything-claude-code', () => {
|
||||||
const homeDir = createTempDir();
|
const homeDir = createTempDir();
|
||||||
try {
|
try {
|
||||||
@ -147,8 +180,8 @@ function runTests() {
|
|||||||
if (test('prefers exact legacy plugin install over plugin cache', () => {
|
if (test('prefers exact legacy plugin install over plugin cache', () => {
|
||||||
const homeDir = createTempDir();
|
const homeDir = createTempDir();
|
||||||
try {
|
try {
|
||||||
const expected = setupLegacyPluginInstall(homeDir, ['marketplace', 'everything-claude-code']);
|
const expected = setupLegacyPluginInstall(homeDir, ['marketplace', 'ecc']);
|
||||||
setupPluginCache(homeDir, 'everything-claude-code', '1.8.0');
|
setupPluginCache(homeDir, 'ecc', 'affaan-m', '1.10.0');
|
||||||
const result = resolveEccRoot({ envRoot: '', homeDir });
|
const result = resolveEccRoot({ envRoot: '', homeDir });
|
||||||
assert.strictEqual(result, expected);
|
assert.strictEqual(result, expected);
|
||||||
} finally {
|
} finally {
|
||||||
@ -160,7 +193,7 @@ function runTests() {
|
|||||||
if (test('discovers plugin root from cache directory', () => {
|
if (test('discovers plugin root from cache directory', () => {
|
||||||
const homeDir = createTempDir();
|
const homeDir = createTempDir();
|
||||||
try {
|
try {
|
||||||
const expected = setupPluginCache(homeDir, 'everything-claude-code', '1.8.0');
|
const expected = setupPluginCache(homeDir, 'ecc', 'affaan-m', '1.10.0');
|
||||||
const result = resolveEccRoot({ envRoot: '', homeDir });
|
const result = resolveEccRoot({ envRoot: '', homeDir });
|
||||||
assert.strictEqual(result, expected);
|
assert.strictEqual(result, expected);
|
||||||
} finally {
|
} finally {
|
||||||
@ -172,7 +205,7 @@ function runTests() {
|
|||||||
const homeDir = createTempDir();
|
const homeDir = createTempDir();
|
||||||
try {
|
try {
|
||||||
const claudeDir = setupStandardInstall(homeDir);
|
const claudeDir = setupStandardInstall(homeDir);
|
||||||
setupPluginCache(homeDir, 'everything-claude-code', '1.8.0');
|
setupPluginCache(homeDir, 'ecc', 'affaan-m', '1.10.0');
|
||||||
const result = resolveEccRoot({ envRoot: '', homeDir });
|
const result = resolveEccRoot({ envRoot: '', homeDir });
|
||||||
assert.strictEqual(result, claudeDir,
|
assert.strictEqual(result, claudeDir,
|
||||||
'Standard install should take precedence over plugin cache');
|
'Standard install should take precedence over plugin cache');
|
||||||
@ -184,13 +217,13 @@ function runTests() {
|
|||||||
if (test('handles multiple versions in plugin cache', () => {
|
if (test('handles multiple versions in plugin cache', () => {
|
||||||
const homeDir = createTempDir();
|
const homeDir = createTempDir();
|
||||||
try {
|
try {
|
||||||
setupPluginCache(homeDir, 'everything-claude-code', '1.7.0');
|
setupPluginCache(homeDir, 'everything-claude-code', 'legacy-org', '1.7.0');
|
||||||
const expected = setupPluginCache(homeDir, 'everything-claude-code', '1.8.0');
|
const expected = setupPluginCache(homeDir, 'ecc', 'affaan-m', '1.10.0');
|
||||||
const result = resolveEccRoot({ envRoot: '', homeDir });
|
const result = resolveEccRoot({ envRoot: '', homeDir });
|
||||||
// Should find one of them (either is valid)
|
// Should find one of them (either is valid)
|
||||||
assert.ok(
|
assert.ok(
|
||||||
result === expected ||
|
result === expected ||
|
||||||
result === path.join(homeDir, '.claude', 'plugins', 'cache', 'everything-claude-code', 'everything-claude-code', '1.7.0'),
|
result === path.join(homeDir, '.claude', 'plugins', 'cache', 'everything-claude-code', 'legacy-org', '1.7.0'),
|
||||||
'Should resolve to a valid plugin cache directory'
|
'Should resolve to a valid plugin cache directory'
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
@ -262,7 +295,7 @@ function runTests() {
|
|||||||
if (test('INLINE_RESOLVE discovers exact legacy plugin root when env var is unset', () => {
|
if (test('INLINE_RESOLVE discovers exact legacy plugin root when env var is unset', () => {
|
||||||
const homeDir = createTempDir();
|
const homeDir = createTempDir();
|
||||||
try {
|
try {
|
||||||
const expected = setupLegacyPluginInstall(homeDir, ['marketplace', 'everything-claude-code']);
|
const expected = setupLegacyPluginInstall(homeDir, ['marketplace', 'ecc']);
|
||||||
const { execFileSync } = require('child_process');
|
const { execFileSync } = require('child_process');
|
||||||
const result = execFileSync('node', [
|
const result = execFileSync('node', [
|
||||||
'-e', `console.log(${INLINE_RESOLVE})`,
|
'-e', `console.log(${INLINE_RESOLVE})`,
|
||||||
@ -278,7 +311,7 @@ function runTests() {
|
|||||||
if (test('INLINE_RESOLVE discovers plugin cache when env var is unset', () => {
|
if (test('INLINE_RESOLVE discovers plugin cache when env var is unset', () => {
|
||||||
const homeDir = createTempDir();
|
const homeDir = createTempDir();
|
||||||
try {
|
try {
|
||||||
const expected = setupPluginCache(homeDir, 'everything-claude-code', '1.10.0');
|
const expected = setupPluginCache(homeDir, 'ecc', 'affaan-m', '1.10.0');
|
||||||
const { execFileSync } = require('child_process');
|
const { execFileSync } = require('child_process');
|
||||||
const result = execFileSync('node', [
|
const result = execFileSync('node', [
|
||||||
'-e', `console.log(${INLINE_RESOLVE})`,
|
'-e', `console.log(${INLINE_RESOLVE})`,
|
||||||
|
|||||||
@ -79,6 +79,10 @@ test('claude plugin.json has version field', () => {
|
|||||||
assert.ok(claudePlugin.version, 'Expected version field');
|
assert.ok(claudePlugin.version, 'Expected version field');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('claude plugin.json uses short plugin slug', () => {
|
||||||
|
assert.strictEqual(claudePlugin.name, 'ecc');
|
||||||
|
});
|
||||||
|
|
||||||
test('claude plugin.json agents is an array', () => {
|
test('claude plugin.json agents is an array', () => {
|
||||||
assert.ok(Array.isArray(claudePlugin.agents), 'Expected agents to be an array (not a string/directory)');
|
assert.ok(Array.isArray(claudePlugin.agents), 'Expected agents to be an array (not a string/directory)');
|
||||||
});
|
});
|
||||||
@ -146,6 +150,10 @@ test('codex plugin.json has name field', () => {
|
|||||||
assert.ok(codexPlugin.name, 'Expected name field');
|
assert.ok(codexPlugin.name, 'Expected name field');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('codex plugin.json uses short plugin slug', () => {
|
||||||
|
assert.strictEqual(codexPlugin.name, 'ecc');
|
||||||
|
});
|
||||||
|
|
||||||
test('codex plugin.json has version field', () => {
|
test('codex plugin.json has version field', () => {
|
||||||
assert.ok(codexPlugin.version, 'Expected version field');
|
assert.ok(codexPlugin.version, 'Expected version field');
|
||||||
});
|
});
|
||||||
@ -240,6 +248,10 @@ test('marketplace.json has name field', () => {
|
|||||||
assert.ok(marketplace.name, 'Expected name field');
|
assert.ok(marketplace.name, 'Expected name field');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('marketplace.json uses short marketplace slug', () => {
|
||||||
|
assert.strictEqual(marketplace.name, 'ecc');
|
||||||
|
});
|
||||||
|
|
||||||
test('marketplace.json has plugins array with at least one entry', () => {
|
test('marketplace.json has plugins array with at least one entry', () => {
|
||||||
assert.ok(Array.isArray(marketplace.plugins) && marketplace.plugins.length > 0, 'Expected plugins array');
|
assert.ok(Array.isArray(marketplace.plugins) && marketplace.plugins.length > 0, 'Expected plugins array');
|
||||||
});
|
});
|
||||||
@ -253,6 +265,10 @@ test('marketplace.json plugin entries have required fields', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('marketplace.json plugin entry uses short plugin slug', () => {
|
||||||
|
assert.strictEqual(marketplace.plugins[0].name, 'ecc');
|
||||||
|
});
|
||||||
|
|
||||||
test('marketplace local plugin path resolves to the repo-root Codex bundle', () => {
|
test('marketplace local plugin path resolves to the repo-root Codex bundle', () => {
|
||||||
for (const plugin of marketplace.plugins) {
|
for (const plugin of marketplace.plugins) {
|
||||||
if (!plugin.source || plugin.source.source !== 'local') {
|
if (!plugin.source || plugin.source.source !== 'local') {
|
||||||
|
|||||||
@ -99,10 +99,10 @@ function runTests() {
|
|||||||
const projectRoot = createTempDir('harness-audit-project-');
|
const projectRoot = createTempDir('harness-audit-project-');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fs.mkdirSync(path.join(homeDir, '.claude', 'plugins', 'everything-claude-code', '.claude-plugin'), { recursive: true });
|
fs.mkdirSync(path.join(homeDir, '.claude', 'plugins', 'ecc', '.claude-plugin'), { recursive: true });
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
path.join(homeDir, '.claude', 'plugins', 'everything-claude-code', '.claude-plugin', 'plugin.json'),
|
path.join(homeDir, '.claude', 'plugins', 'ecc', '.claude-plugin', 'plugin.json'),
|
||||||
JSON.stringify({ name: 'everything-claude-code' }, null, 2)
|
JSON.stringify({ name: 'ecc' }, null, 2)
|
||||||
);
|
);
|
||||||
|
|
||||||
fs.mkdirSync(path.join(projectRoot, '.github', 'workflows'), { recursive: true });
|
fs.mkdirSync(path.join(projectRoot, '.github', 'workflows'), { recursive: true });
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user