fix: make plugin hooks run on Node 21+ and green the suite under modern Node (#2184)

ROOT CAUSE: hooks load plugin-hook-bootstrap.js via
`node -e "...; process.argv.splice(1,0,s); require(s)"`. On Node 21+,
require.main is `undefined` under --eval, so the `if (require.main === module)`
guard was false and main() never ran — every plugin hook silently no-op'd
(e.g. the MCP-health PreToolUse hook stopped blocking). CI (Node 18/20) hid
this; it only surfaces on Node 21+. Fix: also run main() when require.main is
undefined (the eval-bootstrap case), while staying dormant on real imports.

Also clears pre-existing main debt the full local suite enforces:
- catalog:sync — README/docs agent+skill counts drifted after recent merges
- tests/ci/supply-chain-watch-workflow: update checkout SHA to the merged v6.0.3 (#2183)
- markdownlint + check-unicode-safety --write across docs/skills

Suite: 2683/2683 green under Node v25; lint + unicode clean.

Co-authored-by: ECC Test <ecc@example.test>
This commit is contained in:
Affaan Mustafa 2026-06-07 16:05:28 +08:00 committed by GitHub
parent eef31ad39c
commit e755c5f72b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
36 changed files with 613 additions and 609 deletions

View File

@ -11,7 +11,7 @@
{
"name": "ecc",
"source": "./",
"description": "Harness-native ECC operator layer - 63 agents, 251 skills, 79 legacy command shims, reusable hooks, rules, selective install profiles, and production-ready workflows for Claude Code, Codex, OpenCode, Cursor, and related agent harnesses",
"description": "Harness-native ECC operator layer - 64 agents, 255 skills, 79 legacy command shims, reusable hooks, rules, selective install profiles, and production-ready workflows for Claude Code, Codex, OpenCode, Cursor, and related agent harnesses",
"version": "2.0.0-rc.1",
"author": {
"name": "Affaan Mustafa",

View File

@ -1,7 +1,7 @@
{
"name": "ecc",
"version": "2.0.0-rc.1",
"description": "Harness-native ECC plugin for engineering teams - 63 agents, 251 skills, 79 legacy command shims, reusable hooks, rules, MCP conventions, and operator workflows for Claude Code plus adjacent agent harnesses",
"description": "Harness-native ECC plugin for engineering teams - 64 agents, 255 skills, 79 legacy command shims, reusable hooks, rules, MCP conventions, and operator workflows for Claude Code plus adjacent agent harnesses",
"author": {
"name": "Affaan Mustafa",
"url": "https://x.com/affaanmustafa"

View File

@ -1,6 +1,6 @@
# Everything Claude Code (ECC) — Agent Instructions
This is a **production-ready AI coding plugin** providing 63 specialized agents, 251 skills, 79 commands, and automated hook workflows for software development.
This is a **production-ready AI coding plugin** providing 64 specialized agents, 255 skills, 79 commands, and automated hook workflows for software development.
**Version:** 2.0.0-rc.1
@ -149,8 +149,8 @@ Troubleshoot failures: check test isolation → verify mocks → fix implementat
## Project Structure
```
agents/ — 63 specialized subagents
skills/ — 251 workflow skills and domain knowledge
agents/ — 64 specialized subagents
skills/ — 255 workflow skills and domain knowledge
commands/ — 79 slash commands
hooks/ — Trigger-based automations
rules/ — Always-follow guidelines (common + per-language)

View File

@ -123,7 +123,7 @@ This repo is the raw code only. The guides explain everything.
### v2.0.0-rc.1 — Surface Refresh, Operator Workflows, and ECC 2.0 Alpha (Apr 2026)
- **Dashboard GUI** — New Tkinter-based desktop application (`ecc_dashboard.py` or `npm run dashboard`) with dark/light theme toggle, font customization, and project logo in header and taskbar.
- **Public surface synced to the live repo** — metadata, catalog counts, plugin manifests, and install-facing docs now match the actual OSS surface: 63 agents, 251 skills, and 79 legacy command shims.
- **Public surface synced to the live repo** — metadata, catalog counts, plugin manifests, and install-facing docs now match the actual OSS surface: 64 agents, 255 skills, and 79 legacy command shims.
- **Operator and outbound workflow expansion**`brand-voice`, `social-graph-ranker`, `connections-optimizer`, `customer-billing-ops`, `ecc-tools-cost-audit`, `google-workspace-ops`, `project-flow-ops`, and `workspace-surface-audit` round out the operator lane.
- **Media and launch tooling**`manim-video`, `remotion-video-creation`, and upgraded social publishing surfaces make technical explainers and launch content part of the same system.
- **Framework and product surface growth**`nestjs-patterns`, richer Codex/OpenCode install surfaces, and expanded cross-harness packaging keep the repo usable beyond Claude Code alone.
@ -394,7 +394,7 @@ If you stacked methods, clean up in this order:
/plugin list ecc@ecc
```
**That's it!** You now have access to 63 agents, 251 skills, and 79 legacy command shims.
**That's it!** You now have access to 64 agents, 255 skills, and 79 legacy command shims.
### Dashboard GUI
@ -487,7 +487,6 @@ export ECC_SESSION_RETENTION_DAYS=14
export ECC_CONTEXT_MONITOR_COST_WARNINGS=off
```
Windows PowerShell:
```powershell
@ -525,7 +524,7 @@ ECC/
| |-- plugin.json # Plugin metadata and component paths
| |-- marketplace.json # Marketplace catalog for /plugin marketplace add
|
|-- agents/ # 63 specialized subagents for delegation
|-- agents/ # 64 specialized subagents for delegation
| |-- planner.md # Feature implementation planning
| |-- architect.md # System design decisions
| |-- tdd-guide.md # Test-driven development
@ -1472,9 +1471,9 @@ The configuration is automatically detected from `.opencode/opencode.json`.
| Feature | Claude Code | OpenCode | Status |
|---------|---------------------|----------|--------|
| Agents | PASS: 63 agents | PASS: 12 agents | **Claude Code leads** |
| Agents | PASS: 64 agents | PASS: 12 agents | **Claude Code leads** |
| Commands | PASS: 79 commands | PASS: 35 commands | **Claude Code leads** |
| Skills | PASS: 251 skills | PASS: 37 skills | **Claude Code leads** |
| Skills | PASS: 255 skills | PASS: 37 skills | **Claude Code leads** |
| Hooks | PASS: 8 event types | PASS: 11 events | **OpenCode has more!** |
| Rules | PASS: 29 rules | PASS: 13 instructions | **Claude Code leads** |
| MCP Servers | PASS: 14 servers | PASS: Full | **Full parity** |
@ -1634,9 +1633,9 @@ ECC is the **first plugin to maximize every major AI coding tool**. Here's how e
| Feature | Claude Code | Cursor IDE | Codex CLI | OpenCode | GitHub Copilot |
|---------|-----------------------|------------|-----------|----------|----------------|
| **Agents** | 63 | Shared (AGENTS.md) | Shared (AGENTS.md) | 12 | N/A |
| **Agents** | 64 | Shared (AGENTS.md) | Shared (AGENTS.md) | 12 | N/A |
| **Commands** | 79 | Shared | Instruction-based | 35 | 6 prompts |
| **Skills** | 251 | Shared | 10 (native format) | 37 | Via instructions |
| **Skills** | 255 | Shared | 10 (native format) | 37 | Via instructions |
| **Hook Events** | 8 types | 15 types | None yet | 11 types | None |
| **Hook Scripts** | 20+ scripts | 16 scripts (DRY adapter) | N/A | Plugin hooks | N/A |
| **Rules** | 34 (common + lang) | 34 (YAML frontmatter) | Instruction-based | 13 instructions | 1 always-on file |

View File

@ -160,7 +160,7 @@ Copy-Item -Recurse rules/typescript "$HOME/.claude/rules/"
/plugin list ecc@ecc
```
**完成!** 你现在可以使用 63 个代理、251 个技能和 79 个命令。
**完成!** 你现在可以使用 64 个代理、255 个技能和 79 个命令。
### multi-* 命令需要额外配置

View File

@ -96,7 +96,7 @@ Fix: What to change
## Framework Checks
- **Laravel**: N+1 via `with()`/`load()`, `$fillable`/`$casts`, FormRequest validation, route model binding, `Gate`/`Policy` authorization, Sanctum token abilities, queue idempotency
- **Livewire**: Proper `#[Rule]` attributes, authorization in ` authorize()`, wire:model security
- **Livewire**: Proper `#[Rule]` attributes, authorization in `authorize()`, wire:model security
- **Filament**: Form/table authorization, `canAccess()`, policy registration
- **Plain PHP**: PDO prepared statements, password_hash/password_verify, header-based CSRF

View File

@ -47,26 +47,26 @@ ECC v2.0.0-rc.1 اس قابل استعمال پرت پر عوامی Hermes آپ
<tr>
<td width="25%" align="center">
<a href="https://ecc.tools/pricing">
<strong>💼 ECC Pro</strong><br />
<strong> ECC Pro</strong><br />
<sub>نجی ریپوز · GitHub App · $19/نشست/ماہ</sub>
</a>
</td>
<td width="25%" align="center">
<a href="https://github.com/sponsors/affaan-m">
<strong>❤️ اسپانسر</strong><br />
<strong> اسپانسر</strong><br />
<sub>OSS کو فنڈ کریں · $5/ماہ سے</sub>
</a>
</td>
<td width="25%" align="center">
<a href="https://github.com/affaan-m/ECC/discussions">
<strong>💬 کمیونٹی</strong>
<strong> کمیونٹی</strong>
<br />
<sub>Discussions · Q&amp;A · Show & Tell</sub>
</a>
</td>
<td width="25%" align="center">
<a href="https://github.com/apps/ecc-tools">
<strong>🤖 GitHub App</strong><br />
<strong> GitHub App</strong><br />
<sub>انسٹال · PR آڈٹس · مفت ٹیئر</sub>
</a>
</td>

View File

@ -1,6 +1,6 @@
# Everything Claude Code (ECC) — 智能体指令
这是一个**生产就绪的 AI 编码插件**,提供 63 个专业代理、251 项技能、79 条命令以及自动化钩子工作流,用于软件开发。
这是一个**生产就绪的 AI 编码插件**,提供 64 个专业代理、255 项技能、79 条命令以及自动化钩子工作流,用于软件开发。
**版本:** 2.0.0-rc.1
@ -146,8 +146,8 @@
## 项目结构
```
agents/ — 63 个专业子代理
skills/ — 251 个工作流技能和领域知识
agents/ — 64 个专业子代理
skills/ — 255 个工作流技能和领域知识
commands/ — 79 个斜杠命令
hooks/ — 基于触发的自动化
rules/ — 始终遵循的指导方针(通用 + 每种语言)

View File

@ -224,7 +224,7 @@ Copy-Item -Recurse rules/typescript "$HOME/.claude/rules/"
/plugin list ecc@ecc
```
**搞定!** 你现在可以使用 63 个智能体、251 项技能和 79 个命令了。
**搞定!** 你现在可以使用 64 个智能体、255 项技能和 79 个命令了。
***
@ -1136,9 +1136,9 @@ opencode
| 功能特性 | Claude Code | OpenCode | 状态 |
|---------|---------------|----------|--------|
| 智能体 | PASS: 63 个 | PASS: 12 个 | **Claude Code 领先** |
| 智能体 | PASS: 64 个 | PASS: 12 个 | **Claude Code 领先** |
| 命令 | PASS: 79 个 | PASS: 35 个 | **Claude Code 领先** |
| 技能 | PASS: 251 项 | PASS: 37 项 | **Claude Code 领先** |
| 技能 | PASS: 255 项 | PASS: 37 项 | **Claude Code 领先** |
| 钩子 | PASS: 8 种事件类型 | PASS: 11 种事件 | **OpenCode 更多!** |
| 规则 | PASS: 29 条 | PASS: 13 条指令 | **Claude Code 领先** |
| MCP 服务器 | PASS: 14 个 | PASS: 完整 | **完全对等** |
@ -1244,9 +1244,9 @@ ECC 是**第一个最大化利用每个主要 AI 编码工具的插件**。以
| 功能特性 | Claude Code | Cursor IDE | Codex CLI | OpenCode |
|---------|-----------------------|------------|-----------|----------|
| **智能体** | 63 | 共享 (AGENTS.md) | 共享 (AGENTS.md) | 12 |
| **智能体** | 64 | 共享 (AGENTS.md) | 共享 (AGENTS.md) | 12 |
| **命令** | 79 | 共享 | 基于指令 | 35 |
| **技能** | 251 | 共享 | 10 (原生格式) | 37 |
| **技能** | 255 | 共享 | 10 (原生格式) | 37 |
| **钩子事件** | 8 种类型 | 15 种类型 | 暂无 | 11 种类型 |
| **钩子脚本** | 20+ 个脚本 | 16 个脚本 (DRY 适配器) | N/A | 插件钩子 |
| **规则** | 34 (通用 + 语言) | 34 (YAML 前页) | 基于指令 | 13 条指令 |

View File

@ -171,7 +171,14 @@ function main() {
process.exit(Number.isInteger(result.status) ? result.status : 0);
}
if (require.main === module) {
// Run when invoked as a hook entry. Production hooks load this via
// `node -e "...; process.argv.splice(1,0,s); require(s)"`; on Node 21+ that
// leaves require.main undefined (not this module), which previously skipped
// main() and made every plugin hook a silent no-op. Guard on both the
// direct-entry case and that eval-bootstrap case. When imported for its
// exports (tests), require.main is a real, different module, so main() stays
// dormant.
if (require.main === module || require.main === undefined) {
main();
}

View File

@ -203,8 +203,7 @@ Use ARIA only when native HTML semantics are insufficient. Wrong ARIA is worse t
<button
aria-describedby="delete-warning"
onClick={handleDelete}
>
Delete account
> Delete account
</button>
<p id="delete-warning">This action cannot be undone.</p>
```

View File

@ -71,9 +71,9 @@ Before interrupting the user, evaluate signal strength:
For each strong-signal conflict, present exactly ONE question with 4 options:
> 📄 Evidence: `pathA` uses style X, `pathB` uses style Y
> ⚠️ Risk: mixing both fractures the project style
> Choose: `1` follow X `2` follow Y `3` this is evolution, update rules `4` I have a new rule
> Evidence: `pathA` uses style X, `pathB` uses style Y
> WARNING: Risk: mixing both fractures the project style
> Choose: `1` follow X `2` follow Y `3` this is evolution, update rules `4` I have a new rule
Suspend until the user answers, then proceed to the next conflict. Never stack questions.
@ -89,7 +89,7 @@ Ask the user for enforcement strength (use `AskUserQuestion`):
| Option | Mechanism |
|---|---|
| **1** Soft hook (recommended) | Write `@.ai-style-rules.md` reference into project `CLAUDE.md` |
| **2** Hard hook | Soft hook + `PreToolUse[Write|Edit|MultiEdit]` Hook in `settings.json` |
| **2** Hard hook | Soft hook + `PreToolUse[Write\|Edit\|MultiEdit]` Hook in `settings.json` |
| **3** No hook | Keep the rules file; user references manually |
### Branch B — Incremental Sniff
@ -120,12 +120,12 @@ This skill auto-detects whether it's a first-time or incremental run via `.ai-st
## Anti-Patterns
- Do NOT skip the scale measurement step — sampling a 30-file project "starves" it; full-scanning a 5,000-file repo blows up
- Do NOT stack multiple conflict questions at once — grilling is strictly one-at-a-time
- Do NOT overwrite old rules in incremental mode — always append evolution logs
- Do NOT default to "hard hook" without asking — enforcement strength is the user's call
- Do NOT judge syntax or tech-stack quality — this skill aligns meta-architecture only
- Do NOT copy bugs from exemplar files — reuse structure, flag defects
- FAIL: Do NOT skip the scale measurement step — sampling a 30-file project "starves" it; full-scanning a 5,000-file repo blows up
- FAIL: Do NOT stack multiple conflict questions at once — grilling is strictly one-at-a-time
- FAIL: Do NOT overwrite old rules in incremental mode — always append evolution logs
- FAIL: Do NOT default to "hard hook" without asking — enforcement strength is the user's call
- FAIL: Do NOT judge syntax or tech-stack quality — this skill aligns meta-architecture only
- FAIL: Do NOT copy bugs from exemplar files — reuse structure, flag defects
## Best Practices

View File

@ -337,8 +337,7 @@ export function ExpandingCard({ title, body }: { title: string; body: string })
duration: motionTokens.duration.normal,
ease: motionTokens.easing.smooth,
}}
>
{children}
> {children}
</motion.div>
```

View File

@ -43,7 +43,7 @@ function run() {
if (test('uses read-only permissions and non-persisting checkout credentials', () => {
assert.match(source, /permissions:\r?\n\s+contents: read/);
assert.doesNotMatch(source, /^\s+[A-Za-z-]+:\s*write\b/m);
assert.match(source, /uses: actions\/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd/);
assert.match(source, /uses: actions\/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10/);
assert.match(source, /persist-credentials: false/);
assert.doesNotMatch(source, /id-token:\s*write/);
assert.doesNotMatch(source, /actions\/cache@/);