diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index c5a7f5bf8..e4e40b23f 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -11,7 +11,7 @@ { "name": "ecc", "source": "./", - "description": "Harness-native ECC operator layer - 68 agents, 294 skills, 94 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 - 69 agents, 295 skills, 94 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.2.2", "author": { "name": "Affaan Mustafa", diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 5df8c7cca..a9a6b3818 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "ecc", "version": "2.2.2", - "description": "Harness-native ECC plugin for engineering teams - 68 agents, 294 skills, 94 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 - 69 agents, 295 skills, 94 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" diff --git a/.gemini/GEMINI.md b/.gemini/GEMINI.md index 4dda5bb21..48f0f95ad 100644 --- a/.gemini/GEMINI.md +++ b/.gemini/GEMINI.md @@ -4,7 +4,7 @@ This file provides Gemini CLI with the baseline ECC workflow, review standards, ## Overview -Everything Claude Code (ECC) is a cross-harness coding system with 68 specialized agents, 294 skills, and 94 commands. +Everything Claude Code (ECC) is a cross-harness coding system with 69 specialized agents, 295 skills, and 94 commands. Gemini support is currently focused on a strong project-local instruction layer via `.gemini/GEMINI.md`, plus the shared MCP catalog and package-manager setup assets shipped by the installer. diff --git a/AGENTS.md b/AGENTS.md index 8a30558eb..f78c43c7e 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,6 @@ # Everything Claude Code (ECC) — Agent Instructions -This is a **production-ready AI coding plugin** providing 68 specialized agents, 294 skills, 94 commands, and automated hook workflows for software development. +This is a **production-ready AI coding plugin** providing 69 specialized agents, 295 skills, 94 commands, and automated hook workflows for software development. **Version:** 2.2.2 @@ -20,6 +20,7 @@ This is a **production-ready AI coding plugin** providing 68 specialized agents, | architect | System design and scalability | Architectural decisions | | tdd-guide | Test-driven development | New features, bug fixes | | code-reviewer | Code quality and maintainability | After writing/modifying code | +| bengali-reviewer | Bengali text review | Unicode, normalization, grapheme, search, and locale correctness | | security-reviewer | Vulnerability detection | Before commits, sensitive code | | spec-miner | Brownfield spec extraction | Onboarding brownfield projects to spec-driven development | | build-error-resolver | Fix build/type errors | When build fails | @@ -200,8 +201,8 @@ Troubleshoot failures: check test isolation → verify mocks → fix implementat ## Project Structure ``` -agents/ — 68 specialized subagents -skills/ — 294 workflow skills and domain knowledge +agents/ — 69 specialized subagents +skills/ — 295 workflow skills and domain knowledge commands/ — 94 slash commands hooks/ — Trigger-based automations rules/ — Always-follow guidelines (common + per-language) diff --git a/README.md b/README.md index 5cec0bd09..e243a4903 100644 --- a/README.md +++ b/README.md @@ -140,12 +140,12 @@ Instead of rebuilding that process in every prompt, you install it once and make ECC is MIT-licensed open source. It works best with Claude Code today, has a supported Codex sync path, and provides capability-limited adapters for Cursor, OpenCode, Gemini, Zed, GitHub Copilot, Antigravity, Qwen, and other harnesses. See the [support status matrix](#platform-support) before assuming feature parity. -Access to 68 agents, 294 skills, and 94 legacy command shims, plus hooks, rules, memory, continuous learning, and AgentShield security scanning. The agents are specialized for planning, review, build repair, security, architecture, and domain work. +Access to 69 agents, 295 skills, and 94 legacy command shims, plus hooks, rules, memory, continuous learning, and AgentShield security scanning. The agents are specialized for planning, review, build repair, security, architecture, and domain work. | Included | Count | What it gives you | | ---------------- | ----------: | ------------------------------------------------------------------------------------ | -| Agents | 68 agents | Planning, review, build repair, security, architecture, and domain work | -| Skills | 294 skills | TDD, research, security, docs, frontend, data, ML, operations, and more | +| Agents | 69 agents | Planning, review, build repair, security, architecture, and domain work | +| Skills | 295 skills | TDD, research, security, docs, frontend, data, ML, operations, and more | | Commands | 94 commands | Convenient entry points while ECC moves to a skills-first surface | | Hooks and memory | Runtime | Enforcement, session summaries, continuous learning, instincts, and context controls | | Rules | Selective | Always-loaded standards you choose by language or project | @@ -825,7 +825,7 @@ Stable graduation of the 2.0 line: control-pane substrate, worktree lifecycle se ```text ECC/ -|-- agents/ # 68 specialized subagents for delegation +|-- agents/ # 69 specialized subagents for delegation |-- skills/ # 293 reusable workflows loaded on demand |-- commands/ # 94 maintained slash-command shims |-- rules/ # opt-in common and language standards diff --git a/README.zh-CN.md b/README.zh-CN.md index a31159e35..ff63a61c4 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -196,7 +196,7 @@ Copy-Item -Recurse rules/typescript "$HOME/.claude/rules/" /plugin list ecc@ecc ``` -**完成!** 你现在可以使用 68 个代理、294 个技能和 94 个命令。 +**完成!** 你现在可以使用 69 个代理、295 个技能和 94 个命令。 ### multi-* 命令需要额外配置 diff --git a/SOUL.md b/SOUL.md index f0afc4859..604396d84 100644 --- a/SOUL.md +++ b/SOUL.md @@ -1,7 +1,7 @@ # Soul ## Core Identity -Everything Claude Code (ECC) is a production-ready AI coding plugin with 68 specialized agents, 294 skills, 94 commands, and automated hook workflows for software development. +Everything Claude Code (ECC) is a production-ready AI coding plugin with 69 specialized agents, 295 skills, 94 commands, and automated hook workflows for software development. ## Core Principles 1. **Agent-First** — route work to the right specialist as early as possible. diff --git a/docs/zh-CN/AGENTS.md b/docs/zh-CN/AGENTS.md index b2e3955eb..d3727bb6a 100644 --- a/docs/zh-CN/AGENTS.md +++ b/docs/zh-CN/AGENTS.md @@ -1,6 +1,6 @@ # Everything Claude Code (ECC) — 智能体指令 -这是一个**生产就绪的 AI 编码插件**,提供 68 个专业代理、294 项技能、94 条命令以及自动化钩子工作流,用于软件开发。 +这是一个**生产就绪的 AI 编码插件**,提供 69 个专业代理、295 项技能、94 条命令以及自动化钩子工作流,用于软件开发。 **版本:** 2.2.2 @@ -146,8 +146,8 @@ ## 项目结构 ``` -agents/ — 68 个专业子代理 -skills/ — 294 个工作流技能和领域知识 +agents/ — 69 个专业子代理 +skills/ — 295 个工作流技能和领域知识 commands/ — 94 个斜杠命令 hooks/ — 基于触发的自动化 rules/ — 始终遵循的指导方针(通用 + 每种语言) diff --git a/docs/zh-CN/README.md b/docs/zh-CN/README.md index eeaa41c29..e50534cb1 100644 --- a/docs/zh-CN/README.md +++ b/docs/zh-CN/README.md @@ -260,7 +260,7 @@ Copy-Item -Recurse rules/typescript "$HOME/.claude/rules/" /plugin list ecc@ecc ``` -**搞定!** 你现在可以使用 68 个智能体、294 项技能和 94 个命令了。 +**搞定!** 你现在可以使用 69 个智能体、295 项技能和 94 个命令了。 *** @@ -1172,9 +1172,9 @@ opencode | 功能特性 | Claude Code | OpenCode | 状态 | |---------|---------------|----------|--------| -| 智能体 | PASS: 68 个 | PASS: 12 个 | **Claude Code 领先** | +| 智能体 | PASS: 69 个 | PASS: 12 个 | **Claude Code 领先** | | 命令 | PASS: 94 个 | PASS: 35 个 | **Claude Code 领先** | -| 技能 | PASS: 294 项 | PASS: 37 项 | **Claude Code 领先** | +| 技能 | PASS: 295 项 | PASS: 37 项 | **Claude Code 领先** | | 钩子 | PASS: 8 种事件类型 | PASS: 11 种事件 | **OpenCode 更多!** | | 规则 | PASS: 29 条 | PASS: 13 条指令 | **Claude Code 领先** | | MCP 服务器 | PASS: 14 个 | PASS: 完整 | **完全对等** | @@ -1280,9 +1280,9 @@ ECC 是**第一个最大化利用每个主要 AI 编码工具的插件**。以 | 功能特性 | Claude Code | Cursor IDE | Codex CLI | OpenCode | |---------|-----------------------|------------|-----------|----------| -| **智能体** | 68 | 共享 (AGENTS.md) | 共享 (AGENTS.md) | 12 | +| **智能体** | 69 | 共享 (AGENTS.md) | 共享 (AGENTS.md) | 12 | | **命令** | 94 | 共享 | 基于指令 | 35 | -| **技能** | 294 | 共享 | 10 (原生格式) | 37 | +| **技能** | 295 | 共享 | 10 (原生格式) | 37 | | **钩子事件** | 8 种类型 | 15 种类型 | SessionStart(1 种类型) | 11 种类型 | | **钩子脚本** | 20+ 个脚本 | 16 个脚本 (DRY 适配器) | 1 个 SessionStart 引导脚本 | 插件钩子 | | **规则** | 34 (通用 + 语言) | 34 (YAML 前页) | 基于指令 | 13 条指令 | diff --git a/ecc2/src/config/mod.rs b/ecc2/src/config/mod.rs index 38fd467a1..bdfdc5a8c 100644 --- a/ecc2/src/config/mod.rs +++ b/ecc2/src/config/mod.rs @@ -523,16 +523,36 @@ impl Config { // never overwrite the developer's real config. struct TestConfigRoot(PathBuf); + impl TestConfigRoot { + fn new() -> Self { + let path = std::env::temp_dir() + .join(format!("ecc2-test-config-{}", uuid::Uuid::new_v4())); + std::fs::create_dir(&path).expect("create private ECC 2 test config root"); + #[cfg(unix)] + { + use std::os::unix::fs::PermissionsExt; + std::fs::set_permissions(&path, std::fs::Permissions::from_mode(0o700)) + .expect("restrict ECC 2 test config root permissions"); + } + Self(path) + } + } + impl Drop for TestConfigRoot { fn drop(&mut self) { - let _ = std::fs::remove_dir_all(&self.0); + if let Err(error) = std::fs::remove_dir_all(&self.0) { + if error.kind() != std::io::ErrorKind::NotFound { + eprintln!( + "failed to remove ECC 2 test config root {}: {error}", + self.0.display() + ); + } + } } } thread_local! { - static ROOT: TestConfigRoot = TestConfigRoot( - std::env::temp_dir().join(format!("ecc2-test-config-{}", uuid::Uuid::new_v4())), - ); + static ROOT: TestConfigRoot = TestConfigRoot::new(); } ROOT.with(|root| root.0.clone()) @@ -1149,6 +1169,16 @@ focus_metrics = "e" assert_eq!(Config::config_path(), Config::config_path()); } + #[cfg(unix)] + #[test] + fn config_root_under_test_is_owner_only() { + use std::os::unix::fs::PermissionsExt; + + let root = Config::config_root(); + let mode = std::fs::metadata(root).unwrap().permissions().mode() & 0o777; + assert_eq!(mode, 0o700); + } + #[test] fn primary_config_path_uses_xdg_style_location() { let path = Config::config_path(); diff --git a/manifests/context-packs/skill-triggers@1.json b/manifests/context-packs/skill-triggers@1.json index 2db4bf4ee..fcccaae2e 100644 --- a/manifests/context-packs/skill-triggers@1.json +++ b/manifests/context-packs/skill-triggers@1.json @@ -1 +1 @@ -{"coverage":{"skills":294,"withTriggers":33},"generatedAt":"2026-09-30T01:50:48.425Z","id":"skill-triggers@1","model":{"effort":null,"id":"hand-seeded","source":"manual-curation-pending-regeneration"},"registryDigest":"2fcaf1c7a876e2099dcab469f2a5194c7538ea1444822909dcc37375af8bb3a4","schemaVersion":1,"triggers":{"skill:api-connector-builder":["add api integration","new provider connector","match existing integration pattern"],"skill:api-design":["rest endpoint design","pagination api","status codes","api versioning","rate limiting api","resource naming","filtering api","api error responses","offset pagination","limit query parameter","pagination defaults"],"skill:backend-patterns":["express api","node backend architecture","nextjs api routes","server side patterns","data access layer","static file server","url path handling","file server"],"skill:browser-qa":["deployed feature test","visual regression screenshots","core web vitals check","axe accessibility audit","ship do not ship","staging verification"],"skill:canary-watch":["post deploy monitoring","smoke test url","production url check","console errors production","sse stream check","after deploy verification"],"skill:code-tour":["onboarding walkthrough","explain subsystem","architecture tour","pr walkthrough","rca tour"],"skill:coding-standards":["code review standards","naming conventions","readability review","immutability conventions","fix naming typo","export naming","consistent exports"],"skill:content-hash-cache-pattern":["cache file processing","content addressed cache","sha256 hash cache"],"skill:database-migrations":["zero downtime migration","schema change production","add column large table","backfill data","expand contract","concurrent index","migration rollback","prisma migration","django migration"],"skill:deployment-patterns":["ci cd setup","dockerize app","health checks","rollback strategy","production readiness","deploy pipeline","containerize application"],"skill:design-system":["design tokens","visual consistency audit","css custom properties","ui audit","design system bootstrap"],"skill:django-patterns":["django orm","drf api","django rest framework","django caching","django signals","django middleware"],"skill:django-security":["django authentication","csrf protection","sql injection prevention","xss prevention","django deployment security","role based access control","authorization middleware","permissions checks"],"skill:docker-patterns":["dockerfile review","docker compose setup","container security","multi service orchestration"],"skill:error-handling":["error types","retry logic","circuit breaker","user facing errors","exception handling patterns","typed errors","error boundaries","go error handling","custom error class","error codes","config validation"],"skill:evm-token-decimals":["token decimals","wei conversion","erc20 balance off","bridge token precision"],"skill:frontend-a11y":["aria attributes","screen reader support","focus management","semantic html","form labeling","keyboard navigation react","a11y lint errors"],"skill:git-workflow":["merge vs rebase","commit conventions","resolve merge conflict","branching strategy","clean up commits","pull request cleanup","git history tidy"],"skill:hexagonal-architecture":["ports and adapters","dependency injection boundaries","decouple domain from io"],"skill:kubernetes-patterns":["kubernetes manifests","kubectl debugging","pod probes","k8s rbac","autoscaling config","configmap secrets"],"skill:mybatis-patterns":["mybatis mapper xml","mybatis spring mapper","mybatis resultmap mapping","mybatis dynamic sql","mybatis parameter binding","mybatis sql injection","mybatis transaction boundary","mybatis batch insert","mybatis pagination","mybatis query performance","spring boot mybatis persistence","mybatis legacy dao"],"skill:orch-fix-defect":["fix a bug","broken behavior","regression fix","reproduce bug","defect repair"],"skill:postgres-patterns":["slow postgres query","query optimization","index design","rls policies","supabase schema","postgres indexing","database performance","schema design postgres","postgres driver","node postgres","query planner"],"skill:python-patterns":["pythonic code","pep 8","type hints python","python code review","idiomatic python"],"skill:python-testing":["pytest fixtures","mocking python","parametrized tests","coverage python","tdd python"],"skill:redis-patterns":["cache aside pattern","distributed lock","redis rate limiting","cache invalidation"],"skill:regex-vs-llm-structured-text":["parse invoice","extract receipt data","text extraction pipeline","parse form fields","cheap document parser","extract table data","parse log lines","parse access logs","common log format","log line parsing"],"skill:rust-patterns":["rust ownership","borrow checker","rust error handling","traits rust","rust concurrency","idiomatic rust"],"skill:search-first":["find existing library","npm package research","before writing custom code","evaluate existing tools","add dependency research"],"skill:security-review":["security audit","authentication review","sanitize user input","secrets handling","payment security checklist","prevent injection attacks","secure api endpoints","authn authz review","vulnerability checklist","input validation security","parameterized queries","sql injection"],"skill:security-scan":["audit claude config","claudemd security","mcp server audit","agentshield scan","hook configuration audit","settings json security"],"skill:tdd-workflow":["write test first","failing test","red green refactor","test driven development","regression test first","write a regression test"],"skill:verification-loop":["pre pr checks","verification report","quality gates","build lint test coverage","before creating a pr"]},"triggersDigest":"f4ef0aad185708bcf92caff2b280fbee09361a164273106ec33a7ab505018966"} +{"coverage":{"skills":295,"withTriggers":33},"generatedAt":"2026-09-30T17:25:13.581Z","id":"skill-triggers@1","model":{"effort":null,"id":"hand-seeded","source":"manual-curation-pending-regeneration"},"registryDigest":"a9800609d628eaab0206e04adbab615757590ef4f4cb99f192f06259e9ba91bd","schemaVersion":1,"triggers":{"skill:api-connector-builder":["add api integration","new provider connector","match existing integration pattern"],"skill:api-design":["rest endpoint design","pagination api","status codes","api versioning","rate limiting api","resource naming","filtering api","api error responses","offset pagination","limit query parameter","pagination defaults"],"skill:backend-patterns":["express api","node backend architecture","nextjs api routes","server side patterns","data access layer","static file server","url path handling","file server"],"skill:browser-qa":["deployed feature test","visual regression screenshots","core web vitals check","axe accessibility audit","ship do not ship","staging verification"],"skill:canary-watch":["post deploy monitoring","smoke test url","production url check","console errors production","sse stream check","after deploy verification"],"skill:code-tour":["onboarding walkthrough","explain subsystem","architecture tour","pr walkthrough","rca tour"],"skill:coding-standards":["code review standards","naming conventions","readability review","immutability conventions","fix naming typo","export naming","consistent exports"],"skill:content-hash-cache-pattern":["cache file processing","content addressed cache","sha256 hash cache"],"skill:database-migrations":["zero downtime migration","schema change production","add column large table","backfill data","expand contract","concurrent index","migration rollback","prisma migration","django migration"],"skill:deployment-patterns":["ci cd setup","dockerize app","health checks","rollback strategy","production readiness","deploy pipeline","containerize application"],"skill:design-system":["design tokens","visual consistency audit","css custom properties","ui audit","design system bootstrap"],"skill:django-patterns":["django orm","drf api","django rest framework","django caching","django signals","django middleware"],"skill:django-security":["django authentication","csrf protection","sql injection prevention","xss prevention","django deployment security","role based access control","authorization middleware","permissions checks"],"skill:docker-patterns":["dockerfile review","docker compose setup","container security","multi service orchestration"],"skill:error-handling":["error types","retry logic","circuit breaker","user facing errors","exception handling patterns","typed errors","error boundaries","go error handling","custom error class","error codes","config validation"],"skill:evm-token-decimals":["token decimals","wei conversion","erc20 balance off","bridge token precision"],"skill:frontend-a11y":["aria attributes","screen reader support","focus management","semantic html","form labeling","keyboard navigation react","a11y lint errors"],"skill:git-workflow":["merge vs rebase","commit conventions","resolve merge conflict","branching strategy","clean up commits","pull request cleanup","git history tidy"],"skill:hexagonal-architecture":["ports and adapters","dependency injection boundaries","decouple domain from io"],"skill:kubernetes-patterns":["kubernetes manifests","kubectl debugging","pod probes","k8s rbac","autoscaling config","configmap secrets"],"skill:mybatis-patterns":["mybatis mapper xml","mybatis spring mapper","mybatis resultmap mapping","mybatis dynamic sql","mybatis parameter binding","mybatis sql injection","mybatis transaction boundary","mybatis batch insert","mybatis pagination","mybatis query performance","spring boot mybatis persistence","mybatis legacy dao"],"skill:orch-fix-defect":["fix a bug","broken behavior","regression fix","reproduce bug","defect repair"],"skill:postgres-patterns":["slow postgres query","query optimization","index design","rls policies","supabase schema","postgres indexing","database performance","schema design postgres","postgres driver","node postgres","query planner"],"skill:python-patterns":["pythonic code","pep 8","type hints python","python code review","idiomatic python"],"skill:python-testing":["pytest fixtures","mocking python","parametrized tests","coverage python","tdd python"],"skill:redis-patterns":["cache aside pattern","distributed lock","redis rate limiting","cache invalidation"],"skill:regex-vs-llm-structured-text":["parse invoice","extract receipt data","text extraction pipeline","parse form fields","cheap document parser","extract table data","parse log lines","parse access logs","common log format","log line parsing"],"skill:rust-patterns":["rust ownership","borrow checker","rust error handling","traits rust","rust concurrency","idiomatic rust"],"skill:search-first":["find existing library","npm package research","before writing custom code","evaluate existing tools","add dependency research"],"skill:security-review":["security audit","authentication review","sanitize user input","secrets handling","payment security checklist","prevent injection attacks","secure api endpoints","authn authz review","vulnerability checklist","input validation security","parameterized queries","sql injection"],"skill:security-scan":["audit claude config","claudemd security","mcp server audit","agentshield scan","hook configuration audit","settings json security"],"skill:tdd-workflow":["write test first","failing test","red green refactor","test driven development","regression test first","write a regression test"],"skill:verification-loop":["pre pr checks","verification report","quality gates","build lint test coverage","before creating a pr"]},"triggersDigest":"f4ef0aad185708bcf92caff2b280fbee09361a164273106ec33a7ab505018966"} diff --git a/pi/core/skills/laravel-security/SKILL.md b/pi/core/skills/laravel-security/SKILL.md index f7b2245e7..f039fdfdd 100644 --- a/pi/core/skills/laravel-security/SKILL.md +++ b/pi/core/skills/laravel-security/SKILL.md @@ -772,15 +772,17 @@ public function rules(): array ### Secure Storage ```php -// Store files outside public directory -$path = $request->file('document')->store('documents', 'local'); -// Never use 'public' disk for sensitive documents +// Store sensitive files on the same private disk used to create temporary URLs. +$path = $request->file('document')->store('documents', 's3'); +// Never use the 'public' disk for sensitive documents. // Use signed URLs for temporary file access use Illuminate\Support\Facades\Storage; public function download(Document $document) { + // Requires route-model binding for Document, a persisted $document->path, + // and a DocumentPolicy::download rule registered with Laravel. // Authorize against the model that owns the file, never a path taken from the request $this->authorize('download', $document); diff --git a/skills/laravel-security/SKILL.md b/skills/laravel-security/SKILL.md index f7b2245e7..f039fdfdd 100644 --- a/skills/laravel-security/SKILL.md +++ b/skills/laravel-security/SKILL.md @@ -772,15 +772,17 @@ public function rules(): array ### Secure Storage ```php -// Store files outside public directory -$path = $request->file('document')->store('documents', 'local'); -// Never use 'public' disk for sensitive documents +// Store sensitive files on the same private disk used to create temporary URLs. +$path = $request->file('document')->store('documents', 's3'); +// Never use the 'public' disk for sensitive documents. // Use signed URLs for temporary file access use Illuminate\Support\Facades\Storage; public function download(Document $document) { + // Requires route-model binding for Document, a persisted $document->path, + // and a DocumentPolicy::download rule registered with Laravel. // Authorize against the model that owns the file, never a path taken from the request $this->authorize('download', $document); diff --git a/tests/scripts/npm-publish-surface.test.js b/tests/scripts/npm-publish-surface.test.js index ae0179bca..7b81957e0 100644 --- a/tests/scripts/npm-publish-surface.test.js +++ b/tests/scripts/npm-publish-surface.test.js @@ -36,8 +36,9 @@ function isCoveredByAncestor(target, roots) { return false } -// `node scripts/.js`, tolerating an optional "$SKILL_DIR/" style prefix. -const SCRIPT_INVOCATION_RE = /node\s+(?:\$\{?SKILL_DIR\}?\/)?scripts\/([A-Za-z0-9._/-]+\.js)/g +// `node scripts/.js`, tolerating quoted ECC_ROOT or SKILL_DIR prefixes. +const SCRIPT_INVOCATION_RE = + /node\s+["']?(?:\$\{?(?:ECC_ROOT|SKILL_DIR)\}?\/)?scripts\/([A-Za-z0-9._/-]+\.js)["']?/g function collectCommandScriptReferences(repoRoot) { const commandsDir = path.join(repoRoot, "commands") @@ -269,6 +270,7 @@ function main() { "scripts/codex-git-hooks/pre-commit", "scripts/codex-git-hooks/pre-push", "scripts/setup.js", + "scripts/github-coordination.js", "scripts/codex/check-plugin-cache.js", ".gemini/GEMINI.md", ".qwen/QWEN.md",