mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-06-10 10:13:49 +08:00
Compare commits
23 Commits
patch-1
...
pr-2006-sc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
958532920f | ||
|
|
f4ff831890 | ||
|
|
b217bbc3fa | ||
|
|
d6022d6b8d | ||
|
|
ac7434ea8f | ||
|
|
c7d662c3c6 | ||
|
|
8148340ad1 | ||
|
|
e7a7b2aaa3 | ||
|
|
3304848beb | ||
|
|
b62f80750d | ||
|
|
855e8c8336 | ||
|
|
f3cd006252 | ||
|
|
d135e03da0 | ||
|
|
c07276a347 | ||
|
|
7a0645ed47 | ||
|
|
e209afc8c1 | ||
|
|
8141f6904f | ||
|
|
af9b2c1c4c | ||
|
|
9ee1e15564 | ||
|
|
2199b22351 | ||
|
|
b66fa78fe8 | ||
|
|
673dff977f | ||
|
|
6cb194a3c6 |
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "ecc",
|
"name": "ecc",
|
||||||
"interface": {
|
"interface": {
|
||||||
"displayName": "Everything Claude Code"
|
"displayName": "ECC"
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,20 +5,20 @@
|
|||||||
"email": "me@affaanmustafa.com"
|
"email": "me@affaanmustafa.com"
|
||||||
},
|
},
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"description": "Battle-tested Claude Code configurations from an Anthropic hackathon winner"
|
"description": "Harness-native ECC skills, hooks, rules, MCP conventions, and operator workflows"
|
||||||
},
|
},
|
||||||
"plugins": [
|
"plugins": [
|
||||||
{
|
{
|
||||||
"name": "ecc",
|
"name": "ecc",
|
||||||
"source": "./",
|
"source": "./",
|
||||||
"description": "The most comprehensive Claude Code plugin — 60 agents, 232 skills, 75 legacy command shims, selective install profiles, and production-ready hooks for TDD, security scanning, code review, and continuous learning",
|
"description": "Harness-native ECC operator layer - 60 agents, 232 skills, 75 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",
|
"version": "2.0.0-rc.1",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Affaan Mustafa",
|
"name": "Affaan Mustafa",
|
||||||
"email": "me@affaanmustafa.com"
|
"email": "me@affaanmustafa.com"
|
||||||
},
|
},
|
||||||
"homepage": "https://ecc.tools",
|
"homepage": "https://ecc.tools",
|
||||||
"repository": "https://github.com/affaan-m/everything-claude-code",
|
"repository": "https://github.com/affaan-m/ECC",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"agents",
|
"agents",
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"name": "ecc",
|
"name": "ecc",
|
||||||
"version": "2.0.0-rc.1",
|
"version": "2.0.0-rc.1",
|
||||||
"description": "Battle-tested Claude Code plugin for engineering teams — 60 agents, 232 skills, 75 legacy command shims, production-ready hooks, and selective install workflows evolved through continuous real-world use",
|
"description": "Harness-native ECC plugin for engineering teams - 60 agents, 232 skills, 75 legacy command shims, reusable hooks, rules, MCP conventions, and operator workflows for Claude Code plus adjacent agent harnesses",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Affaan Mustafa",
|
"name": "Affaan Mustafa",
|
||||||
"url": "https://x.com/affaanmustafa"
|
"url": "https://x.com/affaanmustafa"
|
||||||
},
|
},
|
||||||
"homepage": "https://ecc.tools",
|
"homepage": "https://ecc.tools",
|
||||||
"repository": "https://github.com/affaan-m/everything-claude-code",
|
"repository": "https://github.com/affaan-m/ECC",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"claude-code",
|
"claude-code",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# .codex-plugin — Codex Native Plugin for ECC
|
# .codex-plugin — Codex Native Plugin for ECC
|
||||||
|
|
||||||
This directory contains the **Codex plugin manifest** for Everything Claude Code.
|
This directory contains the **Codex plugin manifest** for ECC.
|
||||||
|
|
||||||
## Structure
|
## Structure
|
||||||
|
|
||||||
@@ -24,10 +24,10 @@ track that marketplace source from the CLI:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Add the public repo marketplace
|
# Add the public repo marketplace
|
||||||
codex plugin marketplace add affaan-m/everything-claude-code
|
codex plugin marketplace add affaan-m/ECC
|
||||||
|
|
||||||
# Or add a local checkout while developing
|
# Or add a local checkout while developing
|
||||||
codex plugin marketplace add /absolute/path/to/everything-claude-code
|
codex plugin marketplace add /absolute/path/to/ECC
|
||||||
```
|
```
|
||||||
|
|
||||||
The marketplace entry points at the repository root so `.codex-plugin/plugin.json`,
|
The marketplace entry points at the repository root so `.codex-plugin/plugin.json`,
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
{
|
{
|
||||||
"name": "ecc",
|
"name": "ecc",
|
||||||
"version": "2.0.0-rc.1",
|
"version": "2.0.0-rc.1",
|
||||||
"description": "Battle-tested Codex workflows — 207 shared ECC skills, production-ready MCP configs, and selective-install-aligned conventions for TDD, security scanning, code review, and autonomous development.",
|
"description": "Harness-native ECC workflows for Codex: shared skills, production-ready MCP configs, and selective-install-aligned conventions for TDD, security scanning, code review, and autonomous development.",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Affaan Mustafa",
|
"name": "Affaan Mustafa",
|
||||||
"email": "me@affaanmustafa.com",
|
"email": "me@affaanmustafa.com",
|
||||||
"url": "https://x.com/affaanmustafa"
|
"url": "https://x.com/affaanmustafa"
|
||||||
},
|
},
|
||||||
"homepage": "https://ecc.tools",
|
"homepage": "https://ecc.tools",
|
||||||
"repository": "https://github.com/affaan-m/everything-claude-code",
|
"repository": "https://github.com/affaan-m/ECC",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"keywords": ["codex", "agents", "skills", "tdd", "code-review", "security", "workflow", "automation"],
|
"keywords": ["codex", "agents", "skills", "tdd", "code-review", "security", "workflow", "automation"],
|
||||||
"skills": "./skills/",
|
"skills": "./skills/",
|
||||||
"mcpServers": "./.mcp.json",
|
"mcpServers": "./.mcp.json",
|
||||||
"interface": {
|
"interface": {
|
||||||
"displayName": "Everything Claude Code",
|
"displayName": "ECC",
|
||||||
"shortDescription": "207 battle-tested ECC skills plus MCP configs for TDD, security, code review, and autonomous development.",
|
"shortDescription": "207 battle-tested ECC skills plus MCP configs for TDD, security, code review, and autonomous development.",
|
||||||
"longDescription": "Everything Claude Code (ECC) is a community-maintained collection of Codex-ready skills and MCP configs evolved over 10+ months of intensive daily use. It covers TDD workflows, security scanning, code review, architecture decisions, operator workflows, and more — all in one installable plugin.",
|
"longDescription": "ECC is a harness-native operator system for Codex and adjacent agent harnesses. It packages reusable skills, MCP configs, TDD workflows, security scanning, code review, architecture decisions, operator workflows, and release gates in one installable plugin.",
|
||||||
"developerName": "Affaan Mustafa",
|
"developerName": "Affaan Mustafa",
|
||||||
"category": "Productivity",
|
"category": "Productivity",
|
||||||
"capabilities": ["Read", "Write"],
|
"capabilities": ["Read", "Write"],
|
||||||
|
|||||||
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
* @affaan-m
|
||||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -96,7 +96,7 @@ jobs:
|
|||||||
|
|
||||||
### Notes
|
### Notes
|
||||||
- npm package: \`ecc-universal\`
|
- npm package: \`ecc-universal\`
|
||||||
- Claude marketplace/plugin identifier: \`everything-claude-code@everything-claude-code\`
|
- Claude marketplace/plugin identifier: \`ecc@ecc\`
|
||||||
- For migration tips and compatibility notes, see README and CHANGELOG.
|
- For migration tips and compatibility notes, see README and CHANGELOG.
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/reusable-release.yml
vendored
2
.github/workflows/reusable-release.yml
vendored
@@ -114,7 +114,7 @@ jobs:
|
|||||||
|
|
||||||
### Package Notes
|
### Package Notes
|
||||||
- npm package: \`ecc-universal\`
|
- npm package: \`ecc-universal\`
|
||||||
- Claude marketplace/plugin identifier: \`everything-claude-code@everything-claude-code\`
|
- Claude marketplace/plugin identifier: \`ecc@ecc\`
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
- name: Pack npm artifact
|
- name: Pack npm artifact
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Migration Guide: Claude Code to OpenCode
|
# Migration Guide: Claude Code to OpenCode
|
||||||
|
|
||||||
This guide helps you migrate from Claude Code to OpenCode while using the Everything Claude Code (ECC) configuration.
|
This guide helps you migrate from Claude Code to OpenCode while using the ECC configuration.
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
@@ -365,4 +365,4 @@ If you need to switch back:
|
|||||||
|
|
||||||
For issues specific to:
|
For issues specific to:
|
||||||
- **OpenCode CLI**: Report to OpenCode's issue tracker
|
- **OpenCode CLI**: Report to OpenCode's issue tracker
|
||||||
- **ECC Configuration**: Report to [github.com/affaan-m/everything-claude-code](https://github.com/affaan-m/everything-claude-code)
|
- **ECC Configuration**: Report to [github.com/affaan-m/ECC](https://github.com/affaan-m/ECC)
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
> WARNING: This README is specific to OpenCode usage.
|
> WARNING: This README is specific to OpenCode usage.
|
||||||
> If you installed ECC via npm (e.g. `npm install opencode-ecc`), refer to the root README instead.
|
> If you installed ECC via npm (e.g. `npm install opencode-ecc`), refer to the root README instead.
|
||||||
|
|
||||||
Everything Claude Code (ECC) plugin for OpenCode - agents, commands, hooks, and skills.
|
ECC plugin for OpenCode - agents, commands, hooks, and skills.
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
## Installation Overview
|
## Installation Overview
|
||||||
|
|
||||||
There are two ways to use Everything Claude Code (ECC):
|
There are two ways to use ECC:
|
||||||
|
|
||||||
1. **npm package (recommended for most users)**
|
1. **npm package (recommended for most users)**
|
||||||
Install via npm/bun/yarn and use the `ecc-install` CLI to set up rules and agents.
|
Install via npm/bun/yarn and use the `ecc-install` CLI to set up rules and agents.
|
||||||
@@ -52,8 +52,8 @@ npx ecc-install typescript
|
|||||||
Clone and run OpenCode in the repository:
|
Clone and run OpenCode in the repository:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/affaan-m/everything-claude-code
|
git clone https://github.com/affaan-m/ECC
|
||||||
cd everything-claude-code
|
cd ECC
|
||||||
opencode
|
opencode
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ node scripts/harness-audit.js <scope> --format <text|json> [--root <path>]
|
|||||||
|
|
||||||
This script is the source of truth for scoring and checks. Do not invent additional dimensions or ad-hoc points.
|
This script is the source of truth for scoring and checks. Do not invent additional dimensions or ad-hoc points.
|
||||||
|
|
||||||
Rubric version: `2026-03-30`.
|
Rubric version: `2026-05-19`.
|
||||||
|
|
||||||
The script computes 7 fixed categories (`0-10` normalized each):
|
The script computes up to 12 fixed categories (`0-10` normalized each). The first seven are always applicable; GitHub Integration is always applicable; deploy-target categories are applicable only when a matching marker is detected.
|
||||||
|
|
||||||
1. Tool Coverage
|
1. Tool Coverage
|
||||||
2. Context Efficiency
|
2. Context Efficiency
|
||||||
@@ -35,6 +35,11 @@ The script computes 7 fixed categories (`0-10` normalized each):
|
|||||||
5. Eval Coverage
|
5. Eval Coverage
|
||||||
6. Security Guardrails
|
6. Security Guardrails
|
||||||
7. Cost Efficiency
|
7. Cost Efficiency
|
||||||
|
8. GitHub Integration
|
||||||
|
9. Vercel Integration *(when `vercel.json` or `.vercel/` is present)*
|
||||||
|
10. Netlify Integration *(when `netlify.toml` or `.netlify/` is present)*
|
||||||
|
11. Cloudflare Integration *(when `wrangler.toml` or `wrangler.jsonc` is present)*
|
||||||
|
12. Fly Integration *(when `fly.toml` is present)*
|
||||||
|
|
||||||
Scores are derived from explicit file/rule checks and are reproducible for the same commit.
|
Scores are derived from explicit file/rule checks and are reproducible for the same commit.
|
||||||
The script audits the current working directory by default and auto-detects whether the target is the ECC repo itself or a consumer project using ECC.
|
The script audits the current working directory by default and auto-detects whether the target is the ECC repo itself or a consumer project using ECC.
|
||||||
@@ -43,11 +48,12 @@ The script audits the current working directory by default and auto-detects whet
|
|||||||
|
|
||||||
Return:
|
Return:
|
||||||
|
|
||||||
1. `overall_score` out of `max_score` (70 for `repo`; smaller for scoped audits)
|
1. `overall_score` out of `max_score`. `max_score` depends on which categories are applicable to the target; never assume a fixed total.
|
||||||
2. Category scores and concrete findings
|
2. `applicable_categories[]` and `category_count` describing which categories contributed.
|
||||||
3. Failed checks with exact file paths
|
3. Category scores and concrete findings.
|
||||||
4. Top 3 actions from the deterministic output (`top_actions`)
|
4. Failed checks with exact file paths.
|
||||||
5. Suggested ECC skills to apply next
|
5. Top 3 actions from the deterministic output (`top_actions`).
|
||||||
|
6. Suggested ECC skills to apply next.
|
||||||
|
|
||||||
## Checklist
|
## Checklist
|
||||||
|
|
||||||
@@ -59,14 +65,15 @@ Return:
|
|||||||
## Example Result
|
## Example Result
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Harness Audit (repo): 66/70
|
Harness Audit (repo, repo): 71/80
|
||||||
- Tool Coverage: 10/10 (10/10 pts)
|
- Tool Coverage: 10/10 (10/10 pts)
|
||||||
- Context Efficiency: 9/10 (9/10 pts)
|
- Context Efficiency: 9/10 (9/10 pts)
|
||||||
- Quality Gates: 10/10 (10/10 pts)
|
- Quality Gates: 10/10 (10/10 pts)
|
||||||
|
- GitHub Integration: 2/10 (2/10 pts)
|
||||||
|
|
||||||
Top 3 Actions:
|
Top 3 Actions:
|
||||||
1) [Security Guardrails] Add prompt/tool preflight security guards in hooks/hooks.json. (hooks/hooks.json)
|
1) [GitHub Integration] Add at least one workflow under .github/workflows/. (.github/workflows/)
|
||||||
2) [Tool Coverage] Sync commands/harness-audit.md and .opencode/commands/harness-audit.md. (.opencode/commands/harness-audit.md)
|
2) [Security Guardrails] Add prompt/tool preflight security guards in hooks/hooks.json. (hooks/hooks.json)
|
||||||
3) [Eval Coverage] Increase automated test coverage across scripts/hooks/lib. (tests/)
|
3) [Eval Coverage] Increase automated test coverage across scripts/hooks/lib. (tests/)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Everything Claude Code (ECC) Plugin for OpenCode
|
* ECC Plugin for OpenCode
|
||||||
*
|
*
|
||||||
* This package provides the published ECC OpenCode plugin module:
|
* This package provides the published ECC OpenCode plugin module:
|
||||||
* - Plugin hooks (auto-format, TypeScript check, console.log warning, env injection, etc.)
|
* - Plugin hooks (auto-format, TypeScript check, console.log warning, env injection, etc.)
|
||||||
@@ -26,8 +26,8 @@
|
|||||||
*
|
*
|
||||||
* Option 2: Clone and use directly
|
* Option 2: Clone and use directly
|
||||||
* ```bash
|
* ```bash
|
||||||
* git clone https://github.com/affaan-m/everything-claude-code
|
* git clone https://github.com/affaan-m/ECC
|
||||||
* cd everything-claude-code
|
* cd ECC
|
||||||
* opencode
|
* opencode
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
@@ -47,7 +47,7 @@ export const VERSION = "1.6.0"
|
|||||||
export const metadata = {
|
export const metadata = {
|
||||||
name: "ecc-universal",
|
name: "ecc-universal",
|
||||||
version: VERSION,
|
version: VERSION,
|
||||||
description: "Everything Claude Code plugin for OpenCode",
|
description: "ECC plugin for OpenCode",
|
||||||
author: "affaan-m",
|
author: "affaan-m",
|
||||||
features: {
|
features: {
|
||||||
agents: 13,
|
agents: 13,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# Everything Claude Code - OpenCode Instructions
|
# ECC - OpenCode Instructions
|
||||||
|
|
||||||
This document consolidates the core rules and guidelines from the Claude Code configuration for use with OpenCode.
|
This document consolidates the core rules and guidelines from the Claude Code configuration for use with OpenCode.
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "ecc-universal",
|
"name": "ecc-universal",
|
||||||
"version": "2.0.0-rc.1",
|
"version": "2.0.0-rc.1",
|
||||||
"description": "Everything Claude Code (ECC) plugin for OpenCode - agents, commands, hooks, and skills",
|
"description": "ECC plugin for OpenCode - agents, commands, hooks, and skills",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@@ -47,12 +47,12 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/affaan-m/everything-claude-code.git"
|
"url": "git+https://github.com/affaan-m/ECC.git"
|
||||||
},
|
},
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/affaan-m/everything-claude-code/issues"
|
"url": "https://github.com/affaan-m/ECC/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/affaan-m/everything-claude-code#readme",
|
"homepage": "https://github.com/affaan-m/ECC#readme",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Everything Claude Code (ECC) Plugin Hooks for OpenCode
|
* ECC Plugin Hooks for OpenCode
|
||||||
*
|
*
|
||||||
* This plugin translates Claude Code hooks to OpenCode's plugin system.
|
* This plugin translates Claude Code hooks to OpenCode's plugin system.
|
||||||
* OpenCode's plugin system is MORE sophisticated than Claude Code with 20+ events
|
* OpenCode's plugin system is MORE sophisticated than Claude Code with 20+ events
|
||||||
@@ -453,7 +453,7 @@ export const ECCHooksPlugin: ECCHooksPluginFn = async ({
|
|||||||
const contextBlock = [
|
const contextBlock = [
|
||||||
"# ECC Context (preserve across compaction)",
|
"# ECC Context (preserve across compaction)",
|
||||||
"",
|
"",
|
||||||
"## Active Plugin: Everything Claude Code v2.0.0-rc.1",
|
"## Active Plugin: ECC v2.0.0-rc.1",
|
||||||
"- Hooks: file.edited, tool.execute.before/after, session.created/idle/deleted, shell.env, compacting, permission.ask",
|
"- Hooks: file.edited, tool.execute.before/after, session.created/idle/deleted, shell.env, compacting, permission.ask",
|
||||||
"- Tools: run-tests, check-coverage, security-audit, format-code, lint-check, git-summary, changed-files",
|
"- Tools: run-tests, check-coverage, security-audit, format-code, lint-check, git-summary, changed-files",
|
||||||
"- Agents: 13 specialized (planner, architect, tdd-guide, code-reviewer, security-reviewer, build-error-resolver, e2e-runner, refactor-cleaner, doc-updater, go-reviewer, go-build-resolver, database-reviewer, python-reviewer)",
|
"- Agents: 13 specialized (planner, architect, tdd-guide, code-reviewer, security-reviewer, build-error-resolver, e2e-runner, refactor-cleaner, doc-updater, go-reviewer, go-build-resolver, database-reviewer, python-reviewer)",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* Everything Claude Code (ECC) Plugins for OpenCode
|
* ECC Plugins for OpenCode
|
||||||
*
|
*
|
||||||
* This module exports all ECC plugins for OpenCode integration.
|
* This module exports all ECC plugins for OpenCode integration.
|
||||||
* Plugins provide hook-based automation that mirrors Claude Code's hook system
|
* Plugins provide hook-based automation that mirrors Claude Code's hook system
|
||||||
|
|||||||
90
README.md
90
README.md
@@ -1,12 +1,12 @@
|
|||||||
**Language:** English | [Português (Brasil)](docs/pt-BR/README.md) | [简体中文](README.zh-CN.md) | [繁體中文](docs/zh-TW/README.md) | [日本語](docs/ja-JP/README.md) | [한국어](docs/ko-KR/README.md) | [Türkçe](docs/tr/README.md) | [Русский](docs/ru/README.md) | [Tiếng Việt](docs/vi-VN/README.md) | [ไทย](docs/th/README.md)
|
**Language:** English | [Português (Brasil)](docs/pt-BR/README.md) | [简体中文](README.zh-CN.md) | [繁體中文](docs/zh-TW/README.md) | [日本語](docs/ja-JP/README.md) | [한국어](docs/ko-KR/README.md) | [Türkçe](docs/tr/README.md) | [Русский](docs/ru/README.md) | [Tiếng Việt](docs/vi-VN/README.md) | [ไทย](docs/th/README.md)
|
||||||
|
|
||||||
# Everything Claude Code
|
# ECC
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
[](https://github.com/affaan-m/everything-claude-code/stargazers)
|
[](https://github.com/affaan-m/ECC/stargazers)
|
||||||
[](https://github.com/affaan-m/everything-claude-code/network/members)
|
[](https://github.com/affaan-m/ECC/network/members)
|
||||||
[](https://github.com/affaan-m/everything-claude-code/graphs/contributors)
|
[](https://github.com/affaan-m/ECC/graphs/contributors)
|
||||||
[](https://www.npmjs.com/package/ecc-universal)
|
[](https://www.npmjs.com/package/ecc-universal)
|
||||||
[](https://www.npmjs.com/package/ecc-agentshield)
|
[](https://www.npmjs.com/package/ecc-agentshield)
|
||||||
[](https://github.com/marketplace/ecc-tools)
|
[](https://github.com/marketplace/ecc-tools)
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**The performance optimization system for AI agent harnesses. From an Anthropic hackathon winner.**
|
**The harness-native operator system for agentic work. From an Anthropic hackathon winner.**
|
||||||
|
|
||||||
Not just configs. A complete system: skills, instincts, memory optimization, continuous learning, security scanning, and research-first development. Production-ready agents, skills, hooks, rules, MCP configurations, and legacy command shims evolved over 10+ months of intensive daily use building real products.
|
Not just configs. A complete system: skills, instincts, memory optimization, continuous learning, security scanning, and research-first development. Production-ready agents, skills, hooks, rules, MCP configurations, and legacy command shims evolved over 10+ months of intensive daily use building real products.
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ ECC v2.0.0-rc.1 adds the public Hermes operator story on top of that reusable la
|
|||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td width="25%" align="center">
|
<td width="25%" align="center">
|
||||||
<a href="https://github.com/affaan-m/everything-claude-code/discussions">
|
<a href="https://github.com/affaan-m/ECC/discussions">
|
||||||
<strong>Community</strong>
|
<strong>Community</strong>
|
||||||
<br />
|
<br />
|
||||||
<sub>Discussions · Q&A · Show & Tell</sub>
|
<sub>Discussions · Q&A · Show & Tell</sub>
|
||||||
@@ -172,7 +172,7 @@ This repo is the raw code only. The guides explain everything.
|
|||||||
|
|
||||||
### v1.4.1 — Bug Fix (Feb 2026)
|
### v1.4.1 — Bug Fix (Feb 2026)
|
||||||
|
|
||||||
- **Fixed instinct import content loss** — `parse_instinct_file()` was silently dropping all content after frontmatter (Action, Evidence, Examples sections) during `/instinct-import`. ([#148](https://github.com/affaan-m/everything-claude-code/issues/148), [#161](https://github.com/affaan-m/everything-claude-code/pull/161))
|
- **Fixed instinct import content loss** — `parse_instinct_file()` was silently dropping all content after frontmatter (Action, Evidence, Examples sections) during `/instinct-import`. ([#148](https://github.com/affaan-m/ECC/issues/148), [#161](https://github.com/affaan-m/ECC/pull/161))
|
||||||
|
|
||||||
### v1.4.0 — Multi-Language Rules, Installation Wizard & PM2 (Feb 2026)
|
### v1.4.0 — Multi-Language Rules, Installation Wizard & PM2 (Feb 2026)
|
||||||
|
|
||||||
@@ -196,7 +196,7 @@ This repo is the raw code only. The guides explain everything.
|
|||||||
- **Session management** — `/sessions` command for session history
|
- **Session management** — `/sessions` command for session history
|
||||||
- **Continuous learning v2** — Instinct-based learning with confidence scoring, import/export, evolution
|
- **Continuous learning v2** — Instinct-based learning with confidence scoring, import/export, evolution
|
||||||
|
|
||||||
See the full changelog in [Releases](https://github.com/affaan-m/everything-claude-code/releases).
|
See the full changelog in [Releases](https://github.com/affaan-m/ECC/releases).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -265,7 +265,7 @@ npx ecc install --profile minimal --target claude --with capability:machine-lear
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Add marketplace
|
# Add marketplace
|
||||||
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
/plugin marketplace add https://github.com/affaan-m/ECC
|
||||||
|
|
||||||
# Install plugin
|
# Install plugin
|
||||||
/plugin install ecc@ecc
|
/plugin install ecc@ecc
|
||||||
@@ -275,7 +275,7 @@ npx ecc install --profile minimal --target claude --with capability:machine-lear
|
|||||||
|
|
||||||
ECC now has three public identifiers, and they are not interchangeable:
|
ECC now has three public identifiers, and they are not interchangeable:
|
||||||
|
|
||||||
- GitHub source repo: `affaan-m/everything-claude-code`
|
- GitHub source repo: `affaan-m/ECC`
|
||||||
- Claude marketplace/plugin identifier: `ecc@ecc`
|
- Claude marketplace/plugin identifier: `ecc@ecc`
|
||||||
- npm package: `ecc-universal`
|
- npm package: `ecc-universal`
|
||||||
|
|
||||||
@@ -295,8 +295,8 @@ This is intentional. Anthropic marketplace/plugin installs are keyed by a canoni
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Clone the repo first
|
# Clone the repo first
|
||||||
git clone https://github.com/affaan-m/everything-claude-code.git
|
git clone https://github.com/affaan-m/ECC.git
|
||||||
cd everything-claude-code
|
cd ECC
|
||||||
|
|
||||||
# Install dependencies (pick your package manager)
|
# Install dependencies (pick your package manager)
|
||||||
npm install # or: pnpm install | yarn install | bun install
|
npm install # or: pnpm install | yarn install | bun install
|
||||||
@@ -494,7 +494,7 @@ Windows PowerShell:
|
|||||||
This repo is a **Claude Code plugin** - install it directly or copy components manually.
|
This repo is a **Claude Code plugin** - install it directly or copy components manually.
|
||||||
|
|
||||||
```
|
```
|
||||||
everything-claude-code/
|
ECC/
|
||||||
|-- .claude-plugin/ # Plugin and marketplace manifests
|
|-- .claude-plugin/ # Plugin and marketplace manifests
|
||||||
| |-- plugin.json # Plugin metadata and component paths
|
| |-- plugin.json # Plugin metadata and component paths
|
||||||
| |-- marketplace.json # Marketplace catalog for /plugin marketplace add
|
| |-- marketplace.json # Marketplace catalog for /plugin marketplace add
|
||||||
@@ -812,7 +812,7 @@ Claude Code v2.1+ **automatically loads** `hooks/hooks.json` from any installed
|
|||||||
Duplicate hooks file detected: ./hooks/hooks.json resolves to already-loaded file
|
Duplicate hooks file detected: ./hooks/hooks.json resolves to already-loaded file
|
||||||
```
|
```
|
||||||
|
|
||||||
**History:** This has caused repeated fix/revert cycles in this repo ([#29](https://github.com/affaan-m/everything-claude-code/issues/29), [#52](https://github.com/affaan-m/everything-claude-code/issues/52), [#103](https://github.com/affaan-m/everything-claude-code/issues/103)). The behavior changed between Claude Code versions, leading to confusion. We now have a regression test to prevent this from being reintroduced.
|
**History:** This has caused repeated fix/revert cycles in this repo ([#29](https://github.com/affaan-m/ECC/issues/29), [#52](https://github.com/affaan-m/ECC/issues/52), [#103](https://github.com/affaan-m/ECC/issues/103)). The behavior changed between Claude Code versions, leading to confusion. We now have a regression test to prevent this from being reintroduced.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -824,7 +824,7 @@ The easiest way to use this repo - install as a Claude Code plugin:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Add this repo as a marketplace
|
# Add this repo as a marketplace
|
||||||
/plugin marketplace add https://github.com/affaan-m/everything-claude-code
|
/plugin marketplace add https://github.com/affaan-m/ECC
|
||||||
|
|
||||||
# Install the plugin
|
# Install the plugin
|
||||||
/plugin install ecc@ecc
|
/plugin install ecc@ecc
|
||||||
@@ -838,7 +838,7 @@ Or add directly to your `~/.claude/settings.json`:
|
|||||||
"ecc": {
|
"ecc": {
|
||||||
"source": {
|
"source": {
|
||||||
"source": "github",
|
"source": "github",
|
||||||
"repo": "affaan-m/everything-claude-code"
|
"repo": "affaan-m/ECC"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -854,20 +854,21 @@ This gives you instant access to all commands, agents, skills, and hooks.
|
|||||||
>
|
>
|
||||||
> ```bash
|
> ```bash
|
||||||
> # Clone the repo first
|
> # Clone the repo first
|
||||||
> git clone https://github.com/affaan-m/everything-claude-code.git
|
> git clone https://github.com/affaan-m/ECC.git
|
||||||
|
> cd ECC
|
||||||
>
|
>
|
||||||
> # Option A: User-level rules (applies to all projects)
|
> # Option A: User-level rules (applies to all projects)
|
||||||
> mkdir -p ~/.claude/rules/ecc
|
> mkdir -p ~/.claude/rules/ecc
|
||||||
> cp -r everything-claude-code/rules/common ~/.claude/rules/ecc/
|
> cp -r rules/common ~/.claude/rules/ecc/
|
||||||
> cp -r everything-claude-code/rules/typescript ~/.claude/rules/ecc/ # pick your stack
|
> cp -r rules/typescript ~/.claude/rules/ecc/ # pick your stack
|
||||||
> cp -r everything-claude-code/rules/python ~/.claude/rules/ecc/
|
> cp -r rules/python ~/.claude/rules/ecc/
|
||||||
> cp -r everything-claude-code/rules/golang ~/.claude/rules/ecc/
|
> cp -r rules/golang ~/.claude/rules/ecc/
|
||||||
> cp -r everything-claude-code/rules/php ~/.claude/rules/ecc/
|
> cp -r rules/php ~/.claude/rules/ecc/
|
||||||
>
|
>
|
||||||
> # Option B: Project-level rules (applies to current project only)
|
> # Option B: Project-level rules (applies to current project only)
|
||||||
> mkdir -p .claude/rules/ecc
|
> mkdir -p .claude/rules/ecc
|
||||||
> cp -r everything-claude-code/rules/common .claude/rules/ecc/
|
> cp -r rules/common .claude/rules/ecc/
|
||||||
> cp -r everything-claude-code/rules/typescript .claude/rules/ecc/ # pick your stack
|
> cp -r rules/typescript .claude/rules/ecc/ # pick your stack
|
||||||
> ```
|
> ```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -878,34 +879,35 @@ If you prefer manual control over what's installed:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Clone the repo
|
# Clone the repo
|
||||||
git clone https://github.com/affaan-m/everything-claude-code.git
|
git clone https://github.com/affaan-m/ECC.git
|
||||||
|
cd ECC
|
||||||
|
|
||||||
# Copy agents to your Claude config
|
# Copy agents to your Claude config
|
||||||
cp everything-claude-code/agents/*.md ~/.claude/agents/
|
cp agents/*.md ~/.claude/agents/
|
||||||
|
|
||||||
# Copy rules directories (common + language-specific)
|
# Copy rules directories (common + language-specific)
|
||||||
mkdir -p ~/.claude/rules/ecc
|
mkdir -p ~/.claude/rules/ecc
|
||||||
cp -r everything-claude-code/rules/common ~/.claude/rules/ecc/
|
cp -r rules/common ~/.claude/rules/ecc/
|
||||||
cp -r everything-claude-code/rules/typescript ~/.claude/rules/ecc/ # pick your stack
|
cp -r rules/typescript ~/.claude/rules/ecc/ # pick your stack
|
||||||
cp -r everything-claude-code/rules/python ~/.claude/rules/ecc/
|
cp -r rules/python ~/.claude/rules/ecc/
|
||||||
cp -r everything-claude-code/rules/golang ~/.claude/rules/ecc/
|
cp -r rules/golang ~/.claude/rules/ecc/
|
||||||
cp -r everything-claude-code/rules/php ~/.claude/rules/ecc/
|
cp -r rules/php ~/.claude/rules/ecc/
|
||||||
cp -r everything-claude-code/rules/arkts ~/.claude/rules/ecc/
|
cp -r rules/arkts ~/.claude/rules/ecc/
|
||||||
|
|
||||||
# Copy skills first (primary workflow surface)
|
# Copy skills first (primary workflow surface)
|
||||||
# Recommended (new users): core/general skills only
|
# Recommended (new users): core/general skills only
|
||||||
mkdir -p ~/.claude/skills/ecc
|
mkdir -p ~/.claude/skills/ecc
|
||||||
cp -r everything-claude-code/.agents/skills/* ~/.claude/skills/ecc/
|
cp -r .agents/skills/* ~/.claude/skills/ecc/
|
||||||
cp -r everything-claude-code/skills/search-first ~/.claude/skills/ecc/
|
cp -r skills/search-first ~/.claude/skills/ecc/
|
||||||
|
|
||||||
# Optional: add niche/framework-specific skills only when needed
|
# Optional: add niche/framework-specific skills only when needed
|
||||||
# for s in django-patterns django-tdd laravel-patterns springboot-patterns quarkus-patterns; do
|
# for s in django-patterns django-tdd laravel-patterns springboot-patterns quarkus-patterns; do
|
||||||
# cp -r everything-claude-code/skills/$s ~/.claude/skills/ecc/
|
# cp -r skills/$s ~/.claude/skills/ecc/
|
||||||
# done
|
# done
|
||||||
|
|
||||||
# Optional: keep maintained slash-command compatibility during migration
|
# Optional: keep maintained slash-command compatibility during migration
|
||||||
mkdir -p ~/.claude/commands
|
mkdir -p ~/.claude/commands
|
||||||
cp everything-claude-code/commands/*.md ~/.claude/commands/
|
cp commands/*.md ~/.claude/commands/
|
||||||
|
|
||||||
# Retired shims live in legacy-command-shims/commands/.
|
# Retired shims live in legacy-command-shims/commands/.
|
||||||
# Copy individual files from there only if you still need old names such as /tdd.
|
# Copy individual files from there only if you still need old names such as /tdd.
|
||||||
@@ -1083,7 +1085,7 @@ This shows all available agents, commands, and skills from the plugin.
|
|||||||
<details>
|
<details>
|
||||||
<summary><b>My hooks aren't working / I see "Duplicate hooks file" errors</b></summary>
|
<summary><b>My hooks aren't working / I see "Duplicate hooks file" errors</b></summary>
|
||||||
|
|
||||||
This is the most common issue. **Do NOT add a `"hooks"` field to `.claude-plugin/plugin.json`.** Claude Code v2.1+ automatically loads `hooks/hooks.json` from installed plugins. Explicitly declaring it causes duplicate detection errors. See [#29](https://github.com/affaan-m/everything-claude-code/issues/29), [#52](https://github.com/affaan-m/everything-claude-code/issues/52), [#103](https://github.com/affaan-m/everything-claude-code/issues/103).
|
This is the most common issue. **Do NOT add a `"hooks"` field to `.claude-plugin/plugin.json`.** Claude Code v2.1+ automatically loads `hooks/hooks.json` from installed plugins. Explicitly declaring it causes duplicate detection errors. See [#29](https://github.com/affaan-m/ECC/issues/29), [#52](https://github.com/affaan-m/ECC/issues/52), [#103](https://github.com/affaan-m/ECC/issues/103).
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
@@ -1128,11 +1130,11 @@ Yes. Use Option 2 (manual installation) and copy only what you need:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Just agents
|
# Just agents
|
||||||
cp everything-claude-code/agents/*.md ~/.claude/agents/
|
cp agents/*.md ~/.claude/agents/
|
||||||
|
|
||||||
# Just rules
|
# Just rules
|
||||||
mkdir -p ~/.claude/rules/ecc/
|
mkdir -p ~/.claude/rules/ecc/
|
||||||
cp -r everything-claude-code/rules/common ~/.claude/rules/ecc/
|
cp -r rules/common ~/.claude/rules/ecc/
|
||||||
```
|
```
|
||||||
|
|
||||||
Each component is fully independent.
|
Each component is fully independent.
|
||||||
@@ -1145,7 +1147,7 @@ Yes. ECC is cross-platform:
|
|||||||
- **Cursor**: Pre-translated configs in `.cursor/`. See [Cursor IDE Support](#cursor-ide-support).
|
- **Cursor**: Pre-translated configs in `.cursor/`. See [Cursor IDE Support](#cursor-ide-support).
|
||||||
- **Gemini CLI**: Experimental project-local support via `.gemini/GEMINI.md` and shared installer plumbing.
|
- **Gemini CLI**: Experimental project-local support via `.gemini/GEMINI.md` and shared installer plumbing.
|
||||||
- **OpenCode**: Full plugin support in `.opencode/`. See [OpenCode Support](#opencode-support).
|
- **OpenCode**: Full plugin support in `.opencode/`. See [OpenCode Support](#opencode-support).
|
||||||
- **Codex**: First-class support for both macOS app and CLI, with adapter drift guards and SessionStart fallback. See PR [#257](https://github.com/affaan-m/everything-claude-code/pull/257).
|
- **Codex**: First-class support for both macOS app and CLI, with adapter drift guards and SessionStart fallback. See PR [#257](https://github.com/affaan-m/ECC/pull/257).
|
||||||
- **GitHub Copilot (VS Code)**: Instruction and prompt layer via `.github/copilot-instructions.md`, `.vscode/settings.json`, and `.github/prompts/`. See [GitHub Copilot Support](#github-copilot-support).
|
- **GitHub Copilot (VS Code)**: Instruction and prompt layer via `.github/copilot-instructions.md`, `.vscode/settings.json`, and `.github/prompts/`. See [GitHub Copilot Support](#github-copilot-support).
|
||||||
- **Antigravity**: Tightly integrated setup for workflows, skills, and flattened rules in `.agent/`. See [Antigravity Guide](docs/ANTIGRAVITY-GUIDE.md).
|
- **Antigravity**: Tightly integrated setup for workflows, skills, and flattened rules in `.agent/`. See [Antigravity Guide](docs/ANTIGRAVITY-GUIDE.md).
|
||||||
- **JoyCode / CodeBuddy**: Project-local selective install adapters for commands, agents, skills, and flattened rules. See [JoyCode Adapter Guide](docs/JOYCODE-GUIDE.md).
|
- **JoyCode / CodeBuddy**: Project-local selective install adapters for commands, agents, skills, and flattened rules. See [JoyCode Adapter Guide](docs/JOYCODE-GUIDE.md).
|
||||||
@@ -1488,7 +1490,7 @@ OpenCode's plugin system is MORE sophisticated than Claude Code with 20+ event t
|
|||||||
|
|
||||||
**Option 1: Use directly**
|
**Option 1: Use directly**
|
||||||
```bash
|
```bash
|
||||||
cd everything-claude-code
|
cd ECC
|
||||||
opencode
|
opencode
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -1717,7 +1719,7 @@ These configs work for my workflow. You should:
|
|||||||
|
|
||||||
## Community Projects
|
## Community Projects
|
||||||
|
|
||||||
Projects built on or inspired by Everything Claude Code:
|
Projects built on or inspired by ECC:
|
||||||
|
|
||||||
| Project | Description |
|
| Project | Description |
|
||||||
|---------|-------------|
|
|---------|-------------|
|
||||||
@@ -1738,7 +1740,7 @@ This project is free and open source. Sponsors help keep it maintained and growi
|
|||||||
|
|
||||||
## Star History
|
## Star History
|
||||||
|
|
||||||
[](https://star-history.com/#affaan-m/everything-claude-code&Date)
|
[](https://star-history.com/#affaan-m/ECC&Date)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
spec_version: "0.1.0"
|
spec_version: "0.1.0"
|
||||||
name: everything-claude-code
|
name: ecc
|
||||||
version: 2.0.0-rc.1
|
version: 2.0.0-rc.1
|
||||||
description: "Initial gitagent export surface for ECC's shared skill catalog, governance, and identity. Native agents, commands, and hooks remain authoritative in the repository while manifest coverage expands."
|
description: "Initial gitagent export surface for ECC's shared skill catalog, governance, and identity. Native agents, commands, and hooks remain authoritative in the repository while manifest coverage expands."
|
||||||
author: affaan-m
|
author: affaan-m
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ node scripts/harness-audit.js <scope> --format <text|json> [--root <path>]
|
|||||||
|
|
||||||
This script is the source of truth for scoring and checks. Do not invent additional dimensions or ad-hoc points.
|
This script is the source of truth for scoring and checks. Do not invent additional dimensions or ad-hoc points.
|
||||||
|
|
||||||
Rubric version: `2026-03-30`.
|
Rubric version: `2026-05-19`.
|
||||||
|
|
||||||
The script computes 7 fixed categories (`0-10` normalized each):
|
The script computes up to 12 fixed categories (`0-10` normalized each). The first seven are always applicable; GitHub Integration is always applicable; deploy-target categories are applicable only when a matching marker is detected.
|
||||||
|
|
||||||
1. Tool Coverage
|
1. Tool Coverage
|
||||||
2. Context Efficiency
|
2. Context Efficiency
|
||||||
@@ -35,6 +35,11 @@ The script computes 7 fixed categories (`0-10` normalized each):
|
|||||||
5. Eval Coverage
|
5. Eval Coverage
|
||||||
6. Security Guardrails
|
6. Security Guardrails
|
||||||
7. Cost Efficiency
|
7. Cost Efficiency
|
||||||
|
8. GitHub Integration
|
||||||
|
9. Vercel Integration *(when `vercel.json` or `.vercel/` is present)*
|
||||||
|
10. Netlify Integration *(when `netlify.toml` or `.netlify/` is present)*
|
||||||
|
11. Cloudflare Integration *(when `wrangler.toml` or `wrangler.jsonc` is present)*
|
||||||
|
12. Fly Integration *(when `fly.toml` is present)*
|
||||||
|
|
||||||
Scores are derived from explicit file/rule checks and are reproducible for the same commit.
|
Scores are derived from explicit file/rule checks and are reproducible for the same commit.
|
||||||
The script audits the current working directory by default and auto-detects whether the target is the ECC repo itself or a consumer project using ECC.
|
The script audits the current working directory by default and auto-detects whether the target is the ECC repo itself or a consumer project using ECC.
|
||||||
@@ -43,11 +48,12 @@ The script audits the current working directory by default and auto-detects whet
|
|||||||
|
|
||||||
Return:
|
Return:
|
||||||
|
|
||||||
1. `overall_score` out of `max_score` (70 for `repo`; smaller for scoped audits)
|
1. `overall_score` out of `max_score`. `max_score` depends on which categories are applicable to the target; never assume a fixed total.
|
||||||
2. Category scores and concrete findings
|
2. `applicable_categories[]` and `category_count` describing which categories contributed.
|
||||||
3. Failed checks with exact file paths
|
3. Category scores and concrete findings.
|
||||||
4. Top 3 actions from the deterministic output (`top_actions`)
|
4. Failed checks with exact file paths.
|
||||||
5. Suggested ECC skills to apply next
|
5. Top 3 actions from the deterministic output (`top_actions`).
|
||||||
|
6. Suggested ECC skills to apply next.
|
||||||
|
|
||||||
## Checklist
|
## Checklist
|
||||||
|
|
||||||
@@ -59,14 +65,15 @@ Return:
|
|||||||
## Example Result
|
## Example Result
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Harness Audit (repo): 66/70
|
Harness Audit (repo, repo): 71/80
|
||||||
- Tool Coverage: 10/10 (10/10 pts)
|
- Tool Coverage: 10/10 (10/10 pts)
|
||||||
- Context Efficiency: 9/10 (9/10 pts)
|
- Context Efficiency: 9/10 (9/10 pts)
|
||||||
- Quality Gates: 10/10 (10/10 pts)
|
- Quality Gates: 10/10 (10/10 pts)
|
||||||
|
- GitHub Integration: 2/10 (2/10 pts)
|
||||||
|
|
||||||
Top 3 Actions:
|
Top 3 Actions:
|
||||||
1) [Security Guardrails] Add prompt/tool preflight security guards in hooks/hooks.json. (hooks/hooks.json)
|
1) [GitHub Integration] Add at least one workflow under .github/workflows/. (.github/workflows/)
|
||||||
2) [Tool Coverage] Sync commands/harness-audit.md and .opencode/commands/harness-audit.md. (.opencode/commands/harness-audit.md)
|
2) [Security Guardrails] Add prompt/tool preflight security guards in hooks/hooks.json. (hooks/hooks.json)
|
||||||
3) [Eval Coverage] Increase automated test coverage across scripts/hooks/lib. (tests/)
|
3) [Eval Coverage] Increase automated test coverage across scripts/hooks/lib. (tests/)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,29 @@ execution truth is split across:
|
|||||||
- merged PR evidence;
|
- merged PR evidence;
|
||||||
- handoffs under `~/.cluster-swarm/handoffs/`.
|
- handoffs under `~/.cluster-swarm/handoffs/`.
|
||||||
|
|
||||||
|
The May 19 release/growth execution map lives at
|
||||||
|
[`docs/releases/2.0.0/ecc-2-hypergrowth-release-command-center.md`](releases/2.0.0/ecc-2-hypergrowth-release-command-center.md).
|
||||||
|
It is the operator surface for the final ECC 2.0 repo identity, video suite,
|
||||||
|
partner/sponsor funnel, consulting/talk funnel, and social launch plan.
|
||||||
|
|
||||||
|
## 2026-05-19 Delta
|
||||||
|
|
||||||
|
- The public repo identity is now `affaan-m/ECC`; release, package, plugin,
|
||||||
|
workflow, and launch-copy surfaces should use that URL for current public
|
||||||
|
links.
|
||||||
|
- The ECC 2.0 release story should lead with the product shape directly:
|
||||||
|
harness-native operator system, reusable skills/rules/hooks/MCP conventions,
|
||||||
|
`ecc2/` alpha control plane, Hermes as optional operator shell, and ECC Tools
|
||||||
|
Pro/Sponsors/consulting as the business surface.
|
||||||
|
- Copy should avoid presenting this as a repo rename or config-pack migration.
|
||||||
|
The release proof should show the system through install flow, cross-harness
|
||||||
|
demos, security evidence, hosted product evidence, and the video suite.
|
||||||
|
|
||||||
## Current Evidence
|
## Current Evidence
|
||||||
|
|
||||||
As of 2026-05-18:
|
As of 2026-05-19:
|
||||||
|
|
||||||
- GitHub queues are clean across `affaan-m/everything-claude-code`,
|
- GitHub queues are clean across `affaan-m/ECC`,
|
||||||
`affaan-m/agentshield`, `affaan-m/JARVIS`, `ECC-Tools/ECC-Tools`, and
|
`affaan-m/agentshield`, `affaan-m/JARVIS`, `ECC-Tools/ECC-Tools`, and
|
||||||
`ECC-Tools/ECC-website`: the latest `platform-audit` sweep found 0 open PRs,
|
`ECC-Tools/ECC-website`: the latest `platform-audit` sweep found 0 open PRs,
|
||||||
0 open issues, 0 discussion maintainer-touch gaps, 0 answerable Q&A missing
|
0 open issues, 0 discussion maintainer-touch gaps, 0 answerable Q&A missing
|
||||||
@@ -33,8 +51,9 @@ As of 2026-05-18:
|
|||||||
now at 0 open PRs and 0 open issues by live `gh search`. Archived repos
|
now at 0 open PRs and 0 open issues by live `gh search`. Archived repos
|
||||||
touched during closure were restored to archived state.
|
touched during closure were restored to archived state.
|
||||||
- GitHub discussions are current across those tracked repos:
|
- GitHub discussions are current across those tracked repos:
|
||||||
`affaan-m/everything-claude-code` has 58 total discussions and 0 without
|
`affaan-m/ECC` has 59 total discussions and 0 without
|
||||||
maintainer touch after May 15 maintainer updates on #73 and #1239; AgentShield,
|
maintainer touch after the May 19 #2003 AURA integration proposal was routed
|
||||||
|
as an external-adapter proposal, not core wallet/escrow coupling; AgentShield,
|
||||||
JARVIS, ECC Tools, and the ECC Tools website have discussions disabled or 0
|
JARVIS, ECC Tools, and the ECC Tools website have discussions disabled or 0
|
||||||
total discussions. `docs/architecture/discussion-response-playbook.md` now
|
total discussions. `docs/architecture/discussion-response-playbook.md` now
|
||||||
supplies the ITO-59 response categories, public templates, security-escalation
|
supplies the ITO-59 response categories, public templates, security-escalation
|
||||||
@@ -43,12 +62,17 @@ As of 2026-05-18:
|
|||||||
`ITO-59`) and five milestones: Security and Access Baseline, ECC 2.0 Preview
|
`ITO-59`) and five milestones: Security and Access Baseline, ECC 2.0 Preview
|
||||||
and Publication, AgentShield Enterprise Iteration, ECC Tools Next-Level
|
and Publication, AgentShield Enterprise Iteration, ECC Tools Next-Level
|
||||||
Platform, and Legacy Audit and Salvage.
|
Platform, and Legacy Audit and Salvage.
|
||||||
- Linear live sync is current for the May 18 merge and supply-chain batch:
|
- Linear live sync is current for the May 19 PR #2002 merge and discussion
|
||||||
ITO-57 has a final emergency supply-chain refresh comment
|
batch: the ECC platform project has the post-PR #2002 sync document
|
||||||
(`3fe5b2b7-c4fe-401c-a317-b40d72119cb3`), and the ECC platform project has
|
`ecc-may-19-post-pr-2002-sync-64cef8f668e0`, project comment
|
||||||
the latest operator progress comment (`e32e5b7a-287b-4bf4-9ed7-314389a157e1`).
|
`a6411e3a-8c8e-4a58-adba-687e77d4c543`, and issue comments on ITO-44,
|
||||||
Linear project status updates are disabled in this workspace, so the project
|
ITO-47, ITO-48, ITO-49, ITO-51, ITO-54, and ITO-56. ITO-47, ITO-48,
|
||||||
comment is the supported external status surface.
|
ITO-49, ITO-51, ITO-54, and ITO-56 were moved to In Progress because those
|
||||||
|
lanes now have current implementation/evidence and remaining gate/readback
|
||||||
|
work. ITO-57 still has the May 18 emergency supply-chain refresh comment
|
||||||
|
(`3fe5b2b7-c4fe-401c-a317-b40d72119cb3`). Linear project status updates are
|
||||||
|
disabled in this workspace, so project documents and comments are the
|
||||||
|
supported external status surface.
|
||||||
- The latest May 18 merge batch on `main` includes PR #1970 workflow-security
|
- The latest May 18 merge batch on `main` includes PR #1970 workflow-security
|
||||||
validator bypass fixes, PR #1971 metrics bridge cost-reporting and warning
|
validator bypass fixes, PR #1971 metrics bridge cost-reporting and warning
|
||||||
de-dup fixes, PR #1972 `uncloud` skill activation structure, PR #1976
|
de-dup fixes, PR #1972 `uncloud` skill activation structure, PR #1976
|
||||||
@@ -57,20 +81,24 @@ As of 2026-05-18:
|
|||||||
recheck, `7911af4a` release OIDC publishing-scope hardening, `97567a91`
|
recheck, `7911af4a` release OIDC publishing-scope hardening, `97567a91`
|
||||||
release workflow line-ending normalization, and release evidence with a
|
release workflow line-ending normalization, and release evidence with a
|
||||||
refreshed operator dashboard.
|
refreshed operator dashboard.
|
||||||
- `docs/releases/2.0.0-rc.1/publication-evidence-2026-05-18.md` records the
|
- `docs/releases/2.0.0-rc.1/publication-evidence-2026-05-19.md` records the
|
||||||
May 18 queue-zero state, current-head TanStack/Mini Shai-Hulud protection
|
current May 19 queue-zero state, canonical ECC identity merge, release video
|
||||||
recheck, no-lifecycle npm install, npm audit/signature checks, AgentShield
|
suite gate, partner/sponsor/talk outreach pack, owner approval packet
|
||||||
project `.claude` scan, Linear sync, work-items sync, operator dashboard
|
(`owner-approval-packet-2026-05-19.md`), preview-pack smoke digest
|
||||||
refresh, PR #1976 provider-guard validation, ECC-Tools Wrangler OAuth billing
|
`790430aef4a8`, local 2550-test suite, PR #2001 merge and GitHub Actions run
|
||||||
readback evidence, defensive-deny IOC scanner coverage, and current-head CI
|
`26102500291` success, PR #2002's owner-approval dashboard gate refresh and
|
||||||
success for `97567a91`; a detached clean-worktree preview-pack smoke from
|
GitHub Actions run `26103853507`, plus PR #2004's Linear readiness evidence
|
||||||
`680aeff0` passed 5/5 with digest `0ed831dbd0cf`.
|
sync and GitHub Actions run `26105012698`. The May 19 Linear sync document
|
||||||
- `docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-18.md`
|
remains the current external project status surface, and the May 18 evidence
|
||||||
|
remains the detailed supply-chain and publication-path snapshot.
|
||||||
|
- `docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-19.md`
|
||||||
regenerates the ITO-44 prompt-to-artifact dashboard from live platform audit
|
regenerates the ITO-44 prompt-to-artifact dashboard from live platform audit
|
||||||
evidence: PR queue, issue queue, discussion queue, local worktree gate,
|
evidence: PR queue, issue queue, discussion queue, local worktree gate,
|
||||||
dashboard generation, and supply-chain loop are current; publication, plugin,
|
dashboard generation, and supply-chain loop are current; the dashboard now
|
||||||
billing, AgentShield, ECC Tools, legacy, and Linear/productized sync lanes
|
also tracks the `$1,728/mo` to `$10,000/mo` hypergrowth baseline, release
|
||||||
remain the next work.
|
video-suite lane, partner/sponsor/talk outbound pack, and owner approval
|
||||||
|
packet; publication, plugin, billing, AgentShield, ECC Tools, and final
|
||||||
|
outbound approval remain the next work.
|
||||||
- `docs/releases/2.0.0-rc.1/publication-evidence-2026-05-17.md` records the
|
- `docs/releases/2.0.0-rc.1/publication-evidence-2026-05-17.md` records the
|
||||||
May 17 queue-zero state, Japanese localization merge, Dependabot TypeScript
|
May 17 queue-zero state, Japanese localization merge, Dependabot TypeScript
|
||||||
and Node type merges, post-merge ja-JP lint repair, Mini Shai-Hulud/TanStack
|
and Node type merges, post-merge ja-JP lint repair, Mini Shai-Hulud/TanStack
|
||||||
@@ -715,21 +743,21 @@ is not complete unless the evidence column exists and has been freshly verified.
|
|||||||
|
|
||||||
| Prompt requirement | Required artifact or gate | Current evidence | Status |
|
| Prompt requirement | Required artifact or gate | Current evidence | Status |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| Keep public PRs below 20 | Repo-family PR recheck | 0 open PRs across `everything-claude-code`, AgentShield, JARVIS, `ECC-Tools/ECC-Tools`, and `ECC-Tools/ECC-website` on 2026-05-18 after merging PR #1976 and refreshing platform audit evidence | Complete |
|
| Keep public PRs below 20 | Repo-family PR recheck | 0 open PRs across `ECC`, AgentShield, JARVIS, `ECC-Tools/ECC-Tools`, and `ECC-Tools/ECC-website` on 2026-05-19 after merging PR #2004 and refreshing platform audit evidence | Complete |
|
||||||
| Keep public issues below 20 | Repo-family issue recheck | 0 open issues across `everything-claude-code`, AgentShield, JARVIS, `ECC-Tools/ECC-Tools`, and `ECC-Tools/ECC-website` on 2026-05-18 after the live platform audit refresh | Complete |
|
| Keep public issues below 20 | Repo-family issue recheck | 0 open issues across `ECC`, AgentShield, JARVIS, `ECC-Tools/ECC-Tools`, and `ECC-Tools/ECC-website` on 2026-05-19 after the live platform audit refresh | Complete |
|
||||||
| Manage repository discussions | Repo-family discussion recheck plus response playbook | Platform audit reports 0 discussion maintainer-touch gaps and 0 answerable Q&A missing accepted answers; trunk still has 58 total discussions; `docs/architecture/discussion-response-playbook.md` distinguishes support, maintainer coordination, stale/concluded, release, informational, and security-sensitive response paths | Complete |
|
| Manage repository discussions | Repo-family discussion recheck plus response playbook | Platform audit reports 0 discussion maintainer-touch gaps and 0 answerable Q&A missing accepted answers; trunk has 59 total discussions after #2003 was routed with a maintainer response; `docs/architecture/discussion-response-playbook.md` distinguishes support, maintainer coordination, stale/concluded, release, informational, and security-sensitive response paths | Complete |
|
||||||
| Manage PR discussions | PR review/comment closure plus merge/close state | ECC #1976 merged after maintainer follow-up validation; no open tracked PRs remain | Complete |
|
| Manage PR discussions | PR review/comment closure plus merge/close state | ECC #1990-#2004 merged through the harness audit, canonical identity, release video suite, growth outreach, evidence refresh, visual QA, suite-count, owner-approval packet, owner-approval dashboard gate, and Linear readiness evidence batch; no open tracked PRs remain | Complete |
|
||||||
| Salvage useful stale work | `docs/stale-pr-salvage-ledger.md` plus `docs/legacy-artifact-inventory.md` | Ledger records salvaged, superseded, skipped, and manual-review tails; #1815-#1818 added cost tracking, skill scout, frontend design guidance, code-reviewer false-positive guardrails, and the May 12 gap pass; #1687, #1609, #1563, #1564, and #1565 localization tails are attached to Linear ITO-55 for language-owner review and no automatic import remains release-blocking | Complete; repeat legacy scan before release |
|
| Salvage useful stale work | `docs/stale-pr-salvage-ledger.md` plus `docs/legacy-artifact-inventory.md` | Ledger records salvaged, superseded, skipped, and manual-review tails; #1815-#1818 added cost tracking, skill scout, frontend design guidance, code-reviewer false-positive guardrails, and the May 12 gap pass; #1687, #1609, #1563, #1564, and #1565 localization tails are attached to Linear ITO-55 for language-owner review and no automatic import remains release-blocking | Complete; repeat legacy scan before release |
|
||||||
| ECC 2.0 preview pack ready | Release docs, quickstart, publication readiness, release notes | `docs/releases/2.0.0-rc.1/` and readiness docs are in-tree; May 18 evidence records queue-zero state, #1970/#1971/#1972/#1976 merge batch, supply-chain recheck, defensive-deny IOC scanner hardening, npm no-lifecycle install/audit/signature gates, Linear sync, refreshed operator dashboard, provider-guard validation, ECC-Tools Wrangler OAuth billing readback evidence, successful current-head CI on `04d4d819`, and detached clean-worktree preview-pack smoke digest `59bbf2630a44` | Needs final release approval |
|
| ECC 2.0 preview pack ready | Release docs, quickstart, publication readiness, release notes | `docs/releases/2.0.0-rc.1/` and readiness docs are in-tree; May 19 evidence records queue-zero state, canonical ECC identity, release video suite, growth outreach pack, owner approval packet, local 2550-test suite, PR #2001 merge and GitHub Actions run `26102500291`, PR #2002 owner-approval dashboard gate refresh and GitHub Actions run `26103853507`, PR #2004 Linear readiness evidence sync and GitHub Actions run `26105012698`, May 19 operator dashboard, `owner-approval-packet-2026-05-19.md`, and preview-pack smoke digest `790430aef4a8` | Needs final release approval |
|
||||||
| Hermes specialized skills included safely | Hermes setup/import docs and sanitized skill surface | Hermes setup and import playbook are public; secrets stay local | Needs final release review |
|
| Hermes specialized skills included safely | Hermes setup/import docs and sanitized skill surface | Hermes setup and import playbook are public; secrets stay local | Needs final release review |
|
||||||
| Naming and rename readiness | Naming matrix across package/plugin/docs/social surfaces | `docs/releases/2.0.0-rc.1/naming-and-publication-matrix.md` records current package, repo, Claude plugin, Codex plugin, OpenCode, and npm availability evidence | Complete for rc.1; post-rc rename remains future work |
|
| Naming and rename readiness | Naming matrix across package/plugin/docs/social surfaces | `docs/releases/2.0.0-rc.1/naming-and-publication-matrix.md` records current package, repo, Claude plugin, Codex plugin, OpenCode, and npm availability evidence | Complete for rc.1; post-rc rename remains future work |
|
||||||
| Claude and Codex plugin publication | Contact/submission path with required artifacts and status | Publication readiness, naming matrix, and May 12 dry-run evidence document plugin validation, clean-checkout Claude tag/install smoke, and Codex marketplace CLI shape | Needs explicit approval for real tag/push and marketplace submission |
|
| Claude and Codex plugin publication | Contact/submission path with required artifacts and status | Publication readiness, naming matrix, and May 12 dry-run evidence document plugin validation, clean-checkout Claude tag/install smoke, and Codex marketplace CLI shape | Needs explicit approval for real tag/push and marketplace submission |
|
||||||
| Articles, tweets, and announcements | X thread, LinkedIn copy, GitHub release copy, push checklist | Draft launch collateral exists under rc.1 release docs | Needs URL-backed refresh |
|
| Articles, tweets, and announcements | X thread, LinkedIn copy, GitHub release copy, push checklist, partner/sponsor/talk pack | Draft launch collateral and approval-gated outreach copy exist under rc.1 release docs | Needs URL-backed refresh and human approval before posting or sending |
|
||||||
| AgentShield enterprise iteration | Policy gates, SARIF, packs, provenance, corpus, HTML reports, exception lifecycle audit, baseline drift Action/CLI surfaces, evidence-pack redaction, harness adapter registry, enterprise research roadmap, supply-chain hardened release path, CI-safe baseline fingerprints, corpus accuracy recommendations, remediation workflow phases, env proxy hijack corpus coverage, Mini Shai-Hulud full-campaign package IOCs, CI-provenance evidence packs, plugin-cache runtime-confidence triage, evidence-pack consumer readback, fleet-level evidence-pack routing, fleet review items, fleet review ticket payloads, checksum-backed policy export, checksum-verified policy promotion, policy promotion review items, package-manager hardening drift detection, npm age-gate guidance correction, workflow action-runtime pin refresh, package-manager hardening Action outputs, policy-promotion Action outputs, ECC-Tools hosted consumption of promotion Action outputs, ECC-Tools operator-visible promotion output values, and ECC-Tools hosted promotion judge audit traces | PRs #53, #55-#64, #67-#69, and #78-#92 landed with test evidence, ECC-Tools #76 consumes the fleet-summary output in hosted security review, #77 surfaces source evidence paths in hosted finding output, and #78 links fleet routes to harness owner review; AgentShield #91 adds `agentshield policy export` bundles for branch-protection review and downstream promotion; AgentShield #92 adds `agentshield policy promote` with digest verification, tamper rejection, explicit pack selection, dry-run review, and JSON output before writing active policy; AgentShield commit `87aec47` adds `reviewItems` for digest evidence, owner review, protected rollout PR handoff, and runtime smoke testing with green local and remote CI; AgentShield commit `28d08c7` adds package-manager hardening drift detection for plaintext registry credentials, lifecycle-script enablement, and weak pnpm/Yarn release-age cooldowns with green local and remote CI; AgentShield commit `659f569` refreshes all workflow action runtime pins to SHA-pinned checkout v6.0.2 and setup-node v6.4.0 with green remote CI and no remaining action-runtime deprecation annotation; AgentShield commit `ee585cd` corrects npm release-age guidance by flagging unsupported npm age keys and keeping enforceable cooldown findings on pnpm/Yarn with green local and remote CI; AgentShield commit `1124535` exposes package-manager hardening status/count outputs and a redacted job-summary section for registry credentials, lifecycle scripts, and release-age gates with green local and remote CI; AgentShield commit `1593925` exposes policy-promotion status/count/digest outputs plus job-summary review items for owner approval, protected rollout, and runtime smoke, and marks runtime smoke verified when the same Action job scans with the promoted policy; AgentShield commit `840952a` adds Linear/operator-ready fleet review ticket payloads and expands current Mini Shai-Hulud IOC breadcrumbs with green local and remote CI; ECC-Tools commit `8658951` routes those policy-promotion Action outputs into hosted security review findings and Hosted Promotion Readiness scoring; ECC-Tools commit `16c537f` renders policy-promotion status, pack, review item count, action-required count, and digest in hosted security job comments/check-runs; ECC-Tools commit `05d4e82` renders hosted promotion judge request fingerprints and allowed-citation counts without raw provider output; native PDF export deferred in favor of self-contained HTML plus print-to-PDF until explicit enterprise demand appears; `docs/architecture/agentshield-enterprise-research-roadmap.md` now has baseline drift, evidence-pack bundle, redaction, adapter-registry, supply-chain hardening, hashed baseline fingerprints, corpus accuracy recommendation, remediation workflow, env proxy hijack corpus, Mini Shai-Hulud full-campaign package-table, `ci-context.json` provenance, `plugin-cache` confidence, `evidence-pack inspect` readback, `evidence-pack fleet` routing, fleet `reviewItems`, fleet review ticket payloads, policy export, policy promotion, policy promotion `reviewItems`, package-manager hardening Action outputs, policy-promotion Action outputs, hosted consumption of promotion Action outputs, operator-visible promotion output values, and hosted promotion judge audit traces landed | Next workflow automation should deepen live operator approval/readback after Marketplace/payment gates |
|
| AgentShield enterprise iteration | Policy gates, SARIF, packs, provenance, corpus, HTML reports, exception lifecycle audit, baseline drift Action/CLI surfaces, evidence-pack redaction, harness adapter registry, enterprise research roadmap, supply-chain hardened release path, CI-safe baseline fingerprints, corpus accuracy recommendations, remediation workflow phases, env proxy hijack corpus coverage, Mini Shai-Hulud full-campaign package IOCs, CI-provenance evidence packs, plugin-cache runtime-confidence triage, evidence-pack consumer readback, fleet-level evidence-pack routing, fleet review items, fleet review ticket payloads, checksum-backed policy export, checksum-verified policy promotion, policy promotion review items, package-manager hardening drift detection, npm age-gate guidance correction, workflow action-runtime pin refresh, package-manager hardening Action outputs, policy-promotion Action outputs, ECC-Tools hosted consumption of promotion Action outputs, ECC-Tools operator-visible promotion output values, and ECC-Tools hosted promotion judge audit traces | PRs #53, #55-#64, #67-#69, and #78-#92 landed with test evidence, ECC-Tools #76 consumes the fleet-summary output in hosted security review, #77 surfaces source evidence paths in hosted finding output, and #78 links fleet routes to harness owner review; AgentShield #91 adds `agentshield policy export` bundles for branch-protection review and downstream promotion; AgentShield #92 adds `agentshield policy promote` with digest verification, tamper rejection, explicit pack selection, dry-run review, and JSON output before writing active policy; AgentShield commit `87aec47` adds `reviewItems` for digest evidence, owner review, protected rollout PR handoff, and runtime smoke testing with green local and remote CI; AgentShield commit `28d08c7` adds package-manager hardening drift detection for plaintext registry credentials, lifecycle-script enablement, and weak pnpm/Yarn release-age cooldowns with green local and remote CI; AgentShield commit `659f569` refreshes all workflow action runtime pins to SHA-pinned checkout v6.0.2 and setup-node v6.4.0 with green remote CI and no remaining action-runtime deprecation annotation; AgentShield commit `ee585cd` corrects npm release-age guidance by flagging unsupported npm age keys and keeping enforceable cooldown findings on pnpm/Yarn with green local and remote CI; AgentShield commit `1124535` exposes package-manager hardening status/count outputs and a redacted job-summary section for registry credentials, lifecycle scripts, and release-age gates with green local and remote CI; AgentShield commit `1593925` exposes policy-promotion status/count/digest outputs plus job-summary review items for owner approval, protected rollout, and runtime smoke, and marks runtime smoke verified when the same Action job scans with the promoted policy; AgentShield commit `840952a` adds Linear/operator-ready fleet review ticket payloads and expands current Mini Shai-Hulud IOC breadcrumbs with green local and remote CI; ECC-Tools commit `8658951` routes those policy-promotion Action outputs into hosted security review findings and Hosted Promotion Readiness scoring; ECC-Tools commit `16c537f` renders policy-promotion status, pack, review item count, action-required count, and digest in hosted security job comments/check-runs; ECC-Tools commit `05d4e82` renders hosted promotion judge request fingerprints and allowed-citation counts without raw provider output; native PDF export deferred in favor of self-contained HTML plus print-to-PDF until explicit enterprise demand appears; `docs/architecture/agentshield-enterprise-research-roadmap.md` now has baseline drift, evidence-pack bundle, redaction, adapter-registry, supply-chain hardening, hashed baseline fingerprints, corpus accuracy recommendation, remediation workflow, env proxy hijack corpus, Mini Shai-Hulud full-campaign package-table, `ci-context.json` provenance, `plugin-cache` confidence, `evidence-pack inspect` readback, `evidence-pack fleet` routing, fleet `reviewItems`, fleet review ticket payloads, policy export, policy promotion, policy promotion `reviewItems`, package-manager hardening Action outputs, policy-promotion Action outputs, hosted consumption of promotion Action outputs, operator-visible promotion output values, and hosted promotion judge audit traces landed | Next workflow automation should deepen live operator approval/readback after Marketplace/payment gates |
|
||||||
| ECC Tools next-level app | Billing audit, PR checks, deep analyzer, sync backlog, evaluator/RAG corpus, analysis-depth readiness, hosted execution planning, hosted CI diagnostics, hosted security evidence review, hosted harness compatibility audit, hosted reference-set evaluation, hosted AI routing/cost review, hosted team backlog routing, hosted depth-plan check-run, PR-comment hosted job dispatch, hosted job result history/check-runs, hosted result status command, status-aware depth-plan recommendations, hosted promotion readiness, hosted promotion output scoring, hosted promotion retrieval planning, hosted promotion judge contract, gated hosted promotion judge execution, hosted promotion judge audit trace, payment-announcement readiness, billing announcement preflight, aggregate production billing KV readback, Marketplace webhook provenance, target-account billing readback, Marketplace-source provenance counts, AgentShield fleet-summary hosted routing, hosted finding evidence paths, harness-route policy linking, policy-promotion Action-output hosted telemetry, and operator-visible promotion output values | PRs #26-#43 plus #53-#78 landed with test evidence, including AgentShield evidence-pack gap routing, canonical bundle recognition, supply-chain signature gates, PR draft follow-up Linear tracking, evidence-backed/deep-ready repository classification, the `/api/analysis/depth-plan` hosted job plan, `/api/analysis/jobs/ci-diagnostics`, `/api/analysis/jobs/security-evidence-review`, `/api/analysis/jobs/harness-compatibility-audit`, `/api/analysis/jobs/reference-set-evaluation`, `/api/analysis/jobs/ai-routing-cost-review`, `/api/analysis/jobs/team-backlog-routing`, the `ECC Tools / Hosted Depth Plan` check-run, `/ecc-tools analyze --job ...` PR-comment dispatch, non-blocking per-hosted-job result check-runs backed by 30-day result cache records, `/ecc-tools analyze --job status` cache lookup, cache-aware next-job recommendations in the depth-plan check-run, the `ECC Tools / Hosted Promotion Readiness` corpus-backed PR check-run, deterministic hosted-output scoring against cached completed job artifacts/findings, ranked retrieval/model-prompt planning, the fail-closed `hosted-promotion-judge.v1` request contract, opt-in live model-judge execution behind hosted evidence, entitlement, budget, provider, executor, strict JSON, and citation gates, hosted promotion judge request fingerprints plus allowed-citation audit trails, a fail-closed `/api/billing/readiness` `announcementGate` for native GitHub payments claims, `npm run billing:announcement-gate` plus `--preflight` as the non-secret operator verifier, hosted security findings for AgentShield fleet summaries, an `Evidence` column in hosted finding comments/check-runs, hosted harness findings that route AgentShield fleet target paths to harness owners, ECC-Tools commit `8658951` routing AgentShield policy-promotion Action outputs into hosted security review and promotion-readiness scoring, ECC-Tools commit `16c537f` rendering policy-promotion status/pack/count/digest values directly in hosted security job comments/check-runs, ECC-Tools commit `05d4e82` rendering model-judge audit traces without exposing raw provider output, ECC-Tools commit `91a441b` adding the safe billing announcement preflight path, ECC-Tools commit `eb69412` recording the initial production readback state, ECC-Tools commit `95d0bec` adding `npm run billing:kv-readback` with aggregate account-billing and billing-state records but 0 Marketplace Pro billing-state records, ECC-Tools commit `2859678` requiring webhook-derived Marketplace provenance before announcement readiness, ECC-Tools commit `42653f9` adding Wrangler OAuth readback, ECC-Tools commit `632e059` adding sanitized target-account readback that requires both target key families before `--require-ready` can pass, and ECC-Tools commit `d5f60db` adding sanitized Marketplace plan/action provenance counts; the latest 2026-05-18 live Wrangler OAuth recheck found 256 account-billing records, 256 billing-state records, 197 Marketplace-source records, 4 Marketplace webhook-provenance records, all `Open Source`, and 0 Marketplace Pro records, then updated Linear ITO-61 with the data/provisioning blocker | Next work is create or verify Marketplace-managed Pro target billing-state with webhook provenance, configure target account plus `INTERNAL_API_SECRET`, then run `billing:kv-readback -- --wrangler --wrangler-bin ./node_modules/.bin/wrangler --account <github-login> --require-ready`, followed by the live announcement gate |
|
| ECC Tools next-level app | Billing audit, PR checks, deep analyzer, sync backlog, evaluator/RAG corpus, analysis-depth readiness, hosted execution planning, hosted CI diagnostics, hosted security evidence review, hosted harness compatibility audit, hosted reference-set evaluation, hosted AI routing/cost review, hosted team backlog routing, hosted depth-plan check-run, PR-comment hosted job dispatch, hosted job result history/check-runs, hosted result status command, status-aware depth-plan recommendations, hosted promotion readiness, hosted promotion output scoring, hosted promotion retrieval planning, hosted promotion judge contract, gated hosted promotion judge execution, hosted promotion judge audit trace, payment-announcement readiness, billing announcement preflight, aggregate production billing KV readback, Marketplace webhook provenance, target-account billing readback, Marketplace-source provenance counts, AgentShield fleet-summary hosted routing, hosted finding evidence paths, harness-route policy linking, policy-promotion Action-output hosted telemetry, and operator-visible promotion output values | PRs #26-#43 plus #53-#78 landed with test evidence, including AgentShield evidence-pack gap routing, canonical bundle recognition, supply-chain signature gates, PR draft follow-up Linear tracking, evidence-backed/deep-ready repository classification, the `/api/analysis/depth-plan` hosted job plan, `/api/analysis/jobs/ci-diagnostics`, `/api/analysis/jobs/security-evidence-review`, `/api/analysis/jobs/harness-compatibility-audit`, `/api/analysis/jobs/reference-set-evaluation`, `/api/analysis/jobs/ai-routing-cost-review`, `/api/analysis/jobs/team-backlog-routing`, the `ECC Tools / Hosted Depth Plan` check-run, `/ecc-tools analyze --job ...` PR-comment dispatch, non-blocking per-hosted-job result check-runs backed by 30-day result cache records, `/ecc-tools analyze --job status` cache lookup, cache-aware next-job recommendations in the depth-plan check-run, the `ECC Tools / Hosted Promotion Readiness` corpus-backed PR check-run, deterministic hosted-output scoring against cached completed job artifacts/findings, ranked retrieval/model-prompt planning, the fail-closed `hosted-promotion-judge.v1` request contract, opt-in live model-judge execution behind hosted evidence, entitlement, budget, provider, executor, strict JSON, and citation gates, hosted promotion judge request fingerprints plus allowed-citation audit trails, a fail-closed `/api/billing/readiness` `announcementGate` for native GitHub payments claims, `npm run billing:announcement-gate` plus `--preflight` as the non-secret operator verifier, hosted security findings for AgentShield fleet summaries, an `Evidence` column in hosted finding comments/check-runs, hosted harness findings that route AgentShield fleet target paths to harness owners, ECC-Tools commit `8658951` routing AgentShield policy-promotion Action outputs into hosted security review and promotion-readiness scoring, ECC-Tools commit `16c537f` rendering policy-promotion status/pack/count/digest values directly in hosted security job comments/check-runs, ECC-Tools commit `05d4e82` rendering model-judge audit traces without exposing raw provider output, ECC-Tools commit `91a441b` adding the safe billing announcement preflight path, ECC-Tools commit `eb69412` recording the initial production readback state, ECC-Tools commit `95d0bec` adding `npm run billing:kv-readback` with aggregate account-billing and billing-state records but 0 Marketplace Pro billing-state records, ECC-Tools commit `2859678` requiring webhook-derived Marketplace provenance before announcement readiness, ECC-Tools commit `42653f9` adding Wrangler OAuth readback, ECC-Tools commit `632e059` adding sanitized target-account readback that requires both target key families before `--require-ready` can pass, and ECC-Tools commit `d5f60db` adding sanitized Marketplace plan/action provenance counts; the latest 2026-05-18 live Wrangler OAuth recheck found 256 account-billing records, 256 billing-state records, 197 Marketplace-source records, 4 Marketplace webhook-provenance records, all `Open Source`, and 0 Marketplace Pro records, then updated Linear ITO-61 with the data/provisioning blocker | Next work is create or verify Marketplace-managed Pro target billing-state with webhook provenance, configure target account plus `INTERNAL_API_SECRET`, then run `billing:kv-readback -- --wrangler --wrangler-bin ./node_modules/.bin/wrangler --account <github-login> --require-ready`, followed by the live announcement gate |
|
||||||
| GitGuardian/Dependabot/CodeRabbit-style checks | Non-blocking taxonomy, deterministic follow-up checks, and local supply-chain gates | ECC-Tools risk taxonomy check plus follow-up signals landed, including Skill Quality, Deep Analyzer Evidence, Analyzer Corpus Evidence, RAG/Evaluator Evidence, PR Review/Salvage Evidence, and AgentShield evidence-pack evidence; #1846 added npm registry signature gates; #1848 added the supply-chain incident-response playbook and `pull_request_target` cache-poisoning validator guard; #1851 added the privileged checkout credential-persistence guard; AgentShield #78, JARVIS #13, and ECC-Tools #53 applied the same hardening outside trunk | Current supply-chain gate complete; deeper hosted review features remain future |
|
| GitGuardian/Dependabot/CodeRabbit-style checks | Non-blocking taxonomy, deterministic follow-up checks, and local supply-chain gates | ECC-Tools risk taxonomy check plus follow-up signals landed, including Skill Quality, Deep Analyzer Evidence, Analyzer Corpus Evidence, RAG/Evaluator Evidence, PR Review/Salvage Evidence, and AgentShield evidence-pack evidence; #1846 added npm registry signature gates; #1848 added the supply-chain incident-response playbook and `pull_request_target` cache-poisoning validator guard; #1851 added the privileged checkout credential-persistence guard; AgentShield #78, JARVIS #13, and ECC-Tools #53 applied the same hardening outside trunk | Current supply-chain gate complete; deeper hosted review features remain future |
|
||||||
| Harness-agnostic learning system | Audit, adapter matrix, observability, traces, promotion loop | Audit/adapters/observability gates plus `docs/architecture/evaluator-rag-prototype.md`, `examples/evaluator-rag-prototype/`, and ECC-Tools PR #40 define read-only stale-salvage, billing-readiness, CI-failure-diagnosis, harness-config-quality, AgentShield policy-exception, skill-quality evidence, deep-analyzer evidence, and RAG/evaluator comparison scenarios with trace, report, playbook, verifier, and predictive-check artifacts; ECC-Tools PRs #68-#72 now turn that corpus into a deterministic PR check-run gate with cached hosted-output scoring, ranked retrieval candidates, a model prompt seed, a fail-closed hosted model-judge request contract, and opt-in live model execution behind strict hosted-evidence gates | Deterministic hosted PR check, cached output scoring, retrieval planning, judge contract, and gated model execution integrated |
|
| Harness-agnostic learning system | Audit, adapter matrix, observability, traces, promotion loop | Audit/adapters/observability gates plus `docs/architecture/evaluator-rag-prototype.md`, `examples/evaluator-rag-prototype/`, and ECC-Tools PR #40 define read-only stale-salvage, billing-readiness, CI-failure-diagnosis, harness-config-quality, AgentShield policy-exception, skill-quality evidence, deep-analyzer evidence, and RAG/evaluator comparison scenarios with trace, report, playbook, verifier, and predictive-check artifacts; ECC-Tools PRs #68-#72 now turn that corpus into a deterministic PR check-run gate with cached hosted-output scoring, ranked retrieval candidates, a model prompt seed, a fail-closed hosted model-judge request contract, and opt-in live model execution behind strict hosted-evidence gates | Deterministic hosted PR check, cached output scoring, retrieval planning, judge contract, and gated model execution integrated |
|
||||||
| Linear roadmap is detailed | Linear project status plus repo mirror | Repo mirror exists; issue creation was retried on 2026-05-12 and remains blocked by the workspace free issue limit; the May 18 sync adds queue-zero/work-items state, #1970/#1971/#1972/#1976 merge evidence, ITO-57 current-head supply-chain refresh comment `0b9931b9-1556-4ebc-a70c-f3635557625d`, ITO-57 defensive-deny scanner recheck reply `6fa15367-d994-4e53-ade3-9462477e1100`, ECC platform progress comment `e32e5b7a-287b-4bf4-9ed7-314389a157e1`, and generated `operator:dashboard` prompt-to-artifact audit for recurring status updates | Needs recurring status updates after each significant merge batch |
|
| Linear roadmap is detailed | Linear project status plus repo mirror | Repo mirror exists and issue creation works again; the May 19 sync adds post-PR #2002 document `ecc-may-19-post-pr-2002-sync-64cef8f668e0`, project comment `a6411e3a-8c8e-4a58-adba-687e77d4c543`, ITO-44/47/48/49/51/54/56 issue comments, and In Progress state for ITO-47, ITO-48, ITO-49, ITO-51, ITO-54, and ITO-56; PR #2004 mirrors that sync into the repo evidence set | Needs recurring status updates after each significant merge batch |
|
||||||
| Flow separation and progress tracking | Flow lanes with owner artifacts and update cadence | This roadmap defines lanes below and `docs/architecture/progress-sync-contract.md` makes GitHub/Linear/handoff/roadmap sync part of the readiness gate | Active |
|
| Flow separation and progress tracking | Flow lanes with owner artifacts and update cadence | This roadmap defines lanes below and `docs/architecture/progress-sync-contract.md` makes GitHub/Linear/handoff/roadmap sync part of the readiness gate | Active |
|
||||||
| Realtime Linear sync | Project comments while issue/status capacity is blocked; issues later | ECC-Tools #39 implements opt-in Linear API sync for deferred follow-up backlog items, and ECC-Tools #54 adds copy-ready PR drafts to that backlog when draft PR shells are not opened; `docs/architecture/progress-sync-contract.md` defines the local file-backed realtime boundary while issue capacity is blocked; May 18 live connector comments were posted to ITO-57 and the ECC platform project after project status updates returned disabled | Needs workspace capacity/config rollout for productized issue sync |
|
| Realtime Linear sync | Project comments while issue/status capacity is blocked; issues later | ECC-Tools #39 implements opt-in Linear API sync for deferred follow-up backlog items, and ECC-Tools #54 adds copy-ready PR drafts to that backlog when draft PR shells are not opened; `docs/architecture/progress-sync-contract.md` defines the local file-backed realtime boundary while issue capacity is blocked; May 18 live connector comments were posted to ITO-57 and the ECC platform project after project status updates returned disabled | Needs workspace capacity/config rollout for productized issue sync |
|
||||||
| Observability for self-use | Local readiness gate, traces, status snapshots, HUD/status contract, risk ledger, progress-sync contract | `npm run observability:ready` reports 21/21 | Complete for local gate |
|
| Observability for self-use | Local readiness gate, traces, status snapshots, HUD/status contract, risk ledger, progress-sync contract | `npm run observability:ready` reports 21/21 | Complete for local gate |
|
||||||
|
|||||||
@@ -28,15 +28,15 @@ curl -s https://api.npmjs.org/downloads/point/last-month/ecc-agentshield
|
|||||||
### GitHub repository adoption
|
### GitHub repository adoption
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gh api repos/affaan-m/everything-claude-code \
|
gh api repos/affaan-m/ECC \
|
||||||
--jq '{stars:.stargazers_count,forks:.forks_count,contributors_url:.contributors_url,open_issues:.open_issues_count}'
|
--jq '{stars:.stargazers_count,forks:.forks_count,contributors_url:.contributors_url,open_issues:.open_issues_count}'
|
||||||
```
|
```
|
||||||
|
|
||||||
### GitHub traffic (maintainer access required)
|
### GitHub traffic (maintainer access required)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
gh api repos/affaan-m/everything-claude-code/traffic/views
|
gh api repos/affaan-m/ECC/traffic/views
|
||||||
gh api repos/affaan-m/everything-claude-code/traffic/clones
|
gh api repos/affaan-m/ECC/traffic/clones
|
||||||
```
|
```
|
||||||
|
|
||||||
### GitHub App installs
|
### GitHub App installs
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ Use these templates as launch-ready starting points. Review channel tone before
|
|||||||
```text
|
```text
|
||||||
ECC v2.0.0-rc.1 preview pack is ready for final release review.
|
ECC v2.0.0-rc.1 preview pack is ready for final release review.
|
||||||
|
|
||||||
The repo is moving from a Claude Code config pack into a cross-harness operating system for agentic work.
|
ECC 2.0 is the harness-native operator system for agentic work: skills, hooks,
|
||||||
|
rules, MCP conventions, release gates, and an optional Hermes operator shell.
|
||||||
|
|
||||||
What ships:
|
What ships:
|
||||||
- Hermes setup guide
|
- Hermes setup guide
|
||||||
@@ -15,8 +16,8 @@ What ships:
|
|||||||
- cross-harness architecture docs
|
- cross-harness architecture docs
|
||||||
- Hermes import guidance for turning local operator workflows into public ECC skills
|
- Hermes import guidance for turning local operator workflows into public ECC skills
|
||||||
|
|
||||||
Start here: https://github.com/affaan-m/everything-claude-code
|
Start here: https://github.com/affaan-m/ECC
|
||||||
Release notes: https://github.com/affaan-m/everything-claude-code/blob/main/docs/releases/2.0.0-rc.1/release-notes.md
|
Release notes: https://github.com/affaan-m/ECC/blob/main/docs/releases/2.0.0-rc.1/release-notes.md
|
||||||
```
|
```
|
||||||
|
|
||||||
## X Post: Proof + Metrics
|
## X Post: Proof + Metrics
|
||||||
@@ -57,7 +58,7 @@ ECC v2.0.0-rc.1 pushes that further: reusable skills, thin harness adapters, and
|
|||||||
```text
|
```text
|
||||||
ECC v2.0.0-rc.1 preview pack is ready for final release review.
|
ECC v2.0.0-rc.1 preview pack is ready for final release review.
|
||||||
|
|
||||||
The practical shift: ECC is no longer just a Claude Code config pack. It is becoming a cross-harness operating system for agentic work.
|
ECC 2.0 is the harness-native operator system for agentic work. The same reusable layer now reaches Claude Code, Codex, OpenCode, Cursor, Gemini, Zed, GitHub Copilot workflows, and terminal-only operator lanes.
|
||||||
|
|
||||||
This release-candidate surface includes:
|
This release-candidate surface includes:
|
||||||
- sanitized Hermes setup documentation
|
- sanitized Hermes setup documentation
|
||||||
@@ -67,6 +68,6 @@ This release-candidate surface includes:
|
|||||||
|
|
||||||
It does not include private workspace state, credentials, raw local exports, or personal datasets.
|
It does not include private workspace state, credentials, raw local exports, or personal datasets.
|
||||||
|
|
||||||
Repo: https://github.com/affaan-m/everything-claude-code
|
Repo: https://github.com/affaan-m/ECC
|
||||||
Release notes: https://github.com/affaan-m/everything-claude-code/blob/main/docs/releases/2.0.0-rc.1/release-notes.md
|
Release notes: https://github.com/affaan-m/ECC/blob/main/docs/releases/2.0.0-rc.1/release-notes.md
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -36,7 +36,13 @@
|
|||||||
- publish the X thread from `x-thread.md`
|
- publish the X thread from `x-thread.md`
|
||||||
- publish the LinkedIn draft from `linkedin-post.md`
|
- publish the LinkedIn draft from `linkedin-post.md`
|
||||||
- use `article-outline.md` for the longer writeup
|
- use `article-outline.md` for the longer writeup
|
||||||
|
- route sponsor, partner, consulting, conference, podcast, and GitHub
|
||||||
|
Discussion copy through `partner-sponsor-talks-pack.md`
|
||||||
- record one 30-60 second proof-of-work clip
|
- record one 30-60 second proof-of-work clip
|
||||||
|
- validate the release video suite with `npm run release:video-suite -- --format json`
|
||||||
|
after setting `ECC_VIDEO_SOURCE_ROOT` and `ECC_VIDEO_RELEASE_SUITE_ROOT`
|
||||||
|
- keep `video-suite-production.md` aligned with the actual primary launch
|
||||||
|
render, timeline, captions, and self-eval gate
|
||||||
|
|
||||||
## Demo Asset Suggestions
|
## Demo Asset Suggestions
|
||||||
|
|
||||||
@@ -54,3 +60,6 @@ Use language like:
|
|||||||
- "cross-harness operating system for agentic work"
|
- "cross-harness operating system for agentic work"
|
||||||
- "ECC is the reusable substrate; Hermes is the operator shell"
|
- "ECC is the reusable substrate; Hermes is the operator shell"
|
||||||
- "private/local integrations land after sanitization"
|
- "private/local integrations land after sanitization"
|
||||||
|
|
||||||
|
Do not send sponsor, partner, consulting, conference, or podcast outreach
|
||||||
|
without explicit human approval.
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
# ECC v2.0.0-rc.1 Naming And Publication Matrix
|
# ECC v2.0.0-rc.1 Naming And Publication Matrix
|
||||||
|
|
||||||
Snapshot date: 2026-05-18.
|
Snapshot date: 2026-05-19.
|
||||||
|
|
||||||
This matrix answers the release question "ship as Everything Claude Code, ECC,
|
This matrix records the rc.1 identity after the public repository rename to
|
||||||
or a renamed surface?" for the rc.1 lane. It is evidence for planning, not a
|
`affaan-m/ECC`. It is evidence for planning, not a publication action.
|
||||||
publication action.
|
|
||||||
|
|
||||||
## Decision
|
## Decision
|
||||||
|
|
||||||
For `v2.0.0-rc.1`, keep the public identity as **Everything Claude Code (ECC)**.
|
For `v2.0.0-rc.1`, ship the public identity as **ECC**.
|
||||||
Use **ECC** as the short product name in copy, plugin slugs, status surfaces,
|
|
||||||
and diagrams, but do not rename the GitHub repo, npm package, or package entry
|
Use `affaan-m/ECC` as the canonical GitHub repo and `ECC` as the product name
|
||||||
points before the rc.1 release.
|
in copy, plugin slugs, status surfaces, diagrams, and release collateral. Keep
|
||||||
|
the npm package and package entry points as `ecc-universal` until a separate
|
||||||
|
post-rc migration plan exists.
|
||||||
|
|
||||||
Reason:
|
Reason:
|
||||||
|
|
||||||
@@ -19,21 +20,17 @@ Reason:
|
|||||||
plugin slug;
|
plugin slug;
|
||||||
- the exact npm package name `ecc` is already occupied by an unrelated elliptic
|
- the exact npm package name `ecc` is already occupied by an unrelated elliptic
|
||||||
curve cryptography package;
|
curve cryptography package;
|
||||||
- the repo name `affaan-m/ecc` is not present, but renaming
|
- `affaan-m/ECC` is the live public GitHub repo;
|
||||||
`affaan-m/everything-claude-code` before rc.1 would create avoidable URL,
|
|
||||||
package, docs, and marketplace churn;
|
|
||||||
- Claude and Codex plugin surfaces are already short enough as `ecc`;
|
- Claude and Codex plugin surfaces are already short enough as `ecc`;
|
||||||
- rc.1 should prove the release, plugin, and publication pipeline before any
|
- rc.1 should prove the release, plugin, and publication pipeline before any
|
||||||
broader brand migration.
|
npm/package rename.
|
||||||
|
|
||||||
## Current Values
|
## Current Values
|
||||||
|
|
||||||
| Surface | Current value | Evidence command | 2026-05-18 result | Release decision |
|
| Surface | Current value | Evidence command | 2026-05-18 result | Release decision |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| Product display name | `Everything Claude Code` | `rg -n "Everything Claude Code" README.md CHANGELOG.md docs/releases/2.0.0-rc.1` | Present across README, release notes, launch copy, and plugin manifests | Keep for rc.1 |
|
| Product display name | `ECC` | `rg -n "^# ECC\|displayName.*ECC\|affaan-m/ECC" README.md .codex-plugin/plugin.json docs/releases/2.0.0-rc.1` | Present across README, plugin manifests, release copy, and URL ledger | Keep for rc.1 and GA |
|
||||||
| Short name | `ECC` | README/release docs | Used as the short cross-harness brand | Keep and prefer in tight copy |
|
| GitHub repo | `affaan-m/ECC` | `git remote get-url origin` | `https://github.com/affaan-m/ECC.git` | Keep for rc.1 and GA |
|
||||||
| GitHub repo | `affaan-m/everything-claude-code` | `git remote get-url origin` | `https://github.com/affaan-m/everything-claude-code.git` | Keep for rc.1 |
|
|
||||||
| Possible short repo | `affaan-m/ecc` | `gh repo view affaan-m/ecc` | Not found with current auth | Candidate after rc.1 only |
|
|
||||||
| npm package | `ecc-universal` | `node -p "require('./package.json').name"` | `ecc-universal` | Keep for rc.1 |
|
| npm package | `ecc-universal` | `node -p "require('./package.json').name"` | `ecc-universal` | Keep for rc.1 |
|
||||||
| npm package version | `2.0.0-rc.1` local, `1.10.0` registry latest | `node -p "require('./package.json').version"` and `npm view ecc-universal name version dist-tags --json` | Local rc.1 is ready; registry latest remains `1.10.0` and no `next` dist-tag exists yet | Publish rc as `next`, not `latest` |
|
| npm package version | `2.0.0-rc.1` local, `1.10.0` registry latest | `node -p "require('./package.json').version"` and `npm view ecc-universal name version dist-tags --json` | Local rc.1 is ready; registry latest remains `1.10.0` and no `next` dist-tag exists yet | Publish rc as `next`, not `latest` |
|
||||||
| Exact npm short name | `ecc` | `npm view ecc name version description repository.url --json` | Occupied by `ecc@0.0.2`, "Elliptic curve cryptography functions." | Do not use |
|
| Exact npm short name | `ecc` | `npm view ecc name version description repository.url --json` | Occupied by `ecc@0.0.2`, "Elliptic curve cryptography functions." | Do not use |
|
||||||
@@ -77,21 +74,18 @@ Reason:
|
|||||||
| Billing/native payments | Announcement remains blocked by ITO-61 | Marketplace Pro target readback, webhook provenance, `INTERNAL_API_SECRET`, announcement gate | ECC Tools owner | Do not include native-payments claim in rc.1 announcement |
|
| Billing/native payments | Announcement remains blocked by ITO-61 | Marketplace Pro target readback, webhook provenance, `INTERNAL_API_SECRET`, announcement gate | ECC Tools owner | Do not include native-payments claim in rc.1 announcement |
|
||||||
| Social/longform copy | Drafts exist | Final live GitHub, npm, Claude, Codex, billing URLs | Release owner | Publish only after release/package/plugin URLs exist |
|
| Social/longform copy | Drafts exist | Final live GitHub, npm, Claude, Codex, billing URLs | Release owner | Publish only after release/package/plugin URLs exist |
|
||||||
|
|
||||||
## Rename After rc.1
|
## Package Rename After rc.1
|
||||||
|
|
||||||
If the project moves from "Everything Claude Code" toward "ECC" after rc.1,
|
If the package layer moves from `ecc-universal` toward a shorter npm surface
|
||||||
do it as a staged migration:
|
after rc.1, do it as a staged migration:
|
||||||
|
|
||||||
1. Keep `ecc-universal` as the npm package until a replacement package has a
|
1. Keep `ecc-universal` as the npm package until a replacement package has a
|
||||||
verified owner, deprecation plan, and install migration.
|
verified owner, deprecation plan, and install migration.
|
||||||
2. Keep `affaan-m/everything-claude-code` as the canonical repo until release
|
2. Keep `affaan-m/ECC` as the canonical repo for public docs, release notes,
|
||||||
notes, docs, plugin marketplace entries, npm metadata, and external links
|
plugin marketplace entries, npm metadata, and external links.
|
||||||
are prepared for redirects.
|
3. Reserve or create any new npm/package surfaces before announcing the
|
||||||
3. Use `ECC` as the product name in new diagrams, status payloads, and
|
package rename.
|
||||||
cross-harness docs immediately.
|
4. Ship a compatibility guide that maps old commands, package names, plugin
|
||||||
4. Reserve or create any new GitHub/npm/package surfaces before announcing the
|
|
||||||
rename.
|
|
||||||
5. Ship a compatibility guide that maps old commands, package names, plugin
|
|
||||||
slugs, and docs URLs to the new names.
|
slugs, and docs URLs to the new names.
|
||||||
|
|
||||||
## Evidence Captured In This Pass
|
## Evidence Captured In This Pass
|
||||||
@@ -152,7 +146,7 @@ HOME="$(mktemp -d)" codex plugin marketplace add <local-checkout>
|
|||||||
Added marketplace ecc and recorded the installed marketplace root as
|
Added marketplace ecc and recorded the installed marketplace root as
|
||||||
<local-checkout> without touching the real Codex config.
|
<local-checkout> without touching the real Codex config.
|
||||||
|
|
||||||
HOME="$(mktemp -d)" codex plugin marketplace add affaan-m/everything-claude-code --ref "$(git rev-parse HEAD)"
|
HOME="$(mktemp -d)" codex plugin marketplace add affaan-m/ECC --ref "$(git rev-parse HEAD)"
|
||||||
Added marketplace ecc from the GitHub repo pinned to
|
Added marketplace ecc from the GitHub repo pinned to
|
||||||
67e63e63f9bfd074bd6a21bf6bac71f3dfefa58b without touching the real Codex
|
67e63e63f9bfd074bd6a21bf6bac71f3dfefa58b without touching the real Codex
|
||||||
config.
|
config.
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
# ECC Operator Readiness Dashboard
|
||||||
|
|
||||||
|
This dashboard is generated by `npm run operator:dashboard`. It is an operator snapshot, not release approval.
|
||||||
|
|
||||||
|
Generated: 2026-05-19T15:08:49.870Z
|
||||||
|
Commit: ac7434ea8f39166b11e9d06ce64b38c4fb8d9202
|
||||||
|
Status: work remaining
|
||||||
|
|
||||||
|
## Current Status
|
||||||
|
|
||||||
|
| Area | Status | Evidence |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| PR queue | Current | 0 open PRs across tracked repos |
|
||||||
|
| Issue queue | Current | 0 open issues across tracked repos |
|
||||||
|
| Discussions | Current | 0 need maintainer touch; 0 missing accepted answer |
|
||||||
|
| Local worktree | Current | 0 blocking dirty files; 0 ignored dirty entries |
|
||||||
|
| Dashboard generation | Current | platform audit ready: true; GitHub skipped: false |
|
||||||
|
| Publication | Not complete | release, npm, plugin, billing, and announcement gates are tracked below |
|
||||||
|
|
||||||
|
## Growth Baseline
|
||||||
|
|
||||||
|
| Metric | Current | Target | Gap |
|
||||||
|
| --- | ---: | ---: | ---: |
|
||||||
|
| MRR | $1,728/mo | $10,000/mo | $8,272/mo |
|
||||||
|
|
||||||
|
Growth lanes: GitHub Sponsors and OSS partner sponsors; ECC Tools Pro subscriptions; consulting and implementation contracts; talks, podcasts, conference demos, and partner webinars.
|
||||||
|
|
||||||
|
## Prompt-To-Artifact Checklist
|
||||||
|
|
||||||
|
| Objective requirement | Artifact or gate | Status | Evidence | Gap |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| Keep public PRs below 20 | scripts/platform-audit.js live GitHub sweep plus owner-wide queue cleanup ledger | current | 0 open PRs across 5 tracked repos; 0 owner-wide open PRs after cleanup | repeat platform:audit and owner-wide gh search before release |
|
||||||
|
| Keep public issues below 20 | scripts/platform-audit.js live GitHub sweep plus owner-wide queue cleanup ledger | current | 0 open issues across 5 tracked repos; 0 owner-wide open issues after cleanup | repeat platform:audit and owner-wide gh search before release |
|
||||||
|
| Respond and manage repository discussions | scripts/platform-audit.js discussion summary | current | 0 need maintainer touch; 0 answerable discussions missing accepted answer | repeat before release |
|
||||||
|
| Build ITO-44 completion dashboard into a repeatable command | npm run operator:dashboard | complete | operator:dashboard package script exists | keep generated dashboard attached to publication evidence |
|
||||||
|
| ECC 2.0 preview pack ready | docs/releases/2.0.0-rc.1/preview-pack-manifest.md | current | preview pack manifest and deterministic smoke gate are in-tree | repeat clean-checkout preview-pack smoke before publication |
|
||||||
|
| Include Hermes specialized skills safely | docs/HERMES-SETUP.md and skills/hermes-imports/SKILL.md | current | Hermes setup/import artifacts are covered by preview-pack smoke | repeat preview-pack smoke before release review |
|
||||||
|
| Prepare name-change, Claude plugin, and Codex plugin paths | naming-and-publication-matrix plus release-name-plugin-publication checklist plus publication-readiness | in_progress | naming matrix, release publication checklist, and plugin readiness gates exist | real tag/push, marketplace submission, and final channel choice remain approval-gated |
|
||||||
|
| Prepare release notes, articles, tweets, and push notifications | docs/releases/2.0.0-rc.1 social and release-copy files | in_progress | release notes, X thread, LinkedIn draft, and URL ledger are present | final live release/npm/plugin/billing URLs and publish approval still pending |
|
||||||
|
| Prepare final owner approval packet | docs/releases/2.0.0-rc.1/owner-approval-packet-2026-05-19.md | current | owner approval packet covers release, package, plugin, video, billing, social, and outbound decisions | review owner approvals from the final release commit before any publication or outbound action |
|
||||||
|
| Create a second-phase hypergrowth release command center | docs/releases/2.0.0/ecc-2-hypergrowth-release-command-center.md plus May 19 evidence | current | current MRR, target MRR, gap, release claim, video lane, distribution plan, and approval boundaries are in-tree | refresh after every MRR, channel, or approval-state change before public launch |
|
||||||
|
| Produce the ECC 2.0 release video suite | docs/releases/2.0.0-rc.1/video-suite-production.md and npm run release:video-suite | current | video-suite gate is ready with 15/15 source assets, 13/13 suite artifacts, 12/12 publish candidates, primary self-eval, and zero detected black-frame segments recorded in May 19 evidence | final owner approval, upload, and public video URLs remain approval-gated |
|
||||||
|
| Prepare sponsor, partner, consulting, podcast, talk, and Discussion copy | docs/releases/2.0.0-rc.1/partner-sponsor-talks-pack.md | in_progress | sponsor outbound, platform partner DM, consulting intro, talk/podcast pitch, GitHub Discussion announcement, CTA hooks, and do-not-send gate are drafted | replace final URLs after publication gates, then get explicit approval before outbound or personal-account posts |
|
||||||
|
| Advance AgentShield enterprise iteration | AgentShield PR evidence plus enterprise roadmap | in_progress | AgentShield policy promotion `reviewItems` landed in `87aec47`; package-manager hardening drift detection landed in `28d08c7`; workflow action runtime pins were refreshed in `659f569`; npm age-gate guidance was corrected in `ee585cd`; package-manager hardening Action outputs landed in `1124535`; policy-promotion Action outputs and runtime-smoke job-summary evidence landed in `1593925`; fleet review ticket payloads and current Mini Shai-Hulud IOC breadcrumbs landed in `840952a`; ECC-Tools consumes those outputs in `8658951`, surfaces operator-readable status/pack/count/digest telemetry in `16c537f`, and renders hosted promotion judge audit traces in `05d4e82`; all are mirrored in the GA roadmap | deepen live operator approval/readback after Marketplace/payment gates |
|
||||||
|
| Advance ECC Tools native payments and AI-native harness-agnostic app | ECC Tools PR evidence, billing gate, hosted analysis lanes | in_progress | billing announcement gate, hosted analysis lanes, AgentShield fleet-summary consumption, hosted finding evidence paths, harness-route policy linking, policy-promotion Action-output telemetry, operator-visible promotion output details, hosted promotion judge audit traces, billing announcement preflight, aggregate production billing KV readback, Wrangler OAuth readback, target-account billing readback, provenance-aware Marketplace billing-state gates, sanitized Marketplace plan/action provenance counts, hosted team-learning feedback controls, and ECC-Tools Dependabot alert remediation are mirrored in the GA roadmap | create or verify Marketplace-managed Pro target billing-state with webhook provenance, configure the target account and INTERNAL_API_SECRET, then rerun target readback and the live announcement gate |
|
||||||
|
| Audit, prune, or attach legacy work | docs/stale-pr-salvage-ledger.md and legacy inventory | current | legacy salvage ledger and inventory are current; all localization tails are attached to Linear ITO-55 for manual language-owner review | repeat legacy scan before release |
|
||||||
|
| Keep Linear roadmap detailed and progress tracking synchronized | Linear project mirror plus progress-sync contract | current | Linear live sync is current with the May 19 post-PR #2002 sync document, project comment, and active issue-lane updates; progress-sync contract defines the file-backed work-items/status path | repeat Linear/project status update and local work-items sync after each significant merge batch |
|
||||||
|
| Provide ECC 2.0 observability for self-use | observability readiness gate | complete | observability:ready command and readiness doc exist | runtime/dashboard implementation can continue after release gates |
|
||||||
|
| Keep Mini Shai-Hulud/TanStack protection loop current | supply-chain watch plus runbook plus AgentShield package-manager hardening | current | scheduled supply-chain watch emits IOC/advisory-source refresh artifacts; ECC scanner covers gh-token-monitor token-store persistence; AgentShield now detects known AI-tool persistence IOCs, npm lifecycle/token drift, unsupported npm age-key drift, and pnpm/Yarn cooldown drift; current-head watch evidence and ITO-57 May 18 Linear evidence updates are current | repeat advisory/source refresh and Linear sync after each significant supply-chain batch |
|
||||||
|
|
||||||
|
## Top Actions
|
||||||
|
|
||||||
|
- `naming-and-plugin-publication`: real tag/push, marketplace submission, and final channel choice remain approval-gated
|
||||||
|
- `release-notes-and-notifications`: final live release/npm/plugin/billing URLs and publish approval still pending
|
||||||
|
- `partner-sponsor-talks-pack`: replace final URLs after publication gates, then get explicit approval before outbound or personal-account posts
|
||||||
|
- `agentshield-enterprise-iteration`: deepen live operator approval/readback after Marketplace/payment gates
|
||||||
|
- `ecc-tools-next-level`: create or verify Marketplace-managed Pro target billing-state with webhook provenance, configure the target account and INTERNAL_API_SECRET, then rerun target readback and the live announcement gate
|
||||||
|
|
||||||
|
## Next Work Order
|
||||||
|
|
||||||
|
1. Regenerate this dashboard from the final release commit before publication evidence is recorded.
|
||||||
|
2. Review the owner approval packet from the final release commit and approve, defer, or block each publication and outbound lane.
|
||||||
|
3. Review the owner-approved primary launch video candidates, choose the final cuts, upload after approval, and attach public video URLs to the release pack.
|
||||||
|
4. Replace final release, npm, plugin, billing, and video URLs in the partner/sponsor/talk pack, then get explicit approval before outbound.
|
||||||
|
5. Repeat ITO-57 Linear/project status sync after the next significant merge batch or advisory-source refresh.
|
||||||
|
6. Create or verify Marketplace-managed Pro target billing-state with webhook provenance, configure the target account and INTERNAL_API_SECRET, then rerun target readback and the live announcement gate before publishing native-payments copy.
|
||||||
95
docs/releases/2.0.0-rc.1/owner-approval-packet-2026-05-19.md
Normal file
95
docs/releases/2.0.0-rc.1/owner-approval-packet-2026-05-19.md
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
# ECC v2.0.0-rc.1 Owner Approval Packet
|
||||||
|
|
||||||
|
Snapshot date: 2026-05-19.
|
||||||
|
|
||||||
|
This packet is the final human decision sheet for the rc.1 public launch. It
|
||||||
|
does not publish anything by itself. Use it to approve, defer, or block each
|
||||||
|
release action after the final evidence commands are rerun from the intended
|
||||||
|
release commit.
|
||||||
|
|
||||||
|
Source commit for the clean evidence baseline this packet extends:
|
||||||
|
`ac7434ea8f39166b11e9d06ce64b38c4fb8d9202`.
|
||||||
|
|
||||||
|
## Current Evidence
|
||||||
|
|
||||||
|
| Evidence | Current recorded state | Repeat before approval |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Platform audit | ready true, 0 open PRs, 0 open issues, 0 discussion gaps, 0 dirty files | yes |
|
||||||
|
| Preview pack smoke | ready true, digest `790430aef4a8`, 5/5 checks | yes |
|
||||||
|
| Video suite | ready true, 15/15 source assets, 13/13 suite artifacts, 12/12 publish candidates | yes |
|
||||||
|
| Release surface tests | 27/27 passed after this packet was added | yes |
|
||||||
|
| Full local suite | 2550/2550 passed after this packet was added | yes |
|
||||||
|
| GitHub CI | PR #1998, PR #1999, PR #2000, PR #2001, PR #2002, and PR #2004 merged after green required checks | verify current head |
|
||||||
|
|
||||||
|
## Decision Register
|
||||||
|
|
||||||
|
| Decision | Approve / defer / block | Evidence required first | Notes |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| GitHub prerelease | defer | final clean branch, URL ledger, release notes, attached video or video link | Approve only after final release notes contain live package/plugin/video URLs or explicitly marked blocked URLs. |
|
||||||
|
| npm `next` publish | defer | `npm pack --dry-run`, `npm publish --tag next --dry-run`, registry dist-tag readback plan | Keep `ecc-universal@2.0.0-rc.1` on `next`; do not move `latest` during rc.1. |
|
||||||
|
| Claude plugin tag | defer | `claude plugin validate .claude-plugin/plugin.json`, `claude plugin tag .claude-plugin --dry-run` | Create and push the real tag only after release approval. |
|
||||||
|
| Codex repo marketplace | defer | temp-home marketplace add smoke and current official Plugin Directory status | Claim repo-marketplace distribution only; do not claim official Plugin Directory listing without listing evidence. |
|
||||||
|
| ECC Tools billing language | defer | live readiness readback for the target account and billing/product state | Do not announce native payments or Marketplace-managed Pro until the gate is live. |
|
||||||
|
| Video upload | defer | owner selects primary launch cut plus short clips, self-eval stays clean | Upload only approved cuts; keep editable timeline/project output preserved. |
|
||||||
|
| X, LinkedIn, GitHub Discussion, longform | defer | live release, npm, plugin, video, and billing URL ledger updates | Personal-account posts and outbound copy need explicit approval. |
|
||||||
|
| Sponsor, partner, consulting, conference, podcast outreach | defer | final public URLs plus owner-approved outbound copy | Do not send drafts until the owner approves the exact batch. |
|
||||||
|
|
||||||
|
## Final URL Fill-In
|
||||||
|
|
||||||
|
Update these surfaces after the approved publication actions finish:
|
||||||
|
|
||||||
|
| Surface | Final value source | Update targets |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| GitHub prerelease URL | `gh release view v2.0.0-rc.1 --repo affaan-m/ECC --json url` | release notes, URL ledger, social copy |
|
||||||
|
| npm rc package URL | `npm view ecc-universal@2.0.0-rc.1 version dist-tags --json` | URL ledger, quickstart, release notes |
|
||||||
|
| Claude plugin tag URL | pushed `ecc--v2.0.0-rc.1` tag or marketplace readback | URL ledger, plugin docs, release notes |
|
||||||
|
| Codex repo-marketplace evidence | temp-home `codex plugin marketplace add <local-checkout>` readback | URL ledger, publication readiness |
|
||||||
|
| Primary launch video URL | uploaded owner-approved primary launch video | GitHub release, X, LinkedIn, longform |
|
||||||
|
| Short clip URLs | uploaded approved clips | X thread, LinkedIn, partner/sponsor/talk pack |
|
||||||
|
| ECC Tools billing/readiness URL | live readiness readback or explicit blocked status | sponsor copy, Pro copy, release notes |
|
||||||
|
|
||||||
|
## Final Evidence Commands
|
||||||
|
|
||||||
|
Run these from the exact release commit before approving publication:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git status --short --branch
|
||||||
|
node scripts/platform-audit.js --json
|
||||||
|
npm run preview-pack:smoke -- --format json
|
||||||
|
npm run release:video-suite -- --format json
|
||||||
|
npm run harness:adapters -- --check
|
||||||
|
npm run harness:audit -- --format json
|
||||||
|
npm run observability:ready
|
||||||
|
npm run security:ioc-scan
|
||||||
|
npm audit --audit-level=moderate
|
||||||
|
npm audit signatures
|
||||||
|
node tests/docs/ecc2-release-surface.test.js
|
||||||
|
node tests/run-all.js
|
||||||
|
cd ecc2 && cargo test
|
||||||
|
```
|
||||||
|
|
||||||
|
## Approval Text
|
||||||
|
|
||||||
|
Use short, explicit approvals. Example:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Approved for rc.1 GitHub prerelease, npm next publish, Claude plugin tag, and
|
||||||
|
release announcement after the final evidence commands pass from commit <sha>.
|
||||||
|
Video uploads approved for <primary-video> and <shorts-list>.
|
||||||
|
Outbound sponsor, partner, consulting, conference, and podcast messages remain
|
||||||
|
blocked until I approve the exact batch.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Do Not Approve If
|
||||||
|
|
||||||
|
- The final branch is dirty or no longer matches the intended release commit.
|
||||||
|
- Any required evidence command fails or is skipped without a written deferral.
|
||||||
|
- The release copy claims live billing, plugin marketplace propagation, npm
|
||||||
|
`next`, or official Codex Plugin Directory listing before readback exists.
|
||||||
|
- Announcement copy contains stale URLs, private paths, or unresolved live-link
|
||||||
|
decisions.
|
||||||
|
- The selected video cut has black frames, missing audio, stale URLs, weak
|
||||||
|
product proof, or unreviewed captions.
|
||||||
|
- The outbound batch has not been reviewed exactly as it will be sent.
|
||||||
|
|
||||||
|
No outbound email, personal-account post, package publish, plugin tag, or billing announcement is authorized by this packet alone.
|
||||||
208
docs/releases/2.0.0-rc.1/partner-sponsor-talks-pack.md
Normal file
208
docs/releases/2.0.0-rc.1/partner-sponsor-talks-pack.md
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
# ECC v2.0.0-rc.1 Partner, Sponsor, and Talks Pack
|
||||||
|
|
||||||
|
This pack turns the rc.1 release surface into outbound-ready copy for sponsors,
|
||||||
|
partners, consulting conversations, conference talks, podcast bookings, and
|
||||||
|
community announcements.
|
||||||
|
|
||||||
|
It is not a publish action. Use it after the release URL ledger, video suite,
|
||||||
|
and publication gates are current.
|
||||||
|
|
||||||
|
## Current Business Baseline
|
||||||
|
|
||||||
|
| Metric | Current | Target | Gap |
|
||||||
|
| --- | ---: | ---: | ---: |
|
||||||
|
| MRR | `$1,728/mo` | `$10,000/mo` | `$8,272/mo` |
|
||||||
|
| Core revenue lanes | Sponsors, ECC Tools Pro, consulting, talks | Repeatable growth loop | Approval-gated outbound |
|
||||||
|
| Launch proof | rc.1 preview pack, video suite, queue-zero audit | Public release package | Final URLs and human approval |
|
||||||
|
|
||||||
|
## Positioning Line
|
||||||
|
|
||||||
|
ECC 2.0 is the harness-native operator system for agentic work.
|
||||||
|
|
||||||
|
Use this short version in partner and sponsor messages:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ECC gives teams one reusable layer for skills, hooks, rules, MCP conventions,
|
||||||
|
release gates, and operator workflows across Claude Code, Codex, OpenCode,
|
||||||
|
Cursor, Gemini, Zed, GitHub Copilot, and terminal-only workflows.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Offer Ladder
|
||||||
|
|
||||||
|
| Motion | Best fit | Starting point | Primary ask |
|
||||||
|
| --- | --- | ---: | --- |
|
||||||
|
| Pilot sponsor | OSS-friendly team that wants early signal | `$200/mo` | GitHub Sponsors |
|
||||||
|
| Business sponsor | Tooling or AI infra company that wants logo and case-study surface | `$500/mo` | GitHub Sponsors or direct invoice |
|
||||||
|
| Strategic partner | Platform, marketplace, security, or developer-tool company | `$1,000+/mo` | Sponsor plus launch or integration plan |
|
||||||
|
| Consulting sprint | Team adopting agent harnesses internally | Scoped quote | Harness audit, rollout plan, and operating loop |
|
||||||
|
| Talk or podcast | Devtools, AI engineering, security, OSS, or founder audience | No fee required for high-leverage reach | Recording slot, demo slot, or conference proposal |
|
||||||
|
|
||||||
|
## Partner Targets
|
||||||
|
|
||||||
|
Prioritize partners that already benefit from a harness-agnostic operating
|
||||||
|
layer:
|
||||||
|
|
||||||
|
- AI coding platforms and IDEs;
|
||||||
|
- hosted agent and workflow orchestration tools;
|
||||||
|
- code review, security, and supply-chain vendors;
|
||||||
|
- model and inference providers;
|
||||||
|
- developer education, podcast, and conference organizers;
|
||||||
|
- teams adopting multiple harnesses at once.
|
||||||
|
|
||||||
|
## Sponsor Outbound
|
||||||
|
|
||||||
|
Subject:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ECC 2.0 sponsor slot for cross-harness agent workflows
|
||||||
|
```
|
||||||
|
|
||||||
|
Body:
|
||||||
|
|
||||||
|
```text
|
||||||
|
Hey [name],
|
||||||
|
|
||||||
|
I am getting ECC v2.0.0-rc.1 ready for release review.
|
||||||
|
|
||||||
|
The project is now positioned around one reusable operator layer for agentic
|
||||||
|
work across Claude Code, Codex, OpenCode, Cursor, Gemini, Zed, GitHub Copilot,
|
||||||
|
and terminal workflows.
|
||||||
|
|
||||||
|
The sponsor fit is pretty direct: ECC reaches the exact builders who are
|
||||||
|
standardizing their AI coding stack, security posture, and workflow automation.
|
||||||
|
|
||||||
|
The current public sponsor ladder is:
|
||||||
|
|
||||||
|
- Pilot Partner: $200/mo
|
||||||
|
- Business Sponsor: $500/mo
|
||||||
|
- Strategic Partner: $1,000+/mo
|
||||||
|
|
||||||
|
Business sponsors get logo placement and release visibility. Strategic partners
|
||||||
|
can turn it into a deeper integration or launch motion.
|
||||||
|
|
||||||
|
Repo: https://github.com/affaan-m/ECC
|
||||||
|
Sponsor: https://github.com/sponsors/affaan-m
|
||||||
|
Release notes: https://github.com/affaan-m/ECC/blob/main/docs/releases/2.0.0-rc.1/release-notes.md
|
||||||
|
|
||||||
|
If useful, I can send the short sponsor packet and a proposed first 30-day plan.
|
||||||
|
|
||||||
|
Affaan
|
||||||
|
```
|
||||||
|
|
||||||
|
## Platform Partner DM
|
||||||
|
|
||||||
|
```text
|
||||||
|
ECC 2.0 is getting close to rc.1.
|
||||||
|
|
||||||
|
The release is centered on cross-harness agent workflows: reusable skills,
|
||||||
|
hooks, rules, MCP conventions, release gates, and an optional Hermes operator
|
||||||
|
shell.
|
||||||
|
|
||||||
|
The partner angle is not "another prompt pack." It is a tested operating layer
|
||||||
|
for teams using more than one AI coding harness.
|
||||||
|
|
||||||
|
I think there is a real integration or co-launch angle here if your team wants
|
||||||
|
better setup, policy, security, or workflow portability for agent users.
|
||||||
|
|
||||||
|
Repo: https://github.com/affaan-m/ECC
|
||||||
|
```
|
||||||
|
|
||||||
|
## Consulting Intro
|
||||||
|
|
||||||
|
```text
|
||||||
|
I am open to a small number of ECC 2.0 implementation sprints for teams that
|
||||||
|
are standardizing AI coding workflows.
|
||||||
|
|
||||||
|
The useful scope is usually:
|
||||||
|
|
||||||
|
1. audit the current harness setup;
|
||||||
|
2. turn repeated workflows into ECC skills, hooks, and rules;
|
||||||
|
3. add release, security, and CI gates;
|
||||||
|
4. create a team operating loop that works across Claude Code, Codex, OpenCode,
|
||||||
|
Cursor, Gemini, Zed, GitHub Copilot, and terminal workflows.
|
||||||
|
|
||||||
|
This is not generic AI consulting. The output is a working harness operating
|
||||||
|
system your team can keep using.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Talk And Podcast Pitch
|
||||||
|
|
||||||
|
Title options:
|
||||||
|
|
||||||
|
- Building a Cross-Harness Operating System for AI Coding
|
||||||
|
- From Prompt Packs to Operator Systems
|
||||||
|
- What Breaks When Teams Adopt Too Many AI Coding Harnesses
|
||||||
|
- Security and Release Discipline for Agentic Coding Workflows
|
||||||
|
|
||||||
|
Short pitch:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ECC started as an open-source workflow layer for Claude Code and is now moving
|
||||||
|
toward a cross-harness operating system for agentic work.
|
||||||
|
|
||||||
|
The talk is about the practical problems teams hit after the first AI coding
|
||||||
|
honeymoon: scattered prompts, duplicated setup, weak release gates, fragile
|
||||||
|
security posture, and no clear operating loop across tools.
|
||||||
|
|
||||||
|
I can show how ECC uses reusable skills, hooks, MCP conventions, release gates,
|
||||||
|
AgentShield-style security checks, and an optional Hermes operator shell to make
|
||||||
|
agentic work more measurable and portable.
|
||||||
|
```
|
||||||
|
|
||||||
|
## GitHub Discussion Announcement
|
||||||
|
|
||||||
|
```text
|
||||||
|
ECC v2.0.0-rc.1 preview pack is ready for final release review.
|
||||||
|
|
||||||
|
The main point: ECC 2.0 is the harness-native operator system for agentic work.
|
||||||
|
|
||||||
|
It now has a reviewed public surface for:
|
||||||
|
|
||||||
|
- reusable skills, hooks, rules, and MCP conventions;
|
||||||
|
- Claude Code, Codex, OpenCode, Cursor, Gemini, Zed, GitHub Copilot, and
|
||||||
|
terminal workflows;
|
||||||
|
- Hermes as the optional operator shell;
|
||||||
|
- release, security, queue, discussion, Linear, observability, and video-suite
|
||||||
|
gates.
|
||||||
|
|
||||||
|
The release is still approval-gated until the GitHub prerelease, npm package,
|
||||||
|
plugin paths, final URLs, and billing claims have live evidence.
|
||||||
|
|
||||||
|
Feedback wanted: install friction, cross-harness gaps, partner integrations,
|
||||||
|
sponsor fit, and examples of teams using multiple AI coding harnesses.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Video CTA Hooks
|
||||||
|
|
||||||
|
Use these with the release video suite:
|
||||||
|
|
||||||
|
- "If your AI coding setup only works in one harness, it is not an operating
|
||||||
|
system yet."
|
||||||
|
- "ECC 2.0 is the shared layer: skills, hooks, MCPs, release gates, and team
|
||||||
|
workflows across the tools people actually use."
|
||||||
|
- "OSS stays free. Sponsors, Pro, and implementation work fund the public
|
||||||
|
layer."
|
||||||
|
- "Start with one workflow lane: engineering, research, content, or outreach."
|
||||||
|
|
||||||
|
## Do Not Send Or Publish If
|
||||||
|
|
||||||
|
- The release URL ledger still has stale or placeholder links.
|
||||||
|
- `npm run release:video-suite -- --format json` is not green against the
|
||||||
|
intended video roots.
|
||||||
|
- The GitHub prerelease, npm package, plugin path, or billing claim is described
|
||||||
|
as live without evidence.
|
||||||
|
- The message claims native payments are ready before ECC Tools billing readback
|
||||||
|
passes.
|
||||||
|
- The recipient needs a custom promise that is not covered by `SPONSORS.md`,
|
||||||
|
`SPONSORING.md`, or a separate consulting scope.
|
||||||
|
- The user has not approved outbound sponsor, partner, consulting, or media
|
||||||
|
messages.
|
||||||
|
|
||||||
|
## Routing Links
|
||||||
|
|
||||||
|
- Repo: <https://github.com/affaan-m/ECC>
|
||||||
|
- Release notes: <https://github.com/affaan-m/ECC/blob/main/docs/releases/2.0.0-rc.1/release-notes.md>
|
||||||
|
- Quickstart: <https://github.com/affaan-m/ECC/blob/main/docs/releases/2.0.0-rc.1/quickstart.md>
|
||||||
|
- Sponsor: <https://github.com/sponsors/affaan-m>
|
||||||
|
- Sponsor tiers: <https://github.com/affaan-m/ECC/blob/main/SPONSORS.md>
|
||||||
|
- Sponsoring guide: <https://github.com/affaan-m/ECC/blob/main/SPONSORING.md>
|
||||||
@@ -24,11 +24,16 @@ surfaces, or posting announcements.
|
|||||||
| `docs/releases/2.0.0-rc.1/publication-evidence-2026-05-15.md` | Current May 15 queue, roadmap, security, supply-chain watch, no-lifecycle CI install hardening, AgentShield #86 evidence-pack provenance, ECC Tools billing-gate, Actions cache purge, and `ecc2` test evidence through PR #1941 | Must be superseded by a final clean-checkout evidence file before real publication |
|
| `docs/releases/2.0.0-rc.1/publication-evidence-2026-05-15.md` | Current May 15 queue, roadmap, security, supply-chain watch, no-lifecycle CI install hardening, AgentShield #86 evidence-pack provenance, ECC Tools billing-gate, Actions cache purge, and `ecc2` test evidence through PR #1941 | Must be superseded by a final clean-checkout evidence file before real publication |
|
||||||
| `docs/releases/2.0.0-rc.1/publication-evidence-2026-05-16.md` | Current May 16/17 queue cleanup, recsys skill merge, GateGuard triage, PR #1947 supply-chain protection, AgentShield #87 plugin-cache confidence evidence, AgentShield #88 evidence-pack inspect/readback, AgentShield #89 evidence-pack fleet routing, AgentShield #90 fleet review items, AgentShield #91 policy export, AgentShield #92 policy promotion, ECC-Tools #76 fleet-summary consumption, ECC-Tools #77 hosted finding evidence paths, ECC-Tools #78 harness policy-route linking, dashboard refresh, and combined Node/Rust/release-surface gate evidence through the May 16 mirror | Must still be repeated from a strict clean checkout before real publication |
|
| `docs/releases/2.0.0-rc.1/publication-evidence-2026-05-16.md` | Current May 16/17 queue cleanup, recsys skill merge, GateGuard triage, PR #1947 supply-chain protection, AgentShield #87 plugin-cache confidence evidence, AgentShield #88 evidence-pack inspect/readback, AgentShield #89 evidence-pack fleet routing, AgentShield #90 fleet review items, AgentShield #91 policy export, AgentShield #92 policy promotion, ECC-Tools #76 fleet-summary consumption, ECC-Tools #77 hosted finding evidence paths, ECC-Tools #78 harness policy-route linking, dashboard refresh, and combined Node/Rust/release-surface gate evidence through the May 16 mirror | Must still be repeated from a strict clean checkout before real publication |
|
||||||
| `docs/releases/2.0.0-rc.1/publication-evidence-2026-05-17.md` | May 17 queue-zero state, Japanese localization merge, Dependabot TypeScript and Node type merges, post-merge ja-JP lint repair, Mini Shai-Hulud/TanStack protection recheck, npm audit/signature checks, legacy and Linear progress routing, deterministic preview-pack smoke, operator dashboard refresh, Linear sync, and GitHub CI evidence for `27dc2918` | Superseded by the May 18 evidence snapshot; repeat from a strict clean checkout before real publication |
|
| `docs/releases/2.0.0-rc.1/publication-evidence-2026-05-17.md` | May 17 queue-zero state, Japanese localization merge, Dependabot TypeScript and Node type merges, post-merge ja-JP lint repair, Mini Shai-Hulud/TanStack protection recheck, npm audit/signature checks, legacy and Linear progress routing, deterministic preview-pack smoke, operator dashboard refresh, Linear sync, and GitHub CI evidence for `27dc2918` | Superseded by the May 18 evidence snapshot; repeat from a strict clean checkout before real publication |
|
||||||
| `docs/releases/2.0.0-rc.1/publication-evidence-2026-05-18.md` | Current May 18 queue-zero state, #1970/#1971/#1972 merge batch, #1978 review/closure, current-head Mini Shai-Hulud/TanStack protection recheck, no-lifecycle install, npm audit/signature checks, AgentShield `840952a` enterprise/IOC evidence mirror, work-items sync, Linear sync, operator dashboard refresh, latest current-head CI/security scan success for `4470e2e6`, and ITO-46 naming/plugin publication closure | Current strongest readiness snapshot; must still be repeated from a strict clean checkout before real publication |
|
| `docs/releases/2.0.0-rc.1/publication-evidence-2026-05-18.md` | May 18 queue-zero state, #1970/#1971/#1972 merge batch, #1978 review/closure, supply-chain recheck, AgentShield evidence mirror, Linear sync, current-head CI/security scan success for `4470e2e6`, and ITO-46 naming/plugin publication closure | Superseded by the May 19 ECC identity, video, and growth evidence snapshot |
|
||||||
|
| `docs/releases/2.0.0-rc.1/publication-evidence-2026-05-19.md` | Current May 19 evidence for canonical ECC identity, release video suite, partner/sponsor/talk outreach pack, owner approval packet, May 19 operator dashboard, preview-pack smoke digest `790430aef4a8`, 2550-test local suite, PR #1998 visual QA CI success, PR #1999 dashboard evidence CI success, PR #2000 suite-count evidence success, PR #2001 owner approval packet CI success, PR #2002 owner-approval dashboard gate CI success, PR #2004 Linear readiness evidence sync CI success, and the May 19 Linear sync document | Current strongest readiness snapshot; must still be repeated from a strict clean checkout before real publication |
|
||||||
| `docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-17.md` | Previous prompt-to-artifact operator dashboard | Superseded by the May 18 generated dashboard |
|
| `docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-17.md` | Previous prompt-to-artifact operator dashboard | Superseded by the May 18 generated dashboard |
|
||||||
| `docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-18.md` | Current prompt-to-artifact operator dashboard | Shows PR/issue/discussion/platform/supply-chain gates current and publication, plugin, billing, AgentShield, ECC Tools, legacy, and Linear productization gaps still open |
|
| `docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-18.md` | Previous prompt-to-artifact operator dashboard | Superseded by the May 19 generated dashboard |
|
||||||
| `docs/releases/2.0.0-rc.1/release-url-ledger-2026-05-18.md` | Live URL and approval-gated URL ledger for release copy | Must be regenerated from the final release commit before public announcements |
|
| `docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-19.md` | Current prompt-to-artifact operator dashboard | Shows PR/issue/discussion/platform/supply-chain gates current and adds the current `$1,728/mo` to `$10,000/mo` hypergrowth, video owner-approval, and outbound-pack operating lanes |
|
||||||
| `docs/releases/2.0.0-rc.1/naming-and-publication-matrix.md` | Naming, slug, and publication-path decision record | Keeps `Everything Claude Code / ECC`, npm `ecc-universal`, and plugin slug `ecc` for rc.1 |
|
| `docs/releases/2.0.0-rc.1/owner-approval-packet-2026-05-19.md` | Final human decision sheet for release, package, plugin, video, billing, social, and outbound approvals | Must be reviewed by the owner before any publication or outbound action |
|
||||||
|
| `docs/releases/2.0.0-rc.1/release-url-ledger-2026-05-19.md` | Live URL and approval-gated URL ledger for release copy | Must be regenerated from the final release commit before public announcements |
|
||||||
|
| `docs/releases/2.0.0-rc.1/video-suite-production.md` | Release video production manifest | Gates local media inventory, rough primary render, captions, timeline, self-eval, and no-private-path publication rules |
|
||||||
|
| `docs/releases/2.0.0-rc.1/partner-sponsor-talks-pack.md` | Partner, sponsor, consulting, conference, podcast, and discussion copy | Must stay approval-gated and avoid live billing, release, package, or plugin claims without evidence |
|
||||||
|
| `docs/releases/2.0.0-rc.1/naming-and-publication-matrix.md` | Naming, slug, and publication-path decision record | Keeps `ECC`, npm `ecc-universal`, and plugin slug `ecc` for rc.1 |
|
||||||
| `docs/releases/2.0.0-rc.1/release-name-plugin-publication-checklist-2026-05-18.md` | Release name, package, Claude plugin, Codex plugin, and publication-order checklist | Freezes rc.1 identity and requires final commit evidence before release, npm, plugin, billing, or announcement actions |
|
| `docs/releases/2.0.0-rc.1/release-name-plugin-publication-checklist-2026-05-18.md` | Release name, package, Claude plugin, Codex plugin, and publication-order checklist | Freezes rc.1 identity and requires final commit evidence before release, npm, plugin, billing, or announcement actions |
|
||||||
| `docs/releases/2.0.0-rc.1/x-thread.md` | X launch draft | Must replace placeholders with live URLs after release/package/plugin publication |
|
| `docs/releases/2.0.0-rc.1/x-thread.md` | X launch draft | Must replace placeholders with live URLs after release/package/plugin publication |
|
||||||
| `docs/releases/2.0.0-rc.1/linkedin-post.md` | LinkedIn launch draft | Must replace placeholders with live URLs after release/package/plugin publication |
|
| `docs/releases/2.0.0-rc.1/linkedin-post.md` | LinkedIn launch draft | Must replace placeholders with live URLs after release/package/plugin publication |
|
||||||
@@ -75,6 +80,7 @@ Run these from the exact release commit before publication:
|
|||||||
git status --short --branch
|
git status --short --branch
|
||||||
node scripts/platform-audit.js --json
|
node scripts/platform-audit.js --json
|
||||||
npm run preview-pack:smoke
|
npm run preview-pack:smoke
|
||||||
|
npm run release:video-suite -- --format json
|
||||||
npm run harness:adapters -- --check
|
npm run harness:adapters -- --check
|
||||||
npm run harness:audit -- --format json
|
npm run harness:audit -- --format json
|
||||||
npm run observability:ready
|
npm run observability:ready
|
||||||
|
|||||||
116
docs/releases/2.0.0-rc.1/publication-evidence-2026-05-19.md
Normal file
116
docs/releases/2.0.0-rc.1/publication-evidence-2026-05-19.md
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
# ECC v2.0.0-rc.1 Publication Evidence - 2026-05-19
|
||||||
|
|
||||||
|
This is release-readiness evidence only. It does not create a GitHub release,
|
||||||
|
npm publication, plugin tag, marketplace submission, billing announcement, or
|
||||||
|
social announcement.
|
||||||
|
|
||||||
|
## Source Commit
|
||||||
|
|
||||||
|
| Field | Evidence |
|
||||||
|
| --- | --- |
|
||||||
|
| Upstream main | `ac7434ea8f39166b11e9d06ce64b38c4fb8d9202` |
|
||||||
|
| Git remote | `https://github.com/affaan-m/ECC.git` |
|
||||||
|
| Evidence scope | Current `main` after PR #1990 harness-audit GitHub integration scoring, PR #1991 canonical ECC identity gate, PR #1992 release video-suite gate, PR #1993 growth outreach pack, PR #1994 May 19 publication evidence refresh, PR #1995 operator dashboard refresh, PR #1996 primary render self-eval gate, PR #1997 publish-candidate gate, PR #1998 visual QA gate, PR #1999 video dashboard evidence refresh, PR #2000 suite-count evidence refresh, PR #2001 owner approval packet addition, PR #2002 owner approval dashboard gate refresh, and PR #2004 Linear readiness evidence sync |
|
||||||
|
| Local status caveat | `git status --short --branch` was clean after pulling `origin/main`; generated evidence files are committed after the source snapshot they describe |
|
||||||
|
|
||||||
|
The release operator must repeat all publish-facing checks from the exact final
|
||||||
|
release commit with a strictly clean checkout before publishing.
|
||||||
|
|
||||||
|
## Queue And Discussion State
|
||||||
|
|
||||||
|
| Surface | Command | Result |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Platform audit | `node scripts/platform-audit.js --json` | Ready true; tracked repos report 0 open PRs, 0 open issues, 0 discussion maintainer-touch gaps, 0 answerable Q&A gaps, 0 conflicting PRs, and 0 blocking dirty files |
|
||||||
|
| Trunk PRs | `gh pr list --repo affaan-m/ECC --state open --json number,title,url,author --limit 100` | `[]` |
|
||||||
|
| Trunk issues | `gh issue list --repo affaan-m/ECC --state open --json number,title,url,author --limit 100` | `[]` |
|
||||||
|
| Discussion audit through platform audit | `node scripts/platform-audit.js --json` | `affaan-m/ECC` discussions enabled; 59 sampled after #2003 AURA integration proposal; 0 needing maintainer touch; 0 answerable without accepted answer |
|
||||||
|
| Worktree | `git status --short --branch` | `## main...origin/main` |
|
||||||
|
|
||||||
|
Tracked repositories in the platform audit were:
|
||||||
|
|
||||||
|
- `affaan-m/ECC`
|
||||||
|
- `affaan-m/agentshield`
|
||||||
|
- `affaan-m/JARVIS`
|
||||||
|
- `ECC-Tools/ECC-Tools`
|
||||||
|
- `ECC-Tools/ECC-website`
|
||||||
|
|
||||||
|
## Merge Batch
|
||||||
|
|
||||||
|
| Item | Result |
|
||||||
|
| --- | --- |
|
||||||
|
| PR #1990 | Merged GitHub integration harness-audit scoring and conflict salvage from the earlier unsafe PR lane |
|
||||||
|
| PR #1991 | Merged canonical ECC release identity gate across README, plugin/package metadata, OpenCode surfaces, Marketplace metadata, audit defaults, quickstart, release URL ledger, naming/publication matrix, and release tests |
|
||||||
|
| PR #1992 | Merged the release video-suite gate, production manifest, validator, package file surface, preview-pack smoke wiring, release-surface tests, and compact CI JSON output |
|
||||||
|
| PR #1993 | Merged the partner, sponsor, consulting, conference, podcast, GitHub Discussion, and video CTA pack for the hypergrowth outbound lane |
|
||||||
|
| PR #1994 | Merged the May 19 publication-evidence refresh, platform-audit evidence gate, preview-pack smoke evidence gate, and URL/readiness/roadmap references |
|
||||||
|
| PR #1995 | Merged the May 19 operator dashboard refresh with the `$1,728/mo` MRR baseline, `$10,000/mo` target, and release/video/outbound top actions |
|
||||||
|
| PR #1996 | Merged the primary launch render self-eval gate for duration, size, resolution, video stream, and audio stream checks |
|
||||||
|
| PR #1997 | Merged the publish-candidate gate for the primary launch MP4/captions plus five short clips in wide and vertical formats |
|
||||||
|
| PR #1998 | Merged the release video visual QA gate for publish candidates and black-frame segment detection |
|
||||||
|
| PR #1999 | Merged the operator dashboard refresh that moved the release video suite to current once publish-candidate evidence was recorded |
|
||||||
|
| PR #2000 | Merged the suite-count evidence refresh so the platform audit rejects stale local-suite totals |
|
||||||
|
| PR #2001 | Merged the final human decision sheet for release, package, plugin, video, billing, social, and outbound approvals; GitHub Actions run `26102500291` completed successfully |
|
||||||
|
| PR #2002 | Merged the owner-approval dashboard refresh so the operator dashboard fails closed when the final decision sheet is missing or incomplete; CI passed before merge |
|
||||||
|
| PR #2004 | Merged the May 19 Linear readiness evidence sync after PR #2002, including roadmap, dashboard, preview-pack manifest, publication evidence, operator dashboard generator, and release-surface test updates |
|
||||||
|
|
||||||
|
## Release And Growth Evidence
|
||||||
|
|
||||||
|
| Gate | Command | Result |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Release-surface tests | `node tests/docs/ecc2-release-surface.test.js` | 27 passed, 0 failed |
|
||||||
|
| Preview-pack smoke | `npm run preview-pack:smoke -- --format json` | Ready true; digest `790430aef4a8`; 31 required artifacts; 5 passed, 0 failed |
|
||||||
|
| Operator dashboard | `npm run operator:dashboard -- --write docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-19.md` | Regenerated from `ac7434ea8f39166b11e9d06ce64b38c4fb8d9202` with platform audit ready true, 0 tracked PRs, 0 tracked issues, 0 discussion gaps, `$1,728/mo` current MRR, `$10,000/mo` target MRR, the release video suite marked current, and top actions for plugin publication, notifications, outbound approval, AgentShield, and ECC Tools billing |
|
||||||
|
| Release video suite | `npm run release:video-suite -- --format json --summary` with `ECC_VIDEO_SOURCE_ROOT` and `ECC_VIDEO_RELEASE_SUITE_ROOT` | Ready true; 15/15 source assets present; 13/13 render, timeline, caption, EDL, and segment artifacts present; 12/12 publish-candidate outputs present with zero detected black-frame segments; primary rough render self-eval passed at 144.759 seconds, 1920x1080, 1 audio stream, and 106.78 MB |
|
||||||
|
| Full local suite | `node tests/run-all.js` | 2550 passed, 0 failed |
|
||||||
|
| PR #1998 CI | GitHub Actions run `26099020341` | Completed successfully for `d500de1e9f11c0446b6a1349bd98b522d31f9125`; all reported checks passed, including lint, validation, security scan, coverage, GitGuardian, CodeRabbit, Cubic, and the macOS/Ubuntu/Windows test matrix |
|
||||||
|
| PR #1999 CI | GitHub Actions run `26100148726` | Completed successfully for `90584b6d5e5814bc2ad9a4cd651bebd043de989d`; lint, validation, security scan, coverage, GitGuardian, CodeRabbit, and the macOS/Ubuntu/Windows test matrix passed; Cubic completed neutral and did not block merge |
|
||||||
|
| PR #2001 CI | GitHub Actions run `26102500291` | Completed successfully for `8148340ad14eb32c971346f0cb4cb9431ec0f5de`; required checks passed before merge |
|
||||||
|
| PR #2002 CI | GitHub Actions run `26103853507` | Completed successfully before merge; required checks passed, Cubic remained non-blocking, and PR #2002 merged into `main` as `c7d662c3c68719e5ef0b5305ca3f6782b3214224` |
|
||||||
|
| PR #2004 CI | GitHub Actions run `26105012698` | Completed successfully after rerunning the single failed Windows Node 18 yarn job; required checks passed, Cubic remained non-blocking, and PR #2004 merged into `main` as `ac7434ea8f39166b11e9d06ce64b38c4fb8d9202` |
|
||||||
|
| Linear sync | Linear document `ecc-may-19-post-pr-2002-sync-64cef8f668e0` plus project comment `a6411e3a-8c8e-4a58-adba-687e77d4c543` | Project and issue lanes now record PR #2002 evidence, discussion #2003 routing, owner-approval dashboard gate, and In Progress status for ITO-47, ITO-48, ITO-49, ITO-51, ITO-54, and ITO-56 |
|
||||||
|
| Public-path sanitization | `node scripts/ci/validate-no-personal-paths.js` through local suite and CI | Passed |
|
||||||
|
| Markdown and whitespace | `markdownlint` focused release docs plus `git diff --check` before PR #1999 | Passed |
|
||||||
|
|
||||||
|
## Product And Positioning Evidence
|
||||||
|
|
||||||
|
| Surface | Evidence |
|
||||||
|
| --- | --- |
|
||||||
|
| Canonical repo identity | Public URLs and release docs now use `https://github.com/affaan-m/ECC` where public links are needed |
|
||||||
|
| Release claim | Release notes and launch collateral frame ECC as the harness-native operator system for agentic work, not a Claude-only config pack |
|
||||||
|
| Video proof | `video-suite-production.md` gates the local rough render, timeline, captions, source inventory, publish-candidate clip set, self-eval, black-frame QA, and no-private-path publication rules |
|
||||||
|
| Growth proof | `partner-sponsor-talks-pack.md` provides approval-gated copy for sponsors, partners, consulting, talks, podcasts, GitHub Discussion, and video CTAs |
|
||||||
|
| Owner approval proof | `owner-approval-packet-2026-05-19.md` centralizes release, package, plugin, video, billing, social, and outbound decision gates |
|
||||||
|
| Business baseline | Hypergrowth command center and partner pack use `$1,728/mo` current MRR, `$10,000/mo` target MRR, and `$8,272/mo` gap |
|
||||||
|
| Operator dashboard | `operator-readiness-dashboard-2026-05-19.md` pulls the growth baseline into the same queue, publication, video, outbound, AgentShield, ECC Tools, Linear, and supply-chain control surface |
|
||||||
|
| Linear progress proof | Linear project document `ecc-may-19-post-pr-2002-sync-64cef8f668e0` mirrors the post-PR #2002 state and records active lanes for launch materials, AgentShield, ECC Tools deep analysis, observability, and final release publication |
|
||||||
|
|
||||||
|
## Current Publication Blockers
|
||||||
|
|
||||||
|
- GitHub prerelease `v2.0.0-rc.1` is still not created in this pass.
|
||||||
|
- npm `ecc-universal@2.0.0-rc.1` is still not published to the `next`
|
||||||
|
dist-tag.
|
||||||
|
- Claude plugin tag and marketplace propagation remain approval-gated.
|
||||||
|
- Codex repo-marketplace distribution is verified by prior evidence, but
|
||||||
|
official Plugin Directory publishing remains blocked on OpenAI submission or
|
||||||
|
listing evidence.
|
||||||
|
- ECC Tools billing/native-payments copy remains blocked until a Marketplace
|
||||||
|
Pro purchase/webhook path writes ready production billing state for a target
|
||||||
|
Marketplace test account and the billing announcement gate passes.
|
||||||
|
- Release notes, X, LinkedIn, GitHub release, GitHub Discussion, longform copy,
|
||||||
|
sponsor outreach, partner outreach, consulting copy, conference pitches, and
|
||||||
|
podcast pitches still need final live URLs plus human approval before posting
|
||||||
|
or sending.
|
||||||
|
- Discord/community links still need a real invite or bot/guild credential path
|
||||||
|
before public docs should route users there.
|
||||||
|
|
||||||
|
## Result
|
||||||
|
|
||||||
|
The tracked public PR queue, issue queue, discussion queue, canonical ECC
|
||||||
|
identity, release video suite, preview pack, and growth outreach packet are
|
||||||
|
current on May 19, 2026 for `main` through
|
||||||
|
`ac7434ea8f39166b11e9d06ce64b38c4fb8d9202`. The remaining video work is
|
||||||
|
owner approval, upload, and public URL attachment, not render or QA production.
|
||||||
|
|
||||||
|
This improves publication readiness but does not replace the approval-gated
|
||||||
|
release, package, plugin, billing, Discord, and announcement steps in
|
||||||
|
`publication-readiness.md`.
|
||||||
@@ -45,8 +45,9 @@ AgentShield project scan, AgentShield `840952a` enterprise/IOC evidence mirror,
|
|||||||
release OIDC publishing-scope hardening, workflow normalization, later
|
release OIDC publishing-scope hardening, workflow normalization, later
|
||||||
dashboard/publication-readiness refreshes through `67e63e63`, work-items sync,
|
dashboard/publication-readiness refreshes through `67e63e63`, work-items sync,
|
||||||
Linear progress comments, ITO-46 closure, operator dashboard refresh, and
|
Linear progress comments, ITO-46 closure, operator dashboard refresh, and
|
||||||
current-head CI/security scan success for `4470e2e6`, see
|
current-head CI/security scan success through the May 19 identity, video, and
|
||||||
[`publication-evidence-2026-05-18.md`](publication-evidence-2026-05-18.md).
|
growth-pack merge batch, see
|
||||||
|
[`publication-evidence-2026-05-19.md`](publication-evidence-2026-05-19.md).
|
||||||
For the operator-facing prompt-to-artifact readiness dashboard from the same
|
For the operator-facing prompt-to-artifact readiness dashboard from the same
|
||||||
May 16 pass, see
|
May 16 pass, see
|
||||||
[`operator-readiness-dashboard-2026-05-15.md`](operator-readiness-dashboard-2026-05-15.md).
|
[`operator-readiness-dashboard-2026-05-15.md`](operator-readiness-dashboard-2026-05-15.md).
|
||||||
@@ -54,16 +55,22 @@ For the May 17 operator dashboard refresh, see
|
|||||||
[`operator-readiness-dashboard-2026-05-17.md`](operator-readiness-dashboard-2026-05-17.md).
|
[`operator-readiness-dashboard-2026-05-17.md`](operator-readiness-dashboard-2026-05-17.md).
|
||||||
For the May 18 operator dashboard refresh, see
|
For the May 18 operator dashboard refresh, see
|
||||||
[`operator-readiness-dashboard-2026-05-18.md`](operator-readiness-dashboard-2026-05-18.md).
|
[`operator-readiness-dashboard-2026-05-18.md`](operator-readiness-dashboard-2026-05-18.md).
|
||||||
For the May 18 live/pending release URL ledger, see
|
|
||||||
[`release-url-ledger-2026-05-18.md`](release-url-ledger-2026-05-18.md).
|
The current May 19 hypergrowth/operator dashboard is
|
||||||
|
[`operator-readiness-dashboard-2026-05-19.md`](operator-readiness-dashboard-2026-05-19.md).
|
||||||
|
For the final owner decision sheet across release, npm, plugin, video, billing,
|
||||||
|
social, and outbound approvals, see
|
||||||
|
[`owner-approval-packet-2026-05-19.md`](owner-approval-packet-2026-05-19.md).
|
||||||
|
For the May 19 live/pending release URL ledger after the public repo rename, see
|
||||||
|
[`release-url-ledger-2026-05-19.md`](release-url-ledger-2026-05-19.md).
|
||||||
|
|
||||||
## Release Identity Matrix
|
## Release Identity Matrix
|
||||||
|
|
||||||
| Surface | Expected value | Source of truth | Fresh check | Evidence artifact | Owner | Status |
|
| Surface | Expected value | Source of truth | Fresh check | Evidence artifact | Owner | Status |
|
||||||
| --- | --- | --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- | --- | --- |
|
||||||
| Product name | Everything Claude Code / ECC | `README.md`, `CHANGELOG.md`, release notes | `rg -n "Everything Claude Code" README.md CHANGELOG.md docs/releases/2.0.0-rc.1` | `publication-evidence-2026-05-12.md` | Release owner | Evidence recorded |
|
| Product name | ECC | `README.md`, plugin manifests, release notes | `rg -n "^# ECC\|displayName.*ECC\|affaan-m/ECC" README.md .codex-plugin/plugin.json docs/releases/2.0.0-rc.1` | `release-name-plugin-publication-checklist-2026-05-18.md` plus `release-url-ledger-2026-05-19.md` | Release owner | Evidence recorded |
|
||||||
| GitHub repo | `affaan-m/everything-claude-code` | Git remote and release URLs | `git remote get-url origin` | `publication-evidence-2026-05-12.md` | Release owner | Evidence recorded |
|
| GitHub repo | `affaan-m/ECC` | Git remote and release URLs | `git remote get-url origin` | `release-url-ledger-2026-05-19.md` | Release owner | Evidence recorded |
|
||||||
| Git tag | `v2.0.0-rc.1` | GitHub releases | `gh release view v2.0.0-rc.1 --repo affaan-m/everything-claude-code` | `release not found` | Release owner | Blocked until release approval |
|
| Git tag | `v2.0.0-rc.1` | GitHub releases | `gh release view v2.0.0-rc.1 --repo affaan-m/ECC` | `release not found` | Release owner | Blocked until release approval |
|
||||||
| npm package | `ecc-universal` | `package.json` | `node -p "require('./package.json').name"` | `publication-evidence-2026-05-12.md` | Package owner | Evidence recorded |
|
| npm package | `ecc-universal` | `package.json` | `node -p "require('./package.json').name"` | `publication-evidence-2026-05-12.md` | Package owner | Evidence recorded |
|
||||||
| npm version | `2.0.0-rc.1` | `VERSION`, `package.json`, lockfiles | `node -p "require('./package.json').version"` | `publication-evidence-2026-05-12.md` | Package owner | Evidence recorded |
|
| npm version | `2.0.0-rc.1` | `VERSION`, `package.json`, lockfiles | `node -p "require('./package.json').version"` | `publication-evidence-2026-05-12.md` | Package owner | Evidence recorded |
|
||||||
| npm dist-tag | `next` for rc, `latest` only for GA | npm registry | `npm view ecc-universal dist-tags --json` | Current registry only has `latest: 1.10.0`; `next` is pending publish | Package owner | Blocked until publish approval |
|
| npm dist-tag | `next` for rc, `latest` only for GA | npm registry | `npm view ecc-universal dist-tags --json` | Current registry only has `latest: 1.10.0`; `next` is pending publish | Package owner | Blocked until publish approval |
|
||||||
@@ -85,7 +92,7 @@ For the May 18 live/pending release URL ledger, see
|
|||||||
| Codex plugin | Manifest version matches package and docs, repo marketplace points at the plugin root, and OpenAI's current official Plugin Directory status is recorded | `node tests/docs/ecc2-release-surface.test.js`; `node tests/plugin-manifest.test.js`; `codex plugin marketplace add --help`; temp-home `codex plugin marketplace add <local-checkout>` | `Blocker: official Plugin Directory listing requires OpenAI submission/listing evidence` | Plugin owner | Repo-marketplace distribution verified; official directory pending |
|
| Codex plugin | Manifest version matches package and docs, repo marketplace points at the plugin root, and OpenAI's current official Plugin Directory status is recorded | `node tests/docs/ecc2-release-surface.test.js`; `node tests/plugin-manifest.test.js`; `codex plugin marketplace add --help`; temp-home `codex plugin marketplace add <local-checkout>` | `Blocker: official Plugin Directory listing requires OpenAI submission/listing evidence` | Plugin owner | Repo-marketplace distribution verified; official directory pending |
|
||||||
| OpenCode package | Build output is regenerated from source and package metadata is current | `npm run build:opencode` | `Blocker: none for local build; public distribution still follows npm/plugin release` | Package owner | Evidence recorded |
|
| OpenCode package | Build output is regenerated from source and package metadata is current | `npm run build:opencode` | `Blocker: none for local build; public distribution still follows npm/plugin release` | Package owner | Evidence recorded |
|
||||||
| ECC Tools billing reference | Any billing claim links to verified Marketplace/App state | `env -u GITHUB_TOKEN gh repo view ECC-Tools/ECC-Tools --json nameWithOwner,isPrivate,viewerPermission` plus internal `/api/billing/readiness?accountLogin=<marketplace-test-account>` readback | `Blocker: ECC-Tools #73 added announcementGate; live Marketplace test-account readback must return announcementGate.ready === true before payment announcement` | ECC Tools owner | Code gate recorded; live billing readback pending |
|
| ECC Tools billing reference | Any billing claim links to verified Marketplace/App state | `env -u GITHUB_TOKEN gh repo view ECC-Tools/ECC-Tools --json nameWithOwner,isPrivate,viewerPermission` plus internal `/api/billing/readiness?accountLogin=<marketplace-test-account>` readback | `Blocker: ECC-Tools #73 added announcementGate; live Marketplace test-account readback must return announcementGate.ready === true before payment announcement` | ECC Tools owner | Code gate recorded; live billing readback pending |
|
||||||
| Announcement copy | X, LinkedIn, GitHub release, and longform copy point to live URLs | placeholder-marker scan and `release-url-ledger-2026-05-18.md` | `Blocker: final live release/npm/plugin/billing URLs do not exist yet; live and pending URLs are separated in the May 18 ledger` | Release owner | URL ledger recorded; final URLs pending |
|
| Announcement copy | X, LinkedIn, GitHub release, and longform copy point to live URLs | placeholder-marker scan and `release-url-ledger-2026-05-19.md` | `Blocker: final live release/npm/plugin/billing URLs do not exist yet; live and pending URLs are separated in the May 19 ledger` | Release owner | URL ledger recorded; final URLs pending |
|
||||||
| Privileged workflow hardening | Release and maintenance workflows avoid persisted checkout tokens | `node scripts/ci/validate-workflow-security.js` | `Blocker:` | Release owner | Evidence recorded in post-hardening refresh |
|
| Privileged workflow hardening | Release and maintenance workflows avoid persisted checkout tokens | `node scripts/ci/validate-workflow-security.js` | `Blocker:` | Release owner | Evidence recorded in post-hardening refresh |
|
||||||
|
|
||||||
## Required Command Evidence
|
## Required Command Evidence
|
||||||
@@ -94,24 +101,24 @@ Record the exact commit SHA and command output before any publication action:
|
|||||||
|
|
||||||
| Evidence | Command | Required result | Recorded output |
|
| Evidence | Command | Required result | Recorded output |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| Clean release branch | `git status --short --branch` | On intended release commit; no unrelated files | `4470e2e6`: `## main...origin/main`; repeat from the exact final publication commit before release |
|
| Clean release branch | `git status --short --branch` | On intended release commit; no unrelated files | `3304848b`: `## main...origin/main`; repeat from the exact final publication commit before release |
|
||||||
| Preview-pack smoke | `npm run preview-pack:smoke` | Preview pack artifacts, Hermes boundary, final verification command list, and publication blockers pass | `publication-evidence-2026-05-18.md`: ready yes, digest `0ed831dbd0cf`, 5 passed, 0 failed; repeat in the final strict clean-checkout release pass |
|
| Preview-pack smoke | `npm run preview-pack:smoke` | Preview pack artifacts, Hermes boundary, final verification command list, and publication blockers pass | `publication-evidence-2026-05-19.md`: ready yes, digest `790430aef4a8`, 31 artifacts, 5 passed, 0 failed; repeat in the final strict clean-checkout release pass |
|
||||||
| Harness audit | `npm run harness:audit -- --format json` | 70/70 passing | `99e01ded`: 70/70, 0 top actions |
|
| Harness audit | `npm run harness:audit -- --format json` | 70/70 passing | `99e01ded`: 70/70, 0 top actions |
|
||||||
| Adapter scorecard | `npm run harness:adapters -- --check` | PASS | `99e01ded`: PASS, 11 adapters |
|
| Adapter scorecard | `npm run harness:adapters -- --check` | PASS | `99e01ded`: PASS, 11 adapters |
|
||||||
| Observability readiness | `npm run observability:ready` | 21/21 passing | `publication-evidence-2026-05-18.md`: 21/21, ready yes |
|
| Observability readiness | `npm run observability:ready` | 21/21 passing | `publication-evidence-2026-05-18.md`: 21/21, ready yes |
|
||||||
| Release safety gate | `npm run observability:ready -- --format json` | Release Safety category passing with publication readiness, supply-chain, workflow security, package surface, and release-surface evidence | May 18 evidence keeps release safety passing; repeat the JSON gate from the exact final release commit |
|
| Release safety gate | `npm run observability:ready -- --format json` | Release Safety category passing with publication readiness, supply-chain, workflow security, package surface, and release-surface evidence | May 18 evidence keeps release safety passing; repeat the JSON gate from the exact final release commit |
|
||||||
| Supply-chain verification | `npm audit --json`; `npm audit signatures`; `cd ecc2 && cargo audit -q`; Dependabot alerts; GitGuardian Security Checks | 0 vulnerabilities/alerts, registry signatures verified, GitGuardian clean | `publication-evidence-2026-05-18.md` plus CI `26057806361`: npm registry signatures and attestations verified in the evidence pass, 0 high-or-higher npm vulnerabilities, repo/home IOC scans clean, supply-chain IOC scan passed |
|
| Supply-chain verification | `npm audit --json`; `npm audit signatures`; `cd ecc2 && cargo audit -q`; Dependabot alerts; GitGuardian Security Checks | 0 vulnerabilities/alerts, registry signatures verified, GitGuardian clean | `publication-evidence-2026-05-19.md` plus CI `26093792219`: GitGuardian and security scan passed; prior May 18 npm registry signatures and IOC scans remain the latest detailed supply-chain evidence |
|
||||||
| Root suite | `node tests/run-all.js` | 0 failures | `99e01ded`: local `node tests/run-all.js` passed 2512/2512; current-head CI `26057806361` passed the full OS/runtime/package-manager matrix for `4470e2e6` |
|
| Root suite | `node tests/run-all.js` | 0 failures | Current dashboard branch: local `node tests/run-all.js` passed 2550/2550; PR #2001 CI `26102500291` passed the previous full OS/runtime/package-manager matrix |
|
||||||
| Markdown lint | `npx markdownlint-cli '**/*.md' --ignore node_modules` | 0 failures | CI `26057806361`: markdownlint passed on current head; rerun after any release-copy edits |
|
| Markdown lint | `npx markdownlint-cli '**/*.md' --ignore node_modules` | 0 failures | CI `26093792219`: markdownlint passed on the growth-pack PR; rerun after any release-copy edits |
|
||||||
| Package surface | `node tests/scripts/npm-publish-surface.test.js` | 0 failures; no Python bytecode in npm tarball | `2/2` passed in May 12 evidence pass |
|
| Package surface | `node tests/scripts/npm-publish-surface.test.js` | 0 failures; no Python bytecode in npm tarball | `2/2` passed in May 12 evidence pass |
|
||||||
| Release surface | `node tests/docs/ecc2-release-surface.test.js` | 0 failures | May 18 evidence refresh: 21/21 passed after public-path sanitization, during the `0f1775e3` operator-readiness refresh, and again in the ITO-46 dry-run pass before `4470e2e6` |
|
| Release surface | `node tests/docs/ecc2-release-surface.test.js` | 0 failures | May 19 evidence refresh: 27/27 passed after adding the video suite, partner/sponsor/talk gates, owner approval packet, and roadmap evidence mirror |
|
||||||
| Optional Rust surface | `cd ecc2 && cargo test` | 0 failures or explicit deferral | `publication-evidence-2026-05-16.md`: 462/462 passed, existing warnings only |
|
| Optional Rust surface | `cd ecc2 && cargo test` | 0 failures or explicit deferral | `publication-evidence-2026-05-16.md`: 462/462 passed, existing warnings only |
|
||||||
| Queue baseline | `node scripts/platform-audit.js --json` across trunk, AgentShield, JARVIS, ECC Tools, and ECC website | Under 20 open PRs and under 20 open issues | `4470e2e6`: platform audit ready, 0 open PRs, 0 open issues, 0 conflicting PRs, and 0 blocking dirty files in the regenerated dashboard snapshot |
|
| Queue baseline | `node scripts/platform-audit.js --json` across trunk, AgentShield, JARVIS, ECC Tools, and ECC website | Under 20 open PRs and under 20 open issues | `3304848b`: platform audit ready, 0 open PRs, 0 open issues, 0 conflicting PRs, and 0 blocking dirty files |
|
||||||
| Discussion baseline | `node scripts/platform-audit.js --json` and `node scripts/discussion-audit.js --json` | No unmanaged active discussion queue and no answerable Q&A missing an accepted answer | `4470e2e6`: platform audit sampled 58 trunk discussions, 0 needing maintainer touch, 0 answerable discussions missing accepted answer; `docs/architecture/discussion-response-playbook.md` records response templates and security escalation rules |
|
| Discussion baseline | `node scripts/platform-audit.js --json` and `node scripts/discussion-audit.js --json` | No unmanaged active discussion queue and no answerable Q&A missing an accepted answer | `3304848b`: platform audit sampled 58 trunk discussions, 0 needing maintainer touch, 0 answerable discussions missing accepted answer; `docs/architecture/discussion-response-playbook.md` records response templates and security escalation rules |
|
||||||
| Linear roadmap | Linear project and issue readback | Detailed roadmap exists with release, security, AgentShield, ECC Tools, legacy, and observability lanes | May 18 Linear comments include ITO-57 `3fe5b2b7-c4fe-401c-a317-b40d72119cb3` and ITO-44 `fb4a4f33-6c2d-421a-bbdb-63cfad3e3ee4`; earlier evidence records the project and 16 issue lanes |
|
| Linear roadmap | Linear project and issue readback | Detailed roadmap exists with release, security, AgentShield, ECC Tools, legacy, and observability lanes | May 18 Linear comments include ITO-57 `3fe5b2b7-c4fe-401c-a317-b40d72119cb3` and ITO-44 `fb4a4f33-6c2d-421a-bbdb-63cfad3e3ee4`; earlier evidence records the project and 16 issue lanes |
|
||||||
| Operator readiness dashboard | `npm run operator:dashboard -- --json` | Current queue state mapped to macro-goal deliverables and incomplete gaps | `4470e2e6`: regenerated May 18 dashboard from current main; platform audit ready true, 0 open PRs, 0 open issues, 0 discussion gaps, 0 dirty files, and publication gates still approval-gated |
|
| Operator readiness dashboard | `npm run operator:dashboard -- --json` | Current queue state mapped to macro-goal deliverables and incomplete gaps | `3304848b`: regenerated May 19 dashboard from current main; platform audit ready true, 0 open PRs, 0 open issues, 0 discussion gaps, 0 dirty files, release video suite current, and publication gates still approval-gated |
|
||||||
| Release URL ledger | `docs/releases/2.0.0-rc.1/release-url-ledger-2026-05-18.md` plus placeholder-marker scan | Live links and approval-gated links are separated before announcement copy is posted | Ledger records public repo/docs/CI/supply-chain/npm/OpenAI Codex documentation URLs and blocks GitHub release/npm/plugin/billing/social URLs until approval-gated checks pass |
|
| Release URL ledger | `docs/releases/2.0.0-rc.1/release-url-ledger-2026-05-19.md` plus placeholder-marker scan | Live links and approval-gated links are separated before announcement copy is posted | Ledger records public repo/docs/npm/OpenAI Codex documentation URLs and blocks GitHub release/npm/plugin/billing/social URLs until approval-gated checks pass |
|
||||||
| Release name and plugin publication checklist | `docs/releases/2.0.0-rc.1/release-name-plugin-publication-checklist-2026-05-18.md` | Name/package/plugin values are frozen, final-release commands are listed, and Claude/Codex publication paths cite current official docs | Checklist keeps `Everything Claude Code / ECC`, `ecc-universal`, and plugin slug `ecc` for rc.1; no rename, npm publish, plugin tag, official listing, billing claim, or announcement before final evidence |
|
| Release name and plugin publication checklist | `docs/releases/2.0.0-rc.1/release-name-plugin-publication-checklist-2026-05-18.md` | Name/package/plugin values are frozen, final-release commands are listed, and Claude/Codex publication paths cite current official docs | Checklist keeps `ECC`, `ecc-universal`, and plugin slug `ecc` for rc.1; no npm rename, npm publish, plugin tag, official listing, billing claim, or announcement before final evidence |
|
||||||
|
|
||||||
## Do Not Publish If
|
## Do Not Publish If
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ This path is for a new contributor who wants to verify the release surface befor
|
|||||||
## Clone
|
## Clone
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone https://github.com/affaan-m/everything-claude-code.git
|
git clone https://github.com/affaan-m/ECC.git
|
||||||
cd everything-claude-code
|
cd ECC
|
||||||
```
|
```
|
||||||
|
|
||||||
Start from a clean checkout. Do not copy private operator state, raw workspace exports, tokens, or local Hermes files into the repo.
|
Start from a clean checkout. Do not copy private operator state, raw workspace exports, tokens, or local Hermes files into the repo.
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# ECC v2.0.0-rc.1 Release Name And Plugin Publication Checklist
|
# ECC v2.0.0-rc.1 Release Name And Plugin Publication Checklist
|
||||||
|
|
||||||
Snapshot date: 2026-05-18.
|
Snapshot date: 2026-05-18. Canonical repo decision refreshed 2026-05-19
|
||||||
|
after the public repo rename to `affaan-m/ECC`.
|
||||||
|
|
||||||
This checklist is the operator gate for release naming, package publication,
|
This checklist is the operator gate for release naming, package publication,
|
||||||
and Claude/Codex plugin distribution. It is not a publication action by itself.
|
and Claude/Codex plugin distribution. It is not a publication action by itself.
|
||||||
@@ -9,20 +10,22 @@ submitting marketplace forms, or posting announcements.
|
|||||||
|
|
||||||
## Fixed rc.1 Decision
|
## Fixed rc.1 Decision
|
||||||
|
|
||||||
Ship `v2.0.0-rc.1` as **Everything Claude Code (ECC)**.
|
Ship `v2.0.0-rc.1` as **ECC**.
|
||||||
|
|
||||||
- Keep the GitHub repo at `affaan-m/everything-claude-code`.
|
- Keep the GitHub repo at `affaan-m/ECC`.
|
||||||
- Keep the npm package as `ecc-universal`.
|
- Keep the npm package as `ecc-universal`.
|
||||||
- Keep Claude and Codex plugin slugs as `ecc`.
|
- Keep Claude and Codex plugin slugs as `ecc`.
|
||||||
- Publish the npm prerelease on the `next` dist-tag, not `latest`.
|
- Publish the npm prerelease on the `next` dist-tag, not `latest`.
|
||||||
- Do not rename to `affaan-m/ecc`, `ecc`, or `@affaan-m/ecc` before rc.1.
|
- Do not rename the npm package to `ecc` or `@affaan-m/ecc` before rc.1.
|
||||||
|
- Treat `affaan-m/ECC` as the canonical public repo for rc.1 and GA release
|
||||||
|
copy.
|
||||||
|
|
||||||
Reasons:
|
Reasons:
|
||||||
|
|
||||||
- `ecc-universal` is the current working install and package surface.
|
- `ecc-universal` is the current working install and package surface.
|
||||||
- `ecc` on npm is occupied by an unrelated elliptic-curve package.
|
- `ecc` on npm is occupied by an unrelated elliptic-curve package.
|
||||||
- `@affaan-m/ecc` is unclaimed on npm, but would require a migration plan.
|
- `@affaan-m/ecc` is unclaimed on npm, but would require a migration plan.
|
||||||
- `affaan-m/ecc` is not available to the current GitHub auth context.
|
- `affaan-m/ECC` is now the live public GitHub repo.
|
||||||
- Claude and Codex already expose the desired short namespace as `ecc`.
|
- Claude and Codex already expose the desired short namespace as `ecc`.
|
||||||
|
|
||||||
## Current Surface Evidence
|
## Current Surface Evidence
|
||||||
@@ -30,8 +33,7 @@ Reasons:
|
|||||||
| Surface | Current value | Evidence command | 2026-05-18 result | Release action |
|
| Surface | Current value | Evidence command | 2026-05-18 result | Release action |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| Git commit | `67e63e63f9bfd074bd6a21bf6bac71f3dfefa58b` | `git rev-parse HEAD` | Recorded from clean `main` before this ITO-46 evidence refresh | Re-run from final release commit |
|
| Git commit | `67e63e63f9bfd074bd6a21bf6bac71f3dfefa58b` | `git rev-parse HEAD` | Recorded from clean `main` before this ITO-46 evidence refresh | Re-run from final release commit |
|
||||||
| GitHub repo | `affaan-m/everything-claude-code` | `git remote get-url origin` | `https://github.com/affaan-m/everything-claude-code.git` | Keep for rc.1 |
|
| GitHub repo | `affaan-m/ECC` | `git remote get-url origin` | `https://github.com/affaan-m/ECC.git` | Keep for rc.1 and GA |
|
||||||
| Possible short repo | `affaan-m/ecc` | `gh repo view affaan-m/ecc --json nameWithOwner,url,isPrivate` | GraphQL could not resolve repository | Do not depend on it for rc.1 |
|
|
||||||
| npm package | `ecc-universal@2.0.0-rc.1` local, `1.10.0` registry latest | `node -p "require('./package.json').name + '@' + require('./package.json').version"` and `npm view ecc-universal name version dist-tags --json` | Local rc.1 ready; registry still latest `1.10.0` | Publish rc.1 with `--tag next` after approval |
|
| npm package | `ecc-universal@2.0.0-rc.1` local, `1.10.0` registry latest | `node -p "require('./package.json').name + '@' + require('./package.json').version"` and `npm view ecc-universal name version dist-tags --json` | Local rc.1 ready; registry still latest `1.10.0` | Publish rc.1 with `--tag next` after approval |
|
||||||
| Exact npm short name | `ecc` | `npm view ecc name version description repository.url --json` | Occupied by unrelated `ecc@0.0.2` | Do not use |
|
| Exact npm short name | `ecc` | `npm view ecc name version description repository.url --json` | Occupied by unrelated `ecc@0.0.2` | Do not use |
|
||||||
| Scoped npm short name | `@affaan-m/ecc` | `npm view @affaan-m/ecc name version --json` | 404 | Candidate only after migration plan |
|
| Scoped npm short name | `@affaan-m/ecc` | `npm view @affaan-m/ecc name version --json` | 404 | Candidate only after migration plan |
|
||||||
@@ -59,7 +61,7 @@ claude plugin validate .claude-plugin/plugin.json
|
|||||||
claude plugin tag .claude-plugin --dry-run
|
claude plugin tag .claude-plugin --dry-run
|
||||||
codex plugin marketplace add --help
|
codex plugin marketplace add --help
|
||||||
HOME="$(mktemp -d)" codex plugin marketplace add ./
|
HOME="$(mktemp -d)" codex plugin marketplace add ./
|
||||||
HOME="$(mktemp -d)" codex plugin marketplace add affaan-m/everything-claude-code --ref "$(git rev-parse HEAD)"
|
HOME="$(mktemp -d)" codex plugin marketplace add affaan-m/ECC --ref "$(git rev-parse HEAD)"
|
||||||
npm pack --dry-run --json
|
npm pack --dry-run --json
|
||||||
npm publish --tag next --dry-run
|
npm publish --tag next --dry-run
|
||||||
npm run build:opencode
|
npm run build:opencode
|
||||||
@@ -96,8 +98,8 @@ keep the related publication action blocked.
|
|||||||
documents a public submission path or confirms the plugin has been listed.
|
documents a public submission path or confirms the plugin has been listed.
|
||||||
- Do not announce billing, Marketplace, or native payments until ECC Tools live
|
- Do not announce billing, Marketplace, or native payments until ECC Tools live
|
||||||
Marketplace account readback returns ready.
|
Marketplace account readback returns ready.
|
||||||
- Do not rename the repo or package until rc.1 is published and a migration
|
- Do not rename the npm package until rc.1 is published and a migration guide
|
||||||
guide maps old names to new names.
|
maps old install names to new names.
|
||||||
- Do not post social copy while any release, npm, plugin, or billing URL is
|
- Do not post social copy while any release, npm, plugin, or billing URL is
|
||||||
still approval-gated.
|
still approval-gated.
|
||||||
|
|
||||||
|
|||||||
@@ -46,8 +46,8 @@ feature branch:
|
|||||||
- documentation expansion, Japanese localization, zh-CN to ja-JP parity
|
- documentation expansion, Japanese localization, zh-CN to ja-JP parity
|
||||||
repair, and dependency readiness through TypeScript 6 and Node type updates;
|
repair, and dependency readiness through TypeScript 6 and Node type updates;
|
||||||
- launch collateral for GitHub release copy, X, LinkedIn, article outline,
|
- launch collateral for GitHub release copy, X, LinkedIn, article outline,
|
||||||
Telegram/Hermes handoff, demo prompts, and the approval-gated launch
|
Telegram/Hermes handoff, demo prompts, partner/sponsor/talk outreach, and
|
||||||
checklist.
|
the approval-gated launch checklist.
|
||||||
- a release URL ledger that separates links which already resolve from links
|
- a release URL ledger that separates links which already resolve from links
|
||||||
that must wait for the GitHub release, npm rc package, plugin tag/directory,
|
that must wait for the GitHub release, npm rc package, plugin tag/directory,
|
||||||
and ECC Tools billing readback.
|
and ECC Tools billing readback.
|
||||||
@@ -91,7 +91,7 @@ What stays local:
|
|||||||
2. Read the [Hermes setup guide](../../HERMES-SETUP.md).
|
2. Read the [Hermes setup guide](../../HERMES-SETUP.md).
|
||||||
3. Review the [cross-harness architecture](../../architecture/cross-harness.md).
|
3. Review the [cross-harness architecture](../../architecture/cross-harness.md).
|
||||||
4. Run the [observability readiness gate](../../architecture/observability-readiness.md).
|
4. Run the [observability readiness gate](../../architecture/observability-readiness.md).
|
||||||
5. Check the [release URL ledger](release-url-ledger-2026-05-18.md) before
|
5. Check the [release URL ledger](release-url-ledger-2026-05-19.md) before
|
||||||
using any announcement links.
|
using any announcement links.
|
||||||
6. Start with one workflow lane: engineering, research, content, or outreach.
|
6. Start with one workflow lane: engineering, research, content, or outreach.
|
||||||
7. Import only sanitized operator patterns into ECC skills.
|
7. Import only sanitized operator patterns into ECC skills.
|
||||||
|
|||||||
53
docs/releases/2.0.0-rc.1/release-url-ledger-2026-05-19.md
Normal file
53
docs/releases/2.0.0-rc.1/release-url-ledger-2026-05-19.md
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# ECC v2.0.0-rc.1 Release URL Ledger
|
||||||
|
|
||||||
|
This ledger separates links that are already public from links that only become
|
||||||
|
valid after the approval-gated release, package, plugin, and announcement
|
||||||
|
steps. Regenerate it from the final release commit before posting any public
|
||||||
|
announcement.
|
||||||
|
|
||||||
|
Refreshed on 2026-05-19 after the public repository rename to
|
||||||
|
`affaan-m/ECC`. The final release pass must replace commit-specific evidence
|
||||||
|
with output from the exact release commit.
|
||||||
|
|
||||||
|
## Live Now
|
||||||
|
|
||||||
|
| Surface | URL | Verification |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Repository | <https://github.com/affaan-m/ECC> | `git remote get-url origin` returns `https://github.com/affaan-m/ECC.git` |
|
||||||
|
| Release pack folder | <https://github.com/affaan-m/ECC/tree/main/docs/releases/2.0.0-rc.1> | In-tree release pack |
|
||||||
|
| Release notes draft | <https://github.com/affaan-m/ECC/blob/main/docs/releases/2.0.0-rc.1/release-notes.md> | In-tree release copy |
|
||||||
|
| Hermes setup guide | <https://github.com/affaan-m/ECC/blob/main/docs/HERMES-SETUP.md> | In-tree sanitized Hermes guide |
|
||||||
|
| May 19 evidence snapshot | <https://github.com/affaan-m/ECC/blob/main/docs/releases/2.0.0-rc.1/publication-evidence-2026-05-19.md> | Current strongest identity, video, growth, and CI readiness evidence |
|
||||||
|
| May 18 evidence snapshot | <https://github.com/affaan-m/ECC/blob/main/docs/releases/2.0.0-rc.1/publication-evidence-2026-05-18.md> | Previous supply-chain and publication-path readiness evidence |
|
||||||
|
| May 18 operator dashboard | <https://github.com/affaan-m/ECC/blob/main/docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-18.md> | Previous prompt-to-artifact dashboard |
|
||||||
|
| May 19 operator dashboard | <https://github.com/affaan-m/ECC/blob/main/docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-19.md> | Current prompt-to-artifact dashboard with hypergrowth, video, and outbound lanes |
|
||||||
|
| npm package page | <https://www.npmjs.com/package/ecc-universal> | `npm view ecc-universal name version dist-tags --json` returned `latest: 1.10.0`; rc.1 is not published yet |
|
||||||
|
| Codex marketplace CLI docs | <https://developers.openai.com/codex/cli/reference#codex-plugin-marketplace> | Official docs list `codex plugin marketplace add` for GitHub shorthand, Git URLs, SSH URLs, and local marketplace roots |
|
||||||
|
| Codex official Plugin Directory status | <https://developers.openai.com/codex/plugins/build#publish-official-public-plugins> | Official docs say public Plugin Directory publishing and self-serve management are coming soon |
|
||||||
|
|
||||||
|
## Approval-Gated URLs
|
||||||
|
|
||||||
|
| Surface | Intended URL or command | Gate before use |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| GitHub prerelease | <https://github.com/affaan-m/ECC/releases/tag/v2.0.0-rc.1> | `gh release view v2.0.0-rc.1 --repo affaan-m/ECC --json tagName,url,isPrerelease` must return the prerelease |
|
||||||
|
| npm rc package | <https://www.npmjs.com/package/ecc-universal/v/2.0.0-rc.1> | `npm publish --tag next` approval and post-publish `npm view ecc-universal dist-tags --json` |
|
||||||
|
| Claude plugin tag | `claude plugin tag .claude-plugin --dry-run`, then real tag only after approval | Clean release commit and plugin tag/push approval |
|
||||||
|
| Codex repo marketplace install | `codex plugin marketplace add affaan-m/ECC --ref v2.0.0-rc.1` | GitHub tag must exist; official Plugin Directory submission remains separate |
|
||||||
|
| ECC Tools native-payments announcement | ECC Tools Marketplace/App URL plus billing readiness readback | Marketplace-managed test account must return `announcementGate.ready === true` |
|
||||||
|
| Public announcements | X, LinkedIn, GitHub release, and longform URLs | GitHub release, npm, plugin, and billing URLs must resolve first |
|
||||||
|
|
||||||
|
## Pre-Post Check
|
||||||
|
|
||||||
|
Run these immediately before publication:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git status --short --branch
|
||||||
|
gh release view v2.0.0-rc.1 --repo affaan-m/ECC --json tagName,url,isPrerelease
|
||||||
|
npm view ecc-universal name version dist-tags --json
|
||||||
|
codex plugin marketplace add --help
|
||||||
|
rg -n "TODO|TBD|PLACEHOLDER" docs/releases/2.0.0-rc.1
|
||||||
|
npm run preview-pack:smoke
|
||||||
|
```
|
||||||
|
|
||||||
|
Do not post the social or notification copy until the approval-gated URLs above
|
||||||
|
resolve from a clean release commit.
|
||||||
200
docs/releases/2.0.0-rc.1/video-suite-production.md
Normal file
200
docs/releases/2.0.0-rc.1/video-suite-production.md
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
# ECC 2.0 Video Suite Production Manifest
|
||||||
|
|
||||||
|
Snapshot date: 2026-05-19.
|
||||||
|
|
||||||
|
This is the production contract for the ECC 2.0 release video suite. It keeps
|
||||||
|
the public release story, local source inventory, render outputs, and self-eval
|
||||||
|
gate in one place without committing raw footage, private transcript exports, or
|
||||||
|
absolute local paths.
|
||||||
|
|
||||||
|
## Claim
|
||||||
|
|
||||||
|
ECC 2.0 is the harness-native operator system for agentic work.
|
||||||
|
|
||||||
|
The videos should prove that claim directly:
|
||||||
|
|
||||||
|
- one reusable layer across Claude Code, Codex, OpenCode, Cursor, Gemini, Zed,
|
||||||
|
GitHub Copilot, and terminal workflows;
|
||||||
|
- reusable skills, rules, hooks, agents, MCP conventions, release gates, and
|
||||||
|
operator workflows;
|
||||||
|
- `ecc2/` as the alpha control-plane/TUI direction, not the whole product;
|
||||||
|
- AgentShield and supply-chain gates as the enterprise trust layer;
|
||||||
|
- OSS stays free, with GitHub Sponsors, ECC Tools Pro, and consulting as the
|
||||||
|
funding surface.
|
||||||
|
|
||||||
|
Do not frame the launch as a rename, pivot, config pack, or Claude-only package.
|
||||||
|
|
||||||
|
## Private Inputs
|
||||||
|
|
||||||
|
Do not commit raw footage, transcript JSON, or timeline exports.
|
||||||
|
|
||||||
|
Operators should point the validator at local media using environment variables:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ECC_VIDEO_SOURCE_ROOT=/path/to/ecc_2_raws \
|
||||||
|
ECC_VIDEO_RELEASE_SUITE_ROOT=/path/to/ecc_2_release_suite \
|
||||||
|
npm run release:video-suite -- --format json
|
||||||
|
```
|
||||||
|
|
||||||
|
`ECC_VIDEO_SOURCE_ROOT` should contain proof images and may contain an `_edited/`
|
||||||
|
subdirectory with edited source clips. `ECC_VIDEO_RELEASE_SUITE_ROOT` should
|
||||||
|
contain `edl/`, `segments/`, `renders/`, `timelines/`, and `transcripts/`.
|
||||||
|
|
||||||
|
## Source Inventory
|
||||||
|
|
||||||
|
These basenames are the required local inputs for the release suite validator.
|
||||||
|
|
||||||
|
| Asset | Lane | Proof |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `longform-full-wide.mp4` | Primary launch video | operator system, control-plane direction, closing proof |
|
||||||
|
| `sf-longform-full.mp4` | Primary launch video | structured context opener |
|
||||||
|
| `sf-thread-2-whatisecc.mp4` | What is ECC | category clarity and GitHub App explanation |
|
||||||
|
| `sf-thread-4-security.mp4` | Security proof | AgentShield, hooks, MCP, permission risk |
|
||||||
|
| `thread-2-ghapp-money.mp4` | Money/proof clip | OSS plus paid hosting and services |
|
||||||
|
| `architecture-2-wide.mp4` | B-roll | harness-native architecture |
|
||||||
|
| `terminal-scan-2-wide.mp4` | Install proof | terminal workflow and install confidence |
|
||||||
|
| `new_site_raw.mp4` | B-roll | site and product surface |
|
||||||
|
| `coverage-montage-wide.mp4` | Coverage/social proof | distribution and social proof |
|
||||||
|
| `metrics-ticker-2-wide.mp4` | Money/proof clip | traction and funnel proof |
|
||||||
|
| `growth-timeline-2-wide.mp4` | Coverage/social proof | release momentum timeline |
|
||||||
|
| `gh_app_1.png` | Money/proof clip | hosted GitHub App surface |
|
||||||
|
| `star_history.png` | Coverage/social proof | OSS adoption chart |
|
||||||
|
| `x_analytics.png` | Coverage/social proof | social distribution proof |
|
||||||
|
| `100k.png` | Coverage/social proof | reach milestone proof |
|
||||||
|
|
||||||
|
## Deliverables
|
||||||
|
|
||||||
|
| Deliverable | Length | Aspect | Output |
|
||||||
|
| --- | ---: | --- | --- |
|
||||||
|
| Primary launch video | 90-150s | 16:9 | `ecc-2-primary-launch.mp4` |
|
||||||
|
| Install proof clip | 25-35s | 16:9 and 9:16 | `ecc-2-install-proof-*` |
|
||||||
|
| What is ECC clip | 45-60s | 16:9 and 9:16 | `ecc-2-what-is-ecc-*` |
|
||||||
|
| Security proof clip | 45-60s | 16:9 and 9:16 | `ecc-2-security-proof-*` |
|
||||||
|
| Money/proof clip | 30-45s | 16:9 and 9:16 | `ecc-2-money-proof-*` |
|
||||||
|
| Coverage/social proof clip | 30-45s | 16:9 and 9:16 | `ecc-2-social-proof-*` |
|
||||||
|
|
||||||
|
## Primary Launch Video
|
||||||
|
|
||||||
|
The rough v1 primary launch assembly is the current spine. It should stay
|
||||||
|
speech-led, with product proof covering jump cuts and older wording.
|
||||||
|
|
||||||
|
| Order | Source | In | Out | Use |
|
||||||
|
| --- | --- | ---: | ---: | --- |
|
||||||
|
| 01 | `sf-longform-full.mp4` | 161.12 | 177.68 | Cleaner opener: ECC as structured context with skills, commands, agents, hooks, and project setup. |
|
||||||
|
| 02 | `thread-2-ghapp-money.mp4` | 21.84 | 30.40 | Direct product thesis: agentic harness optimization. |
|
||||||
|
| 03 | `thread-2-ghapp-money.mp4` | 41.00 | 59.72 | Not another harness; ECC is the layer and tooling on top of harnesses. |
|
||||||
|
| 04 | `longform-full-wide.mp4` | 254.60 | 271.20 | Agentic IDE, observability, tracing, and multi-agent control-plane direction. |
|
||||||
|
| 05 | `sf-thread-2-whatisecc.mp4` | 40.08 | 60.60 | GitHub App analyzes repos and injects project-specific skills, prompts, and hooks. |
|
||||||
|
| 06 | `sf-thread-4-security.mp4` | 17.60 | 32.72 | Security risk setup: hooks, MCP servers, permissions. |
|
||||||
|
| 07 | `sf-thread-4-security.mp4` | 37.28 | 51.32 | AgentShield proof: rules, categories, grades, secrets, injection, exfiltration. |
|
||||||
|
| 08 | `thread-2-ghapp-money.mp4` | 59.72 | 75.96 | OSS-first business model plus managed GitHub App surface. |
|
||||||
|
| 09 | `longform-full-wide.mp4` | 507.34 | 525.62 | Close on workflows, tested shipping, and secure daily agent work. |
|
||||||
|
|
||||||
|
Required local rough v1 artifacts:
|
||||||
|
|
||||||
|
- `edl/primary-launch.edl.md`
|
||||||
|
- `timelines/primary-launch-v1.timeline.json`
|
||||||
|
- `renders/ecc-2-primary-launch-rough-v1.mp4`
|
||||||
|
- `renders/ecc-2-primary-launch-rough-v1.captions.srt`
|
||||||
|
- `segments/primary-launch-v1/01-structured-context.mp4`
|
||||||
|
- `segments/primary-launch-v1/02-agentic-harness-optimization.mp4`
|
||||||
|
- `segments/primary-launch-v1/03-not-another-harness.mp4`
|
||||||
|
- `segments/primary-launch-v1/04-agentic-ide-surface.mp4`
|
||||||
|
- `segments/primary-launch-v1/05-github-app-proof.mp4`
|
||||||
|
- `segments/primary-launch-v1/06-security-risk.mp4`
|
||||||
|
- `segments/primary-launch-v1/07-agentshield-proof.mp4`
|
||||||
|
- `segments/primary-launch-v1/08-oss-paid-model.mp4`
|
||||||
|
- `segments/primary-launch-v1/09-close-shipping-system.mp4`
|
||||||
|
|
||||||
|
## Publish-Candidate Outputs
|
||||||
|
|
||||||
|
The release validator also expects the current publish-candidate set under
|
||||||
|
`renders/publish-candidates/`. These are still local review files, not public
|
||||||
|
uploads or committed media.
|
||||||
|
|
||||||
|
| Output | Target |
|
||||||
|
| --- | --- |
|
||||||
|
| `ecc-2-primary-launch.mp4` | 90-150s, 1920x1080, audio |
|
||||||
|
| `ecc-2-primary-launch.captions.srt` | primary captions |
|
||||||
|
| `ecc-2-install-proof-wide.mp4` | 25-35s, 1920x1080, audio |
|
||||||
|
| `ecc-2-install-proof-vertical.mp4` | 25-35s, 1080x1920, audio |
|
||||||
|
| `ecc-2-what-is-ecc-wide.mp4` | 45-60s, 1920x1080, audio |
|
||||||
|
| `ecc-2-what-is-ecc-vertical.mp4` | 45-60s, 1080x1920, audio |
|
||||||
|
| `ecc-2-security-proof-wide.mp4` | 45-60s, 1920x1080, audio |
|
||||||
|
| `ecc-2-security-proof-vertical.mp4` | 45-60s, 1080x1920, audio |
|
||||||
|
| `ecc-2-money-proof-wide.mp4` | 30-45s, 1920x1080, audio |
|
||||||
|
| `ecc-2-money-proof-vertical.mp4` | 30-45s, 1080x1920, audio |
|
||||||
|
| `ecc-2-social-proof-wide.mp4` | 30-45s, 1920x1080, audio |
|
||||||
|
| `ecc-2-social-proof-vertical.mp4` | 30-45s, 1080x1920, audio |
|
||||||
|
|
||||||
|
## video-use compatible workflow
|
||||||
|
|
||||||
|
Use the same production shape as Video Use while keeping the ECC-specific media
|
||||||
|
stack intact:
|
||||||
|
|
||||||
|
1. Treat transcript and timeline data as the editing surface.
|
||||||
|
2. Inspect filmstrip or frame samples only at ambiguous cut points.
|
||||||
|
3. Keep an edit decision list before rendering.
|
||||||
|
4. Cut deterministically with FFmpeg.
|
||||||
|
5. Add proof overlays with Remotion or Manim where product claims need visual
|
||||||
|
evidence.
|
||||||
|
6. Export the MP4 plus editable timeline and caption state.
|
||||||
|
7. Run self-eval before any upload or social post.
|
||||||
|
|
||||||
|
Do not dump frames into the repo. Frame samples used for self-eval belong in the
|
||||||
|
local release suite workspace.
|
||||||
|
|
||||||
|
## Browser Capture Plan
|
||||||
|
|
||||||
|
Use Browser or equivalent desktop capture only for proof footage that must be
|
||||||
|
current on release day:
|
||||||
|
|
||||||
|
| Surface | Capture |
|
||||||
|
| --- | --- |
|
||||||
|
| GitHub repo | README hero, install block, sponsor links, release notes |
|
||||||
|
| Codex plugin | repo marketplace install path and local plugin README |
|
||||||
|
| OpenCode package | package install and plugin banner |
|
||||||
|
| ECC Tools Pro | billing/product page only after live readback confirms claims |
|
||||||
|
| AgentShield | CLI output, policy category view, supply-chain gate |
|
||||||
|
| `ecc2/` | alpha control-plane/TUI surface with alpha framing |
|
||||||
|
|
||||||
|
If a surface is not live, use a local browser capture and label it as local or
|
||||||
|
release-candidate proof. Do not claim marketplace, billing, or official
|
||||||
|
directory availability before evidence exists.
|
||||||
|
|
||||||
|
## Self-Eval Gate
|
||||||
|
|
||||||
|
Run the validator:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ECC_VIDEO_SOURCE_ROOT=/path/to/ecc_2_raws \
|
||||||
|
ECC_VIDEO_RELEASE_SUITE_ROOT=/path/to/ecc_2_release_suite \
|
||||||
|
npm run release:video-suite -- --format json
|
||||||
|
```
|
||||||
|
|
||||||
|
Then manually check the final render for:
|
||||||
|
|
||||||
|
- validator self-eval passes for the primary render: 90-150 seconds, at least
|
||||||
|
1280x720, video stream present, audio stream present, and non-empty output;
|
||||||
|
- validator self-eval passes for the publish-candidate set: primary MP4 plus
|
||||||
|
captions and five short clips in both wide and vertical formats;
|
||||||
|
- validator visual QA reports zero detected black-frame segments for every
|
||||||
|
publish-candidate MP4;
|
||||||
|
- no blank frames or accidental desktop exposure;
|
||||||
|
- no stale repo name, pivot, rename, or Claude-only framing in captions;
|
||||||
|
- no captions that rewrite speech into a false claim;
|
||||||
|
- no stale URLs, old install commands, or pre-rename repository links;
|
||||||
|
- no internal MRR numbers unless the post explicitly needs them;
|
||||||
|
- audio continuity across every cut;
|
||||||
|
- first 10 seconds clearly say what ECC is;
|
||||||
|
- final CTA routes to repo, sponsor, Pro, or consulting without clutter.
|
||||||
|
|
||||||
|
## Do Not Publish If
|
||||||
|
|
||||||
|
- `npm run release:video-suite` is not ready for the local source roots.
|
||||||
|
- The primary launch render is outside the 90-150 second target.
|
||||||
|
- Captions mention the old repository name.
|
||||||
|
- Product proof relies on private screens, secrets, customer data, or raw local
|
||||||
|
paths.
|
||||||
|
- The release URL, npm, plugin, billing, or marketplace claims outrun the
|
||||||
|
evidence in `publication-readiness.md`.
|
||||||
@@ -71,13 +71,13 @@ The deeper local integrations stay local until they are sanitized, and publicati
|
|||||||
11/ Start here:
|
11/ Start here:
|
||||||
|
|
||||||
Repo:
|
Repo:
|
||||||
<https://github.com/affaan-m/everything-claude-code>
|
<https://github.com/affaan-m/ECC>
|
||||||
|
|
||||||
Hermes x ECC setup:
|
Hermes x ECC setup:
|
||||||
<https://github.com/affaan-m/everything-claude-code/blob/main/docs/HERMES-SETUP.md>
|
<https://github.com/affaan-m/ECC/blob/main/docs/HERMES-SETUP.md>
|
||||||
|
|
||||||
12/ Release notes:
|
12/ Release notes:
|
||||||
<https://github.com/affaan-m/everything-claude-code/blob/main/docs/releases/2.0.0-rc.1/release-notes.md>
|
<https://github.com/affaan-m/ECC/blob/main/docs/releases/2.0.0-rc.1/release-notes.md>
|
||||||
|
|
||||||
URL ledger:
|
URL ledger:
|
||||||
<https://github.com/affaan-m/everything-claude-code/blob/main/docs/releases/2.0.0-rc.1/release-url-ledger-2026-05-18.md>
|
<https://github.com/affaan-m/ECC/blob/main/docs/releases/2.0.0-rc.1/release-url-ledger-2026-05-19.md>
|
||||||
|
|||||||
155
docs/releases/2.0.0/ecc-2-hypergrowth-release-command-center.md
Normal file
155
docs/releases/2.0.0/ecc-2-hypergrowth-release-command-center.md
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
# ECC 2.0 Hypergrowth Release Command Center
|
||||||
|
|
||||||
|
Snapshot date: 2026-05-19.
|
||||||
|
|
||||||
|
This is the execution map for turning ECC 2.0 into a complete public release,
|
||||||
|
partner funnel, sponsor funnel, consulting surface, and content launch. It is
|
||||||
|
written for operators. Use it to decide what ships, what gets announced, and
|
||||||
|
what stays blocked until evidence exists.
|
||||||
|
|
||||||
|
## Release Claim
|
||||||
|
|
||||||
|
ECC 2.0 is the harness-native operator system for agentic work.
|
||||||
|
|
||||||
|
The public proof must show the actual system:
|
||||||
|
|
||||||
|
- reusable skills, rules, hooks, MCP conventions, and release gates;
|
||||||
|
- Claude Code, Codex, OpenCode, Cursor, Gemini, Zed, GitHub Copilot, and
|
||||||
|
terminal-only workflows as supported execution surfaces;
|
||||||
|
- `ecc2/` as the alpha control-plane/TUI direction;
|
||||||
|
- Hermes as the optional operator shell for chat, cron, handoffs, and daily
|
||||||
|
work routing;
|
||||||
|
- ECC Tools Pro, GitHub Sponsors, and consulting as the business surface that
|
||||||
|
funds the OSS layer.
|
||||||
|
|
||||||
|
Avoid language that frames this as a rename or a retreat from the old project.
|
||||||
|
The release copy should show the 2.0 product shape directly.
|
||||||
|
|
||||||
|
## Current Growth Baseline
|
||||||
|
|
||||||
|
| Metric | Current | Target | Gap |
|
||||||
|
| --- | ---: | ---: | ---: |
|
||||||
|
| MRR | `$1,728/mo` | `$10,000/mo` | `$8,272/mo` |
|
||||||
|
| Sponsor motion | Active GitHub Sponsors plus open inbound | Repeatable sponsor close loop | Approval-gated outbound |
|
||||||
|
| Consulting motion | Open, non-primary | Partner-ready packages | Public proof, talks, and intake |
|
||||||
|
| Content motion | Release video publish candidates ready | Weekly launch clips and founder proof | Owner approval, upload, and public URLs |
|
||||||
|
| Community motion | Discord exists | Useful coding/operator community | Invite, channels, pins, moderation |
|
||||||
|
|
||||||
|
MRR growth should come from four lanes at once:
|
||||||
|
|
||||||
|
- GitHub Sponsors and OSS partner sponsors;
|
||||||
|
- ECC Tools Pro subscriptions;
|
||||||
|
- consulting and implementation contracts;
|
||||||
|
- talks, podcasts, conference demos, and partner webinars that create inbound.
|
||||||
|
|
||||||
|
## Release Gates
|
||||||
|
|
||||||
|
| Lane | Done when | Current action |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| Repo identity | README, package metadata, plugin metadata, release docs, workflows, and launch copy all use `affaan-m/ECC` where public URLs are needed | Canonical URL sweep |
|
||||||
|
| Package and plugin publication | `ecc-universal@2.0.0-rc.1` dry-runs clean, npm `next` is approved, Claude plugin tag dry-runs, Codex repo marketplace smoke passes, OpenCode build passes | Refresh publication evidence from final commit |
|
||||||
|
| Product proof | Quickstart, cross-harness architecture, demo prompts, `ecc2/` alpha boundary, AgentShield safety proof, and hosted ECC Tools links are consistent | Keep proof surfaces concrete |
|
||||||
|
| Revenue proof | Sponsor tiers, Pro pricing, consulting CTA, partner CTA, and billing-readback language are current | Do not announce billing claims before live readback |
|
||||||
|
| Content proof | Launch video, short-form clips, screenshots, release notes, GitHub Discussion, X, LinkedIn, and longform post are aligned | Pick final video cuts, upload after approval, and attach public URLs |
|
||||||
|
| Community proof | Discord invite, rules, channels, onboarding, and sponsor/community routing are ready | Needs invite/token decision before public links |
|
||||||
|
|
||||||
|
## Video Suite
|
||||||
|
|
||||||
|
The video lane should use the existing ECC video-editing skill plus the
|
||||||
|
`browser-use/video-use` model where useful: transcript as the editing surface,
|
||||||
|
strategy approval before render, deterministic cuts, timeline/project output
|
||||||
|
when available, and self-eval before publication.
|
||||||
|
|
||||||
|
Reference pattern: <https://github.com/browser-use/video-use>
|
||||||
|
|
||||||
|
Primary source classes already exist in the local ECC media library. Keep raw
|
||||||
|
absolute paths out of public docs; use basenames or a private production
|
||||||
|
manifest when handing work to an editor or agent.
|
||||||
|
|
||||||
|
| Deliverable | Length | Source material | Proof goal |
|
||||||
|
| --- | ---: | --- | --- |
|
||||||
|
| Primary launch video | 90-150s | `longform-full-wide.mp4`, `sf-longform-full.mp4`, `architecture-2-wide.mp4`, `terminal-scan-2-wide.mp4`, `new_site_raw.mp4` | ECC 2.0 as the operator system |
|
||||||
|
| Install proof | 30s | README install, terminal scan, quickstart, plugin install | Fewer-click adoption |
|
||||||
|
| What is ECC | 45-60s | `sf-thread-2-whatisecc.mp4`, `vertical-2-whatisecc.mp4`, `architecture-2-*` | Product category clarity |
|
||||||
|
| Security proof | 45-60s | `sf-thread-4-security.mp4`, AgentShield evidence, supply-chain gates | Enterprise trust |
|
||||||
|
| Money/proof clip | 30-45s | `thread-2-ghapp-money.mp4`, `metrics-ticker-2-*`, `gh_app_*.png` | Sponsor, Pro, and partner credibility |
|
||||||
|
| Coverage/social proof | 30-45s | `coverage-montage-wide.mp4`, `100k.png`, `star_history.png`, `x_analytics.png`, coverage screenshots | Distribution leverage |
|
||||||
|
|
||||||
|
Production steps:
|
||||||
|
|
||||||
|
1. Generate transcripts for the longform and shortform raw clips.
|
||||||
|
2. Build an edit decision list with hook, proof, demo, business CTA, and final
|
||||||
|
CTA segments.
|
||||||
|
3. Cut deterministically with FFmpeg.
|
||||||
|
4. Add overlays and data motion in Remotion or Manim.
|
||||||
|
5. Add captions, light color correction, audio normalization, and platform
|
||||||
|
reframes.
|
||||||
|
6. Run a self-eval pass for blank frames, bad captions, jump cuts, weak hook,
|
||||||
|
missing product proof, and stale URLs.
|
||||||
|
7. Export final MP4s plus the editable timeline/project state.
|
||||||
|
|
||||||
|
## Distribution Plan
|
||||||
|
|
||||||
|
| Channel | Asset | CTA |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| GitHub Release | release notes, quickstart, launch video, sponsor link | star, install, sponsor |
|
||||||
|
| GitHub Discussion | short announcement and proof bullets | questions, feedback, sponsors |
|
||||||
|
| X | launch thread, 30s install clip, proof clips | repo, sponsor, Pro |
|
||||||
|
| LinkedIn | partner-friendly product proof, consulting CTA | sponsors, consulting, talks |
|
||||||
|
| YouTube/Shorts/Reels/TikTok | primary launch video and clips | repo, site, newsletter/community |
|
||||||
|
| Podcasts/talks | one-page pitch, demo outline, founder proof | bookings, partners |
|
||||||
|
| Sponsor outbound | direct sponsor note and tier table | GitHub Sponsors or Pro |
|
||||||
|
|
||||||
|
The source of truth for sponsor, partner, consulting, conference, podcast, and
|
||||||
|
GitHub Discussion copy is
|
||||||
|
`docs/releases/2.0.0-rc.1/partner-sponsor-talks-pack.md`.
|
||||||
|
The source of truth for owner approval across release, package, plugin, video,
|
||||||
|
billing, social, and outbound actions is
|
||||||
|
`docs/releases/2.0.0-rc.1/owner-approval-packet-2026-05-19.md`.
|
||||||
|
|
||||||
|
## Copy Rules
|
||||||
|
|
||||||
|
Use direct product language:
|
||||||
|
|
||||||
|
- `ECC 2.0 is the harness-native operator system for agentic work.`
|
||||||
|
- `One reusable layer across Claude Code, Codex, OpenCode, Cursor, Gemini, Zed, GitHub Copilot, and terminal workflows.`
|
||||||
|
- `OSS stays free. Sponsors and Pro fund the work.`
|
||||||
|
- `Use ECC for skills, hooks, rules, MCP conventions, release gates, and operator workflows.`
|
||||||
|
|
||||||
|
Avoid:
|
||||||
|
|
||||||
|
- `we renamed the repo`;
|
||||||
|
- `pivot`;
|
||||||
|
- legacy config-pack framing;
|
||||||
|
- `Claude-only`;
|
||||||
|
- generic founder-journey language;
|
||||||
|
- claims about billing, marketplace payments, or official directory listings
|
||||||
|
before live evidence exists.
|
||||||
|
|
||||||
|
## First Build Order
|
||||||
|
|
||||||
|
1. Land the public repo identity fixes.
|
||||||
|
2. Refresh package, plugin, workflow, release, and launch-copy URLs.
|
||||||
|
3. Record final publication evidence from the exact release commit.
|
||||||
|
4. Keep the video suite manifest, transcripts, publish candidates, and visual QA
|
||||||
|
current with `npm run release:video-suite -- --format json`.
|
||||||
|
5. Browser-capture the README, ECC Tools app, install flow, and relevant proof
|
||||||
|
surfaces for b-roll.
|
||||||
|
6. Choose the owner-approved primary launch video and five short clips, then
|
||||||
|
upload and attach final public URLs.
|
||||||
|
7. Finalize GitHub release, X thread, LinkedIn post, Discussion announcement,
|
||||||
|
sponsor email copy, consulting intro, partner DM, and podcast/talk pitch.
|
||||||
|
8. Publish only after npm, plugin, release URL, and billing-readback gates are
|
||||||
|
either live or explicitly marked blocked.
|
||||||
|
|
||||||
|
## Owner Approvals
|
||||||
|
|
||||||
|
These actions need a human approval or credential before they move:
|
||||||
|
|
||||||
|
- sending annual-upgrade or sponsor emails;
|
||||||
|
- updating LinkedIn profile text;
|
||||||
|
- wiring Discord with a bot token and guild ID;
|
||||||
|
- publishing npm or creating plugin tags;
|
||||||
|
- announcing billing/native payments;
|
||||||
|
- sending partner, consulting, conference, podcast, or sponsor outreach;
|
||||||
|
- posting final social copy from personal accounts.
|
||||||
@@ -5,7 +5,7 @@ edition = "2021"
|
|||||||
description = "ECC 2.0 — Agentic IDE control plane with TUI dashboard"
|
description = "ECC 2.0 — Agentic IDE control plane with TUI dashboard"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
authors = ["Affaan Mustafa <me@affaanmustafa.com>"]
|
authors = ["Affaan Mustafa <me@affaanmustafa.com>"]
|
||||||
repository = "https://github.com/affaan-m/everything-claude-code"
|
repository = "https://github.com/affaan-m/ECC"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["vendored-openssl"]
|
default = ["vendored-openssl"]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/pre-bash-dispatcher.js"
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/pre-bash-dispatcher.js"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Consolidated Bash preflight dispatcher for quality, tmux, push, and GateGuard checks",
|
"description": "Consolidated Bash preflight dispatcher for quality, tmux, push, and GateGuard checks",
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js pre:write:doc-file-warning scripts/hooks/doc-file-warning.js standard,strict"
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js pre:write:doc-file-warning scripts/hooks/doc-file-warning.js standard,strict"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Doc file warning: warn about non-standard documentation files (exit code 0; warns only)",
|
"description": "Doc file warning: warn about non-standard documentation files (exit code 0; warns only)",
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js pre:edit-write:suggest-compact scripts/hooks/suggest-compact.js standard,strict"
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js pre:edit-write:suggest-compact scripts/hooks/suggest-compact.js standard,strict"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Suggest manual compaction at logical intervals",
|
"description": "Suggest manual compaction at logical intervals",
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplace\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplace\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js pre:observe scripts/hooks/observe-runner.js standard,strict",
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js pre:observe scripts/hooks/observe-runner.js standard,strict",
|
||||||
"async": true,
|
"async": true,
|
||||||
"timeout": 10
|
"timeout": 10
|
||||||
}
|
}
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js pre:governance-capture scripts/hooks/governance-capture.js standard,strict",
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js pre:governance-capture scripts/hooks/governance-capture.js standard,strict",
|
||||||
"timeout": 10
|
"timeout": 10
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js pre:config-protection scripts/hooks/config-protection.js standard,strict",
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js pre:config-protection scripts/hooks/config-protection.js standard,strict",
|
||||||
"timeout": 5
|
"timeout": 5
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js pre:mcp-health-check scripts/hooks/mcp-health-check.js standard,strict"
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js pre:mcp-health-check scripts/hooks/mcp-health-check.js standard,strict"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Check MCP server health before MCP tool execution and block unhealthy MCP calls",
|
"description": "Check MCP server health before MCP tool execution and block unhealthy MCP calls",
|
||||||
@@ -88,7 +88,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js pre:edit-write:gateguard-fact-force scripts/hooks/gateguard-fact-force.js standard,strict",
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js pre:edit-write:gateguard-fact-force scripts/hooks/gateguard-fact-force.js standard,strict",
|
||||||
"timeout": 5
|
"timeout": 5
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -102,7 +102,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js pre:compact scripts/hooks/pre-compact.js standard,strict"
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js pre:compact scripts/hooks/pre-compact.js standard,strict"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Save state before context compaction",
|
"description": "Save state before context compaction",
|
||||||
@@ -115,7 +115,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/session-start-bootstrap.js"
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/session-start-bootstrap.js"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Load previous context and detect package manager on new session",
|
"description": "Load previous context and detect package manager on new session",
|
||||||
@@ -128,7 +128,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/post-bash-dispatcher.js",
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/post-bash-dispatcher.js",
|
||||||
"async": true,
|
"async": true,
|
||||||
"timeout": 30
|
"timeout": 30
|
||||||
}
|
}
|
||||||
@@ -141,7 +141,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:quality-gate scripts/hooks/quality-gate.js standard,strict",
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:quality-gate scripts/hooks/quality-gate.js standard,strict",
|
||||||
"async": true,
|
"async": true,
|
||||||
"timeout": 30
|
"timeout": 30
|
||||||
}
|
}
|
||||||
@@ -154,7 +154,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:edit:design-quality-check scripts/hooks/design-quality-check.js standard,strict",
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:edit:design-quality-check scripts/hooks/design-quality-check.js standard,strict",
|
||||||
"timeout": 10
|
"timeout": 10
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -166,7 +166,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:edit:accumulate scripts/hooks/post-edit-accumulator.js standard,strict"
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:edit:accumulate scripts/hooks/post-edit-accumulator.js standard,strict"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Record edited JS/TS file paths for batch format+typecheck at Stop time",
|
"description": "Record edited JS/TS file paths for batch format+typecheck at Stop time",
|
||||||
@@ -177,7 +177,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:edit:console-warn scripts/hooks/post-edit-console-warn.js standard,strict"
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:edit:console-warn scripts/hooks/post-edit-console-warn.js standard,strict"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Warn about console.log statements after edits",
|
"description": "Warn about console.log statements after edits",
|
||||||
@@ -188,7 +188,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:governance-capture scripts/hooks/governance-capture.js standard,strict",
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:governance-capture scripts/hooks/governance-capture.js standard,strict",
|
||||||
"timeout": 10
|
"timeout": 10
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -200,7 +200,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:session-activity-tracker scripts/hooks/session-activity-tracker.js standard,strict",
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:session-activity-tracker scripts/hooks/session-activity-tracker.js standard,strict",
|
||||||
"timeout": 10
|
"timeout": 10
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -212,7 +212,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplace\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplace\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:observe scripts/hooks/observe-runner.js standard,strict",
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:observe scripts/hooks/observe-runner.js standard,strict",
|
||||||
"async": true,
|
"async": true,
|
||||||
"timeout": 10
|
"timeout": 10
|
||||||
}
|
}
|
||||||
@@ -225,7 +225,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:ecc-metrics-bridge scripts/hooks/ecc-metrics-bridge.js minimal,standard,strict",
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:ecc-metrics-bridge scripts/hooks/ecc-metrics-bridge.js minimal,standard,strict",
|
||||||
"timeout": 10
|
"timeout": 10
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -237,7 +237,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:ecc-context-monitor scripts/hooks/ecc-context-monitor.js standard,strict",
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:ecc-context-monitor scripts/hooks/ecc-context-monitor.js standard,strict",
|
||||||
"timeout": 10
|
"timeout": 10
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -251,7 +251,7 @@
|
|||||||
"hooks": [
|
"hooks": [
|
||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "node -e \"const p=require('path');const r=(()=>{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 [[\\\"ecc\\\"],[\\\"ecc@ecc\\\"],[\\\"marketplaces\\\",\\\"ecc\\\"],[\\\"everything-claude-code\\\"],[\\\"everything-claude-code@everything-claude-code\\\"],[\\\"marketplaces\\\",\\\"everything-claude-code\\\"]]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of [\\\"ecc\\\",\\\"everything-claude-code\\\"]){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:mcp-health-check scripts/hooks/mcp-health-check.js standard,strict"
|
"command": "node -e \"const p=require('path');const r=(()=>{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 [['ecc'],['ecc@ecc'],['marketplaces','ecc'],['everything-claude-code'],['everything-claude-code@everything-claude-code'],['marketplaces','everything-claude-code']]){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ['ecc','everything-claude-code']){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})();const s=p.join(r,'scripts/hooks/plugin-hook-bootstrap.js');process.env.CLAUDE_PLUGIN_ROOT=r;process.argv.splice(1,0,s);require(s)\" node scripts/hooks/run-with-flags.js post:mcp-health-check scripts/hooks/mcp-health-check.js standard,strict"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "Track failed MCP tool calls, mark unhealthy servers, and attempt reconnect",
|
"description": "Track failed MCP tool calls, mark unhealthy servers, and attempt reconnect",
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codebuddy",
|
"codebuddy",
|
||||||
@@ -33,6 +34,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codex",
|
"codex",
|
||||||
@@ -55,6 +57,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"opencode",
|
"opencode",
|
||||||
@@ -79,6 +82,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"opencode",
|
"opencode",
|
||||||
"codebuddy"
|
"codebuddy"
|
||||||
@@ -106,6 +110,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codex",
|
"codex",
|
||||||
@@ -177,6 +182,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codex",
|
"codex",
|
||||||
@@ -210,6 +216,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codex",
|
"codex",
|
||||||
@@ -255,6 +262,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codex",
|
"codex",
|
||||||
@@ -294,6 +302,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codex",
|
"codex",
|
||||||
@@ -326,6 +335,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codex",
|
"codex",
|
||||||
@@ -360,6 +370,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codex",
|
"codex",
|
||||||
@@ -402,6 +413,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codex",
|
"codex",
|
||||||
@@ -428,6 +440,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codex",
|
"codex",
|
||||||
@@ -459,6 +472,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"codex",
|
"codex",
|
||||||
"opencode",
|
"opencode",
|
||||||
@@ -490,6 +504,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"codex",
|
"codex",
|
||||||
"opencode"
|
"opencode"
|
||||||
],
|
],
|
||||||
@@ -515,6 +530,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codex",
|
"codex",
|
||||||
@@ -559,6 +575,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codex",
|
"codex",
|
||||||
@@ -592,6 +609,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codex",
|
"codex",
|
||||||
@@ -617,6 +635,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codex",
|
"codex",
|
||||||
@@ -653,6 +672,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codex",
|
"codex",
|
||||||
@@ -679,6 +699,7 @@
|
|||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codex",
|
"codex",
|
||||||
@@ -703,7 +724,8 @@
|
|||||||
"docs/ja-JP"
|
"docs/ja-JP"
|
||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude"
|
"claude",
|
||||||
|
"claude-project"
|
||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"defaultInstall": false,
|
"defaultInstall": false,
|
||||||
@@ -718,7 +740,8 @@
|
|||||||
"docs/zh-CN"
|
"docs/zh-CN"
|
||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude"
|
"claude",
|
||||||
|
"claude-project"
|
||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"defaultInstall": false,
|
"defaultInstall": false,
|
||||||
@@ -733,7 +756,8 @@
|
|||||||
"docs/ko-KR"
|
"docs/ko-KR"
|
||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude"
|
"claude",
|
||||||
|
"claude-project"
|
||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"defaultInstall": false,
|
"defaultInstall": false,
|
||||||
@@ -748,7 +772,8 @@
|
|||||||
"docs/pt-BR"
|
"docs/pt-BR"
|
||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude"
|
"claude",
|
||||||
|
"claude-project"
|
||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"defaultInstall": false,
|
"defaultInstall": false,
|
||||||
@@ -763,7 +788,8 @@
|
|||||||
"docs/ru"
|
"docs/ru"
|
||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude"
|
"claude",
|
||||||
|
"claude-project"
|
||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"defaultInstall": false,
|
"defaultInstall": false,
|
||||||
@@ -778,7 +804,8 @@
|
|||||||
"docs/tr"
|
"docs/tr"
|
||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude"
|
"claude",
|
||||||
|
"claude-project"
|
||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"defaultInstall": false,
|
"defaultInstall": false,
|
||||||
@@ -793,7 +820,8 @@
|
|||||||
"docs/vi-VN"
|
"docs/vi-VN"
|
||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude"
|
"claude",
|
||||||
|
"claude-project"
|
||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"defaultInstall": false,
|
"defaultInstall": false,
|
||||||
@@ -808,7 +836,8 @@
|
|||||||
"docs/zh-TW"
|
"docs/zh-TW"
|
||||||
],
|
],
|
||||||
"targets": [
|
"targets": [
|
||||||
"claude"
|
"claude",
|
||||||
|
"claude-project"
|
||||||
],
|
],
|
||||||
"dependencies": [],
|
"dependencies": [],
|
||||||
"defaultInstall": false,
|
"defaultInstall": false,
|
||||||
|
|||||||
12
package.json
12
package.json
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "ecc-universal",
|
"name": "ecc-universal",
|
||||||
"version": "2.0.0-rc.1",
|
"version": "2.0.0-rc.1",
|
||||||
"description": "Complete collection of battle-tested Claude Code configs — agents, skills, hooks, rules, and legacy command shims evolved over 10+ months of intensive daily use by an Anthropic hackathon winner",
|
"description": "Harness-native agent operating system for Claude Code, Codex, OpenCode, Cursor, Gemini, and terminal workflows - skills, hooks, rules, MCP conventions, and operator control-plane patterns",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
@@ -34,11 +34,11 @@
|
|||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/affaan-m/everything-claude-code.git"
|
"url": "git+https://github.com/affaan-m/ECC.git"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/affaan-m/everything-claude-code#readme",
|
"homepage": "https://github.com/affaan-m/ECC#readme",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/affaan-m/everything-claude-code/issues"
|
"url": "https://github.com/affaan-m/ECC/issues"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
".agents/",
|
".agents/",
|
||||||
@@ -89,6 +89,7 @@
|
|||||||
"scripts/operator-readiness-dashboard.js",
|
"scripts/operator-readiness-dashboard.js",
|
||||||
"scripts/platform-audit.js",
|
"scripts/platform-audit.js",
|
||||||
"scripts/preview-pack-smoke.js",
|
"scripts/preview-pack-smoke.js",
|
||||||
|
"scripts/release-video-suite.js",
|
||||||
"scripts/hooks/",
|
"scripts/hooks/",
|
||||||
"scripts/install-apply.js",
|
"scripts/install-apply.js",
|
||||||
"scripts/install-plan.js",
|
"scripts/install-plan.js",
|
||||||
@@ -299,7 +300,7 @@
|
|||||||
"ecc-install": "scripts/install-apply.js"
|
"ecc-install": "scripts/install-apply.js"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"postinstall": "echo '\\n ecc-universal installed!\\n Run: npx ecc typescript\\n Compat: npx ecc-install typescript\\n Docs: https://github.com/affaan-m/everything-claude-code\\n'",
|
"postinstall": "echo '\\n ecc-universal installed!\\n Run: npx ecc typescript\\n Compat: npx ecc-install typescript\\n Docs: https://github.com/affaan-m/ECC\\n'",
|
||||||
"catalog:check": "node scripts/ci/catalog.js --text",
|
"catalog:check": "node scripts/ci/catalog.js --text",
|
||||||
"catalog:sync": "node scripts/ci/catalog.js --write --text",
|
"catalog:sync": "node scripts/ci/catalog.js --write --text",
|
||||||
"command-registry:generate": "node scripts/ci/generate-command-registry.js",
|
"command-registry:generate": "node scripts/ci/generate-command-registry.js",
|
||||||
@@ -311,6 +312,7 @@
|
|||||||
"observability:ready": "node scripts/observability-readiness.js",
|
"observability:ready": "node scripts/observability-readiness.js",
|
||||||
"operator:dashboard": "node scripts/operator-readiness-dashboard.js",
|
"operator:dashboard": "node scripts/operator-readiness-dashboard.js",
|
||||||
"preview-pack:smoke": "node scripts/preview-pack-smoke.js",
|
"preview-pack:smoke": "node scripts/preview-pack-smoke.js",
|
||||||
|
"release:video-suite": "node scripts/release-video-suite.js",
|
||||||
"platform:audit": "node scripts/platform-audit.js",
|
"platform:audit": "node scripts/platform-audit.js",
|
||||||
"discussion:audit": "node scripts/discussion-audit.js",
|
"discussion:audit": "node scripts/discussion-audit.js",
|
||||||
"security:ioc-scan": "node scripts/ci/scan-supply-chain-iocs.js",
|
"security:ioc-scan": "node scripts/ci/scan-supply-chain-iocs.js",
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codex",
|
"codex",
|
||||||
|
|||||||
@@ -49,6 +49,7 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"claude",
|
"claude",
|
||||||
|
"claude-project",
|
||||||
"cursor",
|
"cursor",
|
||||||
"antigravity",
|
"antigravity",
|
||||||
"codex",
|
"codex",
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const {
|
|||||||
|
|
||||||
const SCHEMA_VERSION = 'ecc.discussion-audit.v1';
|
const SCHEMA_VERSION = 'ecc.discussion-audit.v1';
|
||||||
const DEFAULT_REPOS = Object.freeze([
|
const DEFAULT_REPOS = Object.freeze([
|
||||||
'affaan-m/everything-claude-code',
|
'affaan-m/ECC',
|
||||||
'affaan-m/agentshield',
|
'affaan-m/agentshield',
|
||||||
'affaan-m/JARVIS',
|
'affaan-m/JARVIS',
|
||||||
'ECC-Tools/ECC-Tools',
|
'ECC-Tools/ECC-Tools',
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ Examples:
|
|||||||
ecc sessions
|
ecc sessions
|
||||||
ecc sessions session-active --json
|
ecc sessions session-active --json
|
||||||
ecc work-items upsert linear-ecc-20 --source linear --source-id ECC-20 --title "Review control-plane contract" --status blocked
|
ecc work-items upsert linear-ecc-20 --source linear --source-id ECC-20 --title "Review control-plane contract" --status blocked
|
||||||
ecc work-items sync-github --repo affaan-m/everything-claude-code
|
ecc work-items sync-github --repo affaan-m/ECC
|
||||||
ecc session-inspect claude:latest
|
ecc session-inspect claude:latest
|
||||||
ecc loop-status --json
|
ecc loop-status --json
|
||||||
ecc uninstall --target antigravity --dry-run
|
ecc uninstall --target antigravity --dry-run
|
||||||
|
|||||||
@@ -12,8 +12,53 @@ const CATEGORIES = [
|
|||||||
'Eval Coverage',
|
'Eval Coverage',
|
||||||
'Security Guardrails',
|
'Security Guardrails',
|
||||||
'Cost Efficiency',
|
'Cost Efficiency',
|
||||||
|
'GitHub Integration',
|
||||||
|
'Vercel Integration',
|
||||||
|
'Netlify Integration',
|
||||||
|
'Cloudflare Integration',
|
||||||
|
'Fly Integration',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const RUBRIC_VERSION = '2026-05-19';
|
||||||
|
|
||||||
|
const PROVIDERS = {
|
||||||
|
Vercel: {
|
||||||
|
detect: (rootDir) =>
|
||||||
|
fileExists(rootDir, 'vercel.json') ||
|
||||||
|
fileExists(rootDir, '.vercel/project.json') ||
|
||||||
|
fileExists(rootDir, '.vercel'),
|
||||||
|
keyPattern: /vercel/i,
|
||||||
|
buildPattern: /vercel/i,
|
||||||
|
workflowPattern: /(vercel-action|vercel\s+(deploy|--prod))/i,
|
||||||
|
},
|
||||||
|
Netlify: {
|
||||||
|
detect: (rootDir) =>
|
||||||
|
fileExists(rootDir, 'netlify.toml') || fileExists(rootDir, '.netlify'),
|
||||||
|
keyPattern: /netlify/i,
|
||||||
|
buildPattern: /netlify/i,
|
||||||
|
workflowPattern: /(netlify\/actions|netlify\s+deploy)/i,
|
||||||
|
},
|
||||||
|
Cloudflare: {
|
||||||
|
detect: (rootDir) =>
|
||||||
|
fileExists(rootDir, 'wrangler.toml') || fileExists(rootDir, 'wrangler.jsonc'),
|
||||||
|
keyPattern: /\b(cloudflare|wrangler)\b/i,
|
||||||
|
buildPattern: /(wrangler|cloudflare)/i,
|
||||||
|
workflowPattern: /(cloudflare\/wrangler-action|wrangler\s+(deploy|publish))/i,
|
||||||
|
},
|
||||||
|
Fly: {
|
||||||
|
detect: (rootDir) => fileExists(rootDir, 'fly.toml'),
|
||||||
|
keyPattern: /fly[_-]?(api|io)/i,
|
||||||
|
buildPattern: /fly\s+(deploy|launch)/i,
|
||||||
|
workflowPattern: /(superfly\/flyctl-actions|flyctl\s+deploy|fly\s+deploy)/i,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
function getApplicableProviders(rootDir) {
|
||||||
|
return Object.entries(PROVIDERS)
|
||||||
|
.filter(([_, spec]) => spec.detect(rootDir))
|
||||||
|
.map(([name]) => name);
|
||||||
|
}
|
||||||
|
|
||||||
function normalizeScope(scope) {
|
function normalizeScope(scope) {
|
||||||
const value = (scope || 'repo').toLowerCase();
|
const value = (scope || 'repo').toLowerCase();
|
||||||
if (!['repo', 'hooks', 'skills', 'commands', 'agents'].includes(value)) {
|
if (!['repo', 'hooks', 'skills', 'commands', 'agents'].includes(value)) {
|
||||||
@@ -607,9 +652,172 @@ function getRepoChecks(rootDir) {
|
|||||||
pass: fileExists(rootDir, 'commands/model-route.md'),
|
pass: fileExists(rootDir, 'commands/model-route.md'),
|
||||||
fix: 'Add commands/model-route.md and route policies for cheap-default execution.',
|
fix: 'Add commands/model-route.md and route policies for cheap-default execution.',
|
||||||
},
|
},
|
||||||
|
...buildGithubChecks(rootDir),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GitHub Integration is intentionally repo-scoped. Scoped audits such as hooks,
|
||||||
|
// skills, commands, and agents should keep reporting only that surface.
|
||||||
|
function buildGithubChecks(rootDir) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: 'github-workflows',
|
||||||
|
category: 'GitHub Integration',
|
||||||
|
points: 3,
|
||||||
|
scopes: ['repo'],
|
||||||
|
path: '.github/workflows/',
|
||||||
|
description: 'GitHub Actions workflows are checked in',
|
||||||
|
pass: hasFileWithExtension(rootDir, '.github/workflows', ['.yml', '.yaml']),
|
||||||
|
fix: 'Add at least one workflow under .github/workflows/ so CI runs on every PR.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'github-pr-template',
|
||||||
|
category: 'GitHub Integration',
|
||||||
|
points: 2,
|
||||||
|
scopes: ['repo'],
|
||||||
|
path: '.github/PULL_REQUEST_TEMPLATE.md',
|
||||||
|
description: 'A pull request template is configured',
|
||||||
|
pass:
|
||||||
|
fileExists(rootDir, '.github/PULL_REQUEST_TEMPLATE.md') ||
|
||||||
|
fileExists(rootDir, '.github/pull_request_template.md'),
|
||||||
|
fix: 'Add .github/PULL_REQUEST_TEMPLATE.md so PR descriptions follow a consistent shape.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'github-issue-templates',
|
||||||
|
category: 'GitHub Integration',
|
||||||
|
points: 2,
|
||||||
|
scopes: ['repo'],
|
||||||
|
path: '.github/ISSUE_TEMPLATE/',
|
||||||
|
description: 'Issue templates are configured',
|
||||||
|
pass: hasFileWithExtension(rootDir, '.github/ISSUE_TEMPLATE', ['.md', '.yml', '.yaml']),
|
||||||
|
fix: 'Add at least one issue template under .github/ISSUE_TEMPLATE/.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'github-codeowners',
|
||||||
|
category: 'GitHub Integration',
|
||||||
|
points: 1,
|
||||||
|
scopes: ['repo'],
|
||||||
|
path: '.github/CODEOWNERS',
|
||||||
|
description: 'A CODEOWNERS file routes reviews',
|
||||||
|
pass:
|
||||||
|
fileExists(rootDir, 'CODEOWNERS') ||
|
||||||
|
fileExists(rootDir, '.github/CODEOWNERS') ||
|
||||||
|
fileExists(rootDir, 'docs/CODEOWNERS'),
|
||||||
|
fix: 'Add a CODEOWNERS file so PRs auto-request the right reviewers.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'github-dep-updates',
|
||||||
|
category: 'GitHub Integration',
|
||||||
|
points: 2,
|
||||||
|
scopes: ['repo'],
|
||||||
|
path: '.github/dependabot.yml',
|
||||||
|
description: 'Automated dependency updates are configured',
|
||||||
|
pass:
|
||||||
|
fileExists(rootDir, '.github/dependabot.yml') ||
|
||||||
|
fileExists(rootDir, '.github/dependabot.yaml') ||
|
||||||
|
fileExists(rootDir, 'renovate.json') ||
|
||||||
|
fileExists(rootDir, '.github/renovate.json') ||
|
||||||
|
fileExists(rootDir, '.renovaterc'),
|
||||||
|
fix: 'Add a Dependabot or Renovate config so dependency updates land automatically.',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function readAllWorkflowsText(rootDir) {
|
||||||
|
const dir = path.join(rootDir, '.github/workflows');
|
||||||
|
if (!fs.existsSync(dir)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const stack = [dir];
|
||||||
|
let combined = '';
|
||||||
|
|
||||||
|
while (stack.length > 0) {
|
||||||
|
const current = stack.pop();
|
||||||
|
const entries = fs.readdirSync(current, { withFileTypes: true });
|
||||||
|
|
||||||
|
for (const entry of entries) {
|
||||||
|
const nextPath = path.join(current, entry.name);
|
||||||
|
if (entry.isDirectory()) {
|
||||||
|
stack.push(nextPath);
|
||||||
|
} else if (entry.name.endsWith('.yml') || entry.name.endsWith('.yaml')) {
|
||||||
|
try {
|
||||||
|
combined += `${fs.readFileSync(nextPath, 'utf8')}\n`;
|
||||||
|
} catch (_error) {
|
||||||
|
// Ignore unreadable workflow files; the finding should stay deterministic.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return combined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildProviderChecks(rootDir, provider, sharedContext) {
|
||||||
|
const spec = PROVIDERS[provider];
|
||||||
|
const packageJson = sharedContext.packageJson || {};
|
||||||
|
const scriptsText = Object.values(packageJson.scripts || {}).join('\n');
|
||||||
|
const category = `${provider} Integration`;
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: `${provider.toLowerCase()}-config`,
|
||||||
|
category,
|
||||||
|
points: 3,
|
||||||
|
scopes: ['repo'],
|
||||||
|
path: `${provider} config`,
|
||||||
|
description: `${provider} deployment config is checked in`,
|
||||||
|
pass: spec.detect(rootDir),
|
||||||
|
fix: `Commit ${provider} configuration so deploys are reproducible from source.`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: `${provider.toLowerCase()}-build-script`,
|
||||||
|
category,
|
||||||
|
points: 2,
|
||||||
|
scopes: ['repo'],
|
||||||
|
path: 'package.json scripts',
|
||||||
|
description: `package.json scripts reference ${provider}`,
|
||||||
|
pass: spec.buildPattern.test(scriptsText),
|
||||||
|
fix: `Add a build or deploy script in package.json that runs ${provider}.`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: `${provider.toLowerCase()}-env-doc`,
|
||||||
|
category,
|
||||||
|
points: 2,
|
||||||
|
scopes: ['repo'],
|
||||||
|
path: '.env.example',
|
||||||
|
description: `${provider} env keys are documented in .env.example`,
|
||||||
|
pass: spec.keyPattern.test(sharedContext.envExample),
|
||||||
|
fix: `Document ${provider} environment variables in .env.example.`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: `${provider.toLowerCase()}-workflow-uses`,
|
||||||
|
category,
|
||||||
|
points: 3,
|
||||||
|
scopes: ['repo'],
|
||||||
|
path: '.github/workflows/',
|
||||||
|
description: `A GitHub workflow uses the ${provider} action or CLI`,
|
||||||
|
pass: spec.workflowPattern.test(sharedContext.workflowsText),
|
||||||
|
fix: `Reference the ${provider} action or CLI from a workflow under .github/workflows/.`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function collectProviderChecks(rootDir, packageJson) {
|
||||||
|
const providers = getApplicableProviders(rootDir);
|
||||||
|
if (providers.length === 0) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const sharedContext = {
|
||||||
|
packageJson: packageJson || {},
|
||||||
|
envExample: `${safeRead(rootDir, '.env.example')}\n${safeRead(rootDir, '.env.sample')}`,
|
||||||
|
workflowsText: readAllWorkflowsText(rootDir),
|
||||||
|
};
|
||||||
|
|
||||||
|
return providers.flatMap(provider => buildProviderChecks(rootDir, provider, sharedContext));
|
||||||
|
}
|
||||||
|
|
||||||
function getConsumerChecks(rootDir) {
|
function getConsumerChecks(rootDir) {
|
||||||
const packageJson = safeParseJson(safeRead(rootDir, 'package.json'));
|
const packageJson = safeParseJson(safeRead(rootDir, 'package.json'));
|
||||||
const gitignore = safeRead(rootDir, '.gitignore');
|
const gitignore = safeRead(rootDir, '.gitignore');
|
||||||
@@ -731,6 +939,8 @@ function getConsumerChecks(rootDir) {
|
|||||||
pass: projectHooks.includes('PreToolUse') || projectHooks.includes('beforeSubmitPrompt') || fileExists(rootDir, '.claude/hooks.json'),
|
pass: projectHooks.includes('PreToolUse') || projectHooks.includes('beforeSubmitPrompt') || fileExists(rootDir, '.claude/hooks.json'),
|
||||||
fix: 'Add project-local hook settings or hook definitions for prompt/tool guardrails.',
|
fix: 'Add project-local hook settings or hook definitions for prompt/tool guardrails.',
|
||||||
},
|
},
|
||||||
|
...buildGithubChecks(rootDir),
|
||||||
|
...collectProviderChecks(rootDir, packageJson),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -764,6 +974,7 @@ function buildReport(scope, options = {}) {
|
|||||||
const overallScore = checks
|
const overallScore = checks
|
||||||
.filter(check => check.pass)
|
.filter(check => check.pass)
|
||||||
.reduce((sum, check) => sum + check.points, 0);
|
.reduce((sum, check) => sum + check.points, 0);
|
||||||
|
const applicableCategories = CATEGORIES.filter(name => categoryScores[name]?.max > 0);
|
||||||
|
|
||||||
const failedChecks = checks.filter(check => !check.pass);
|
const failedChecks = checks.filter(check => !check.pass);
|
||||||
const topActions = failedChecks
|
const topActions = failedChecks
|
||||||
@@ -781,10 +992,12 @@ function buildReport(scope, options = {}) {
|
|||||||
root_dir: rootDir,
|
root_dir: rootDir,
|
||||||
target_mode: targetMode,
|
target_mode: targetMode,
|
||||||
deterministic: true,
|
deterministic: true,
|
||||||
rubric_version: '2026-03-30',
|
rubric_version: RUBRIC_VERSION,
|
||||||
overall_score: overallScore,
|
overall_score: overallScore,
|
||||||
max_score: maxScore,
|
max_score: maxScore,
|
||||||
categories: categoryScores,
|
categories: categoryScores,
|
||||||
|
applicable_categories: applicableCategories,
|
||||||
|
category_count: applicableCategories.length,
|
||||||
checks: checks.map(check => ({
|
checks: checks.map(check => ({
|
||||||
id: check.id,
|
id: check.id,
|
||||||
category: check.category,
|
category: check.category,
|
||||||
|
|||||||
@@ -27,11 +27,12 @@ Usage: install.sh [--target <${LEGACY_INSTALL_TARGETS.join('|')}>] [--dry-run] [
|
|||||||
install.sh [--target <${SUPPORTED_INSTALL_TARGETS.join('|')}>] [--dry-run] [--json] --profile <name> [--with <component>]... [--without <component>]...
|
install.sh [--target <${SUPPORTED_INSTALL_TARGETS.join('|')}>] [--dry-run] [--json] --profile <name> [--with <component>]... [--without <component>]...
|
||||||
install.sh [--target <${SUPPORTED_INSTALL_TARGETS.join('|')}>] [--dry-run] [--json] --modules <id,id,...> [--with <component>]... [--without <component>]...
|
install.sh [--target <${SUPPORTED_INSTALL_TARGETS.join('|')}>] [--dry-run] [--json] --modules <id,id,...> [--with <component>]... [--without <component>]...
|
||||||
install.sh [--target <${SUPPORTED_INSTALL_TARGETS.join('|')}>] [--dry-run] [--json] --skills <skill-id[,skill-id...]>
|
install.sh [--target <${SUPPORTED_INSTALL_TARGETS.join('|')}>] [--dry-run] [--json] --skills <skill-id[,skill-id...]>
|
||||||
install.sh [--target claude] [--dry-run] [--json] --locale <locale-code>
|
install.sh [--target claude|claude-project] [--dry-run] [--json] --locale <locale-code>
|
||||||
install.sh [--dry-run] [--json] --config <path>
|
install.sh [--dry-run] [--json] --config <path>
|
||||||
|
|
||||||
Targets:
|
Targets:
|
||||||
claude (default) - Install ECC into ~/.claude/ with managed rules/skills under rules/ecc and skills/ecc
|
claude (default) - Install ECC into ~/.claude/ with managed rules/skills under rules/ecc and skills/ecc
|
||||||
|
claude-project - Install ECC into ./.claude/ (per-project) with managed rules/skills under rules/ecc and skills/ecc
|
||||||
cursor - Install rules, hooks, and bundled Cursor configs to ./.cursor/
|
cursor - Install rules, hooks, and bundled Cursor configs to ./.cursor/
|
||||||
antigravity - Install rules, workflows, skills, and agents to ./.agent/
|
antigravity - Install rules, workflows, skills, and agents to ./.agent/
|
||||||
codex - Install shared agents/config into ~/.codex/
|
codex - Install shared agents/config into ~/.codex/
|
||||||
@@ -49,8 +50,8 @@ Options:
|
|||||||
--skills <ids> Install one or more skill directories by ID, e.g. continuous-learning-v2
|
--skills <ids> Install one or more skill directories by ID, e.g. continuous-learning-v2
|
||||||
--without <component>
|
--without <component>
|
||||||
Exclude a user-facing install component
|
Exclude a user-facing install component
|
||||||
--locale <code> Install translated docs to ~/.claude/docs/<locale>/
|
--locale <code> Install translated docs to ~/.claude/docs/<locale>/ (or ./.claude/docs/<locale>/ for claude-project)
|
||||||
(claude target only; can be combined with --profile or --with)
|
(claude or claude-project target only; can be combined with --profile or --with)
|
||||||
--config <path> Load install intent from ecc-install.json
|
--config <path> Load install intent from ecc-install.json
|
||||||
--dry-run Show the install plan without copying files
|
--dry-run Show the install plan without copying files
|
||||||
--json Emit machine-readable plan/result JSON
|
--json Emit machine-readable plan/result JSON
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ const path = require('path');
|
|||||||
const { getInstallTargetAdapter, planInstallTargetScaffold } = require('./install-targets/registry');
|
const { getInstallTargetAdapter, planInstallTargetScaffold } = require('./install-targets/registry');
|
||||||
|
|
||||||
const DEFAULT_REPO_ROOT = path.join(__dirname, '../..');
|
const DEFAULT_REPO_ROOT = path.join(__dirname, '../..');
|
||||||
const SUPPORTED_INSTALL_TARGETS = ['claude', 'cursor', 'antigravity', 'codex', 'gemini', 'opencode', 'codebuddy', 'joycode', 'qwen', 'zed'];
|
const SUPPORTED_INSTALL_TARGETS = ['claude', 'claude-project', 'cursor', 'antigravity', 'codex', 'gemini', 'opencode', 'codebuddy', 'joycode', 'qwen', 'zed'];
|
||||||
const COMPONENT_FAMILY_PREFIXES = {
|
const COMPONENT_FAMILY_PREFIXES = {
|
||||||
baseline: 'baseline:',
|
baseline: 'baseline:',
|
||||||
language: 'lang:',
|
language: 'lang:',
|
||||||
@@ -43,6 +43,14 @@ const LEGACY_COMPAT_BASE_MODULE_IDS_BY_TARGET = Object.freeze({
|
|||||||
'platform-configs',
|
'platform-configs',
|
||||||
'workflow-quality',
|
'workflow-quality',
|
||||||
],
|
],
|
||||||
|
'claude-project': [
|
||||||
|
'rules-core',
|
||||||
|
'agents-core',
|
||||||
|
'commands-core',
|
||||||
|
'hooks-runtime',
|
||||||
|
'platform-configs',
|
||||||
|
'workflow-quality',
|
||||||
|
],
|
||||||
cursor: [
|
cursor: [
|
||||||
'rules-core',
|
'rules-core',
|
||||||
'agents-core',
|
'agents-core',
|
||||||
|
|||||||
91
scripts/lib/install-targets/claude-project.js
Normal file
91
scripts/lib/install-targets/claude-project.js
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const {
|
||||||
|
createInstallTargetAdapter,
|
||||||
|
createRemappedOperation,
|
||||||
|
isForeignPlatformPath,
|
||||||
|
normalizeRelativePath,
|
||||||
|
} = require('./helpers');
|
||||||
|
|
||||||
|
const CLAUDE_ECC_NAMESPACE = 'ecc';
|
||||||
|
|
||||||
|
function getClaudeManagedDestinationPath(adapter, sourceRelativePath, input) {
|
||||||
|
const normalizedSourcePath = normalizeRelativePath(sourceRelativePath);
|
||||||
|
const targetRoot = adapter.resolveRoot(input);
|
||||||
|
|
||||||
|
if (normalizedSourcePath === 'rules') {
|
||||||
|
return path.join(targetRoot, 'rules', CLAUDE_ECC_NAMESPACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normalizedSourcePath.startsWith('rules/')) {
|
||||||
|
return path.join(
|
||||||
|
targetRoot,
|
||||||
|
'rules',
|
||||||
|
CLAUDE_ECC_NAMESPACE,
|
||||||
|
normalizedSourcePath.slice('rules/'.length)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normalizedSourcePath === 'skills') {
|
||||||
|
return path.join(targetRoot, 'skills', CLAUDE_ECC_NAMESPACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normalizedSourcePath.startsWith('skills/')) {
|
||||||
|
return path.join(
|
||||||
|
targetRoot,
|
||||||
|
'skills',
|
||||||
|
CLAUDE_ECC_NAMESPACE,
|
||||||
|
normalizedSourcePath.slice('skills/'.length)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (normalizedSourcePath === 'docs' || normalizedSourcePath.startsWith('docs/')) {
|
||||||
|
return path.join(targetRoot, normalizedSourcePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = createInstallTargetAdapter({
|
||||||
|
id: 'claude-project',
|
||||||
|
target: 'claude-project',
|
||||||
|
kind: 'project',
|
||||||
|
rootSegments: ['.claude'],
|
||||||
|
installStatePathSegments: ['ecc', 'install-state.json'],
|
||||||
|
nativeRootRelativePath: '.claude-plugin',
|
||||||
|
planOperations(input, adapter) {
|
||||||
|
const modules = Array.isArray(input.modules)
|
||||||
|
? input.modules
|
||||||
|
: (input.module ? [input.module] : []);
|
||||||
|
const planningInput = {
|
||||||
|
repoRoot: input.repoRoot,
|
||||||
|
projectRoot: input.projectRoot,
|
||||||
|
homeDir: input.homeDir,
|
||||||
|
};
|
||||||
|
|
||||||
|
return modules.flatMap(module => {
|
||||||
|
const paths = Array.isArray(module.paths) ? module.paths : [];
|
||||||
|
return paths
|
||||||
|
.filter(p => !isForeignPlatformPath(p, 'claude'))
|
||||||
|
.map(sourceRelativePath => {
|
||||||
|
const managedDestinationPath = getClaudeManagedDestinationPath(
|
||||||
|
adapter,
|
||||||
|
sourceRelativePath,
|
||||||
|
planningInput
|
||||||
|
);
|
||||||
|
|
||||||
|
if (managedDestinationPath) {
|
||||||
|
return createRemappedOperation(
|
||||||
|
adapter,
|
||||||
|
module.id,
|
||||||
|
sourceRelativePath,
|
||||||
|
managedDestinationPath,
|
||||||
|
{ strategy: 'preserve-relative-path' }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return adapter.createScaffoldOperation(module.id, sourceRelativePath, planningInput);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
const antigravityProject = require('./antigravity-project');
|
const antigravityProject = require('./antigravity-project');
|
||||||
const claudeHome = require('./claude-home');
|
const claudeHome = require('./claude-home');
|
||||||
|
const claudeProject = require('./claude-project');
|
||||||
const codebuddyProject = require('./codebuddy-project');
|
const codebuddyProject = require('./codebuddy-project');
|
||||||
const codexHome = require('./codex-home');
|
const codexHome = require('./codex-home');
|
||||||
const cursorProject = require('./cursor-project');
|
const cursorProject = require('./cursor-project');
|
||||||
@@ -11,6 +12,7 @@ const zedProject = require('./zed-project');
|
|||||||
|
|
||||||
const ADAPTERS = Object.freeze([
|
const ADAPTERS = Object.freeze([
|
||||||
claudeHome,
|
claudeHome,
|
||||||
|
claudeProject,
|
||||||
cursorProject,
|
cursorProject,
|
||||||
antigravityProject,
|
antigravityProject,
|
||||||
codexHome,
|
codexHome,
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ function isMcpConfigPath(filePath) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function buildResolvedClaudeHooks(plan) {
|
function buildResolvedClaudeHooks(plan) {
|
||||||
if (!plan.adapter || plan.adapter.target !== 'claude') {
|
if (!plan.adapter || (plan.adapter.target !== 'claude' && plan.adapter.target !== 'claude-project')) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -100,8 +100,8 @@ function normalizeInstallRequest(options = {}) {
|
|||||||
`Unsupported locale: "${locale}". Supported locales: ${listSupportedLocales().join(', ')}`
|
`Unsupported locale: "${locale}". Supported locales: ${listSupportedLocales().join(', ')}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (locale && target !== 'claude') {
|
if (locale && target !== 'claude' && target !== 'claude-project') {
|
||||||
throw new Error('--locale can only be used with --target claude');
|
throw new Error('--locale can only be used with --target claude or --target claude-project');
|
||||||
}
|
}
|
||||||
const requestedIncludeComponentIds = dedupeStrings([
|
const requestedIncludeComponentIds = dedupeStrings([
|
||||||
...(config?.includeComponentIds || []),
|
...(config?.includeComponentIds || []),
|
||||||
|
|||||||
@@ -110,7 +110,22 @@ 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 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})()`;
|
function inlineSingleQuote(value) {
|
||||||
|
return `'${String(value).replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function inlineArray(values) {
|
||||||
|
return `[${values.map(inlineSingleQuote).join(',')}]`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function inlineNestedArray(values) {
|
||||||
|
return `[${values.map(inlineArray).join(',')}]`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const INLINE_PLUGIN_ROOT_SEGMENTS = inlineNestedArray(PLUGIN_ROOT_SEGMENTS);
|
||||||
|
const INLINE_PLUGIN_CACHE_SLUGS = inlineArray(PLUGIN_CACHE_SLUGS);
|
||||||
|
|
||||||
|
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 ${INLINE_PLUGIN_ROOT_SEGMENTS}){var l=p.join(d,'plugins',...s);if(f.existsSync(p.join(l,q)))return l}try{for(var g of ${INLINE_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,
|
||||||
|
|||||||
@@ -458,9 +458,12 @@ function supplyChainLocalProtectionGap({ roadmap, scripts }) {
|
|||||||
function hasCurrentLinearProgressSync({ roadmap, progressSync }) {
|
function hasCurrentLinearProgressSync({ roadmap, progressSync }) {
|
||||||
const hasOperatorProgressSurface = roadmap.includes('operator progress snapshot')
|
const hasOperatorProgressSurface = roadmap.includes('operator progress snapshot')
|
||||||
|| roadmap.includes('operator progress comment');
|
|| roadmap.includes('operator progress comment');
|
||||||
|
const hasMay19ProgressSurface = roadmap.includes('ecc-may-19-post-pr-2002-sync-64cef8f668e0')
|
||||||
|
&& roadmap.includes('a6411e3a-8c8e-4a58-adba-687e77d4c543')
|
||||||
|
&& roadmap.includes('ITO-56');
|
||||||
|
|
||||||
return roadmap.includes('Linear live sync is current')
|
return roadmap.includes('Linear live sync is current')
|
||||||
&& hasOperatorProgressSurface
|
&& (hasOperatorProgressSurface || hasMay19ProgressSurface)
|
||||||
&& includesAll(progressSync, [
|
&& includesAll(progressSync, [
|
||||||
'node scripts/work-items.js sync-github --repo <owner/repo>',
|
'node scripts/work-items.js sync-github --repo <owner/repo>',
|
||||||
'node scripts/status.js --json',
|
'node scripts/status.js --json',
|
||||||
@@ -483,6 +486,10 @@ function linearProgressStatus(context) {
|
|||||||
|
|
||||||
function linearProgressEvidence(context) {
|
function linearProgressEvidence(context) {
|
||||||
if (hasCurrentLinearProgressSync(context)) {
|
if (hasCurrentLinearProgressSync(context)) {
|
||||||
|
if (context.roadmap.includes('ecc-may-19-post-pr-2002-sync-64cef8f668e0')) {
|
||||||
|
return 'Linear live sync is current with the May 19 post-PR #2002 sync document, project comment, and active issue-lane updates; progress-sync contract defines the file-backed work-items/status path';
|
||||||
|
}
|
||||||
|
|
||||||
return 'Linear live sync and project progress surface are current; progress-sync contract defines the file-backed work-items/status path';
|
return 'Linear live sync and project progress surface are current; progress-sync contract defines the file-backed work-items/status path';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,15 +550,55 @@ function isCurrentOrComplete(status) {
|
|||||||
return status === 'current' || status === 'complete';
|
return status === 'current' || status === 'complete';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function extractGrowthBaseline(hypergrowth) {
|
||||||
|
const mrrMatch = hypergrowth.match(/\| MRR \| `([^`]+)` \| `([^`]+)` \| `([^`]+)` \|/);
|
||||||
|
|
||||||
|
if (!mrrMatch) {
|
||||||
|
return {
|
||||||
|
currentMrr: 'unknown',
|
||||||
|
targetMrr: 'unknown',
|
||||||
|
gapMrr: 'unknown',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
currentMrr: mrrMatch[1],
|
||||||
|
targetMrr: mrrMatch[2],
|
||||||
|
gapMrr: mrrMatch[3],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildGrowthSummary(rootDir) {
|
||||||
|
const hypergrowth = readText(rootDir, 'docs/releases/2.0.0/ecc-2-hypergrowth-release-command-center.md');
|
||||||
|
const partnerPack = readText(rootDir, 'docs/releases/2.0.0-rc.1/partner-sponsor-talks-pack.md');
|
||||||
|
const baseline = extractGrowthBaseline(hypergrowth || partnerPack);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...baseline,
|
||||||
|
lanes: [
|
||||||
|
'GitHub Sponsors and OSS partner sponsors',
|
||||||
|
'ECC Tools Pro subscriptions',
|
||||||
|
'consulting and implementation contracts',
|
||||||
|
'talks, podcasts, conference demos, and partner webinars',
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function buildRequirements(rootDir, platformReport) {
|
function buildRequirements(rootDir, platformReport) {
|
||||||
const roadmap = readText(rootDir, 'docs/ECC-2.0-GA-ROADMAP.md');
|
const roadmap = readText(rootDir, 'docs/ECC-2.0-GA-ROADMAP.md');
|
||||||
const publicationReadiness = readText(rootDir, 'docs/releases/2.0.0-rc.1/publication-readiness.md');
|
const publicationReadiness = readText(rootDir, 'docs/releases/2.0.0-rc.1/publication-readiness.md');
|
||||||
const namingMatrix = readText(rootDir, 'docs/releases/2.0.0-rc.1/naming-and-publication-matrix.md');
|
const namingMatrix = readText(rootDir, 'docs/releases/2.0.0-rc.1/naming-and-publication-matrix.md');
|
||||||
const releasePublicationChecklist = readText(rootDir, 'docs/releases/2.0.0-rc.1/release-name-plugin-publication-checklist-2026-05-18.md');
|
const releasePublicationChecklist = readText(rootDir, 'docs/releases/2.0.0-rc.1/release-name-plugin-publication-checklist-2026-05-18.md');
|
||||||
const releaseUrlLedger = readText(rootDir, 'docs/releases/2.0.0-rc.1/release-url-ledger-2026-05-18.md');
|
const releaseUrlLedger = readText(rootDir, 'docs/releases/2.0.0-rc.1/release-url-ledger-2026-05-19.md');
|
||||||
|
const publicationEvidenceMay19 = readText(rootDir, 'docs/releases/2.0.0-rc.1/publication-evidence-2026-05-19.md');
|
||||||
|
const hypergrowthCommandCenter = readText(rootDir, 'docs/releases/2.0.0/ecc-2-hypergrowth-release-command-center.md');
|
||||||
|
const partnerSponsorTalksPack = readText(rootDir, 'docs/releases/2.0.0-rc.1/partner-sponsor-talks-pack.md');
|
||||||
|
const releaseVideoProduction = readText(rootDir, 'docs/releases/2.0.0-rc.1/video-suite-production.md');
|
||||||
const ownerQueueCleanup = readText(rootDir, 'docs/releases/2.0.0-rc.1/owner-queue-cleanup-2026-05-18.md');
|
const ownerQueueCleanup = readText(rootDir, 'docs/releases/2.0.0-rc.1/owner-queue-cleanup-2026-05-18.md');
|
||||||
|
const ownerApprovalPacket = readText(rootDir, 'docs/releases/2.0.0-rc.1/owner-approval-packet-2026-05-19.md');
|
||||||
const previewManifest = readText(rootDir, 'docs/releases/2.0.0-rc.1/preview-pack-manifest.md');
|
const previewManifest = readText(rootDir, 'docs/releases/2.0.0-rc.1/preview-pack-manifest.md');
|
||||||
const previewPackSmoke = readText(rootDir, 'scripts/preview-pack-smoke.js');
|
const previewPackSmoke = readText(rootDir, 'scripts/preview-pack-smoke.js');
|
||||||
|
const releaseVideoSuite = readText(rootDir, 'scripts/release-video-suite.js');
|
||||||
const progressSync = readText(rootDir, 'docs/architecture/progress-sync-contract.md');
|
const progressSync = readText(rootDir, 'docs/architecture/progress-sync-contract.md');
|
||||||
const observabilityReadiness = readText(rootDir, 'docs/architecture/observability-readiness.md');
|
const observabilityReadiness = readText(rootDir, 'docs/architecture/observability-readiness.md');
|
||||||
const stalePrSalvage = readText(rootDir, 'docs/stale-pr-salvage-ledger.md');
|
const stalePrSalvage = readText(rootDir, 'docs/stale-pr-salvage-ledger.md');
|
||||||
@@ -577,6 +624,59 @@ function buildRequirements(rootDir, platformReport) {
|
|||||||
]);
|
]);
|
||||||
const hermesArtifactsReady = fileExists(rootDir, 'docs/HERMES-SETUP.md')
|
const hermesArtifactsReady = fileExists(rootDir, 'docs/HERMES-SETUP.md')
|
||||||
&& fileExists(rootDir, 'skills/hermes-imports/SKILL.md');
|
&& fileExists(rootDir, 'skills/hermes-imports/SKILL.md');
|
||||||
|
const hypergrowthCommandCenterReady = includesAll(hypergrowthCommandCenter, [
|
||||||
|
'harness-native operator system',
|
||||||
|
'$1,728/mo',
|
||||||
|
'$10,000/mo',
|
||||||
|
'Video Suite',
|
||||||
|
'Distribution Plan',
|
||||||
|
'Owner Approvals',
|
||||||
|
]) && includesAll(publicationEvidenceMay19, [
|
||||||
|
'Business baseline',
|
||||||
|
'$1,728/mo',
|
||||||
|
'$8,272/mo',
|
||||||
|
]);
|
||||||
|
const releaseVideoSuiteReady = scripts['release:video-suite'] === 'node scripts/release-video-suite.js'
|
||||||
|
&& fileExists(rootDir, 'scripts/release-video-suite.js')
|
||||||
|
&& includesAll(releaseVideoProduction, [
|
||||||
|
'ECC 2.0 Video Suite Production Manifest',
|
||||||
|
'Primary launch video',
|
||||||
|
'Self-Eval Gate',
|
||||||
|
'timeline',
|
||||||
|
])
|
||||||
|
&& includesAll(releaseVideoSuite, [
|
||||||
|
'ecc.release-video-suite.v1',
|
||||||
|
'video-source-assets-present',
|
||||||
|
'video-release-artifacts-present',
|
||||||
|
]);
|
||||||
|
const releaseVideoPublishCandidatesReady = releaseVideoSuiteReady
|
||||||
|
&& includesAll(publicationEvidenceMay19, [
|
||||||
|
'Ready true',
|
||||||
|
'15/15 source assets present',
|
||||||
|
'13/13 render, timeline, caption, EDL, and segment artifacts present',
|
||||||
|
'12/12 publish-candidate outputs present',
|
||||||
|
'zero detected black-frame segments',
|
||||||
|
'primary rough render self-eval passed',
|
||||||
|
]);
|
||||||
|
const partnerSponsorTalksReady = includesAll(partnerSponsorTalksPack, [
|
||||||
|
'Sponsor Outbound',
|
||||||
|
'Platform Partner DM',
|
||||||
|
'Consulting Intro',
|
||||||
|
'Talk And Podcast Pitch',
|
||||||
|
'GitHub Discussion Announcement',
|
||||||
|
'Do Not Send Or Publish If',
|
||||||
|
]);
|
||||||
|
const ownerApprovalPacketReady = includesAll(ownerApprovalPacket, [
|
||||||
|
'Owner Approval Packet',
|
||||||
|
'Decision Register',
|
||||||
|
'GitHub prerelease',
|
||||||
|
'npm `next` publish',
|
||||||
|
'Claude plugin tag',
|
||||||
|
'Video upload',
|
||||||
|
'Final URL Fill-In',
|
||||||
|
'Do Not Approve If',
|
||||||
|
'No outbound email, personal-account post, package publish, plugin tag, or billing announcement is authorized by this packet alone.'
|
||||||
|
]) && includesAll(previewManifest, ['owner-approval-packet-2026-05-19.md']);
|
||||||
|
|
||||||
const githubLive = !platformReport.github.skipped && platformReport.github.totals.errors === 0;
|
const githubLive = !platformReport.github.skipped && platformReport.github.totals.errors === 0;
|
||||||
const ownerWideOpenPrs = extractLabeledCount(ownerQueueCleanup, 'Owner-wide open PRs after cleanup');
|
const ownerWideOpenPrs = extractLabeledCount(ownerQueueCleanup, 'Owner-wide open PRs after cleanup');
|
||||||
@@ -685,11 +785,12 @@ function buildRequirements(rootDir, platformReport) {
|
|||||||
'naming-and-publication-matrix plus release-name-plugin-publication checklist plus publication-readiness',
|
'naming-and-publication-matrix plus release-name-plugin-publication checklist plus publication-readiness',
|
||||||
includesAll(namingMatrix, ['Claude plugin', 'Codex plugin', 'npm package', 'Publication Paths'])
|
includesAll(namingMatrix, ['Claude plugin', 'Codex plugin', 'npm package', 'Publication Paths'])
|
||||||
&& includesAll(releasePublicationChecklist, [
|
&& includesAll(releasePublicationChecklist, [
|
||||||
'Everything Claude Code (ECC)',
|
'Ship `v2.0.0-rc.1` as **ECC**',
|
||||||
|
'affaan-m/ECC',
|
||||||
'ecc-universal',
|
'ecc-universal',
|
||||||
'claude plugin tag .claude-plugin --dry-run',
|
'claude plugin tag .claude-plugin --dry-run',
|
||||||
'codex plugin marketplace add',
|
'codex plugin marketplace add',
|
||||||
'Do not rename the repo or package until rc.1 is published'
|
'Do not rename the npm package until rc.1 is published'
|
||||||
])
|
])
|
||||||
&& includesAll(publicationReadiness, ['Claude plugin', 'Codex plugin'])
|
&& includesAll(publicationReadiness, ['Claude plugin', 'Codex plugin'])
|
||||||
? 'in_progress'
|
? 'in_progress'
|
||||||
@@ -713,6 +814,58 @@ function buildRequirements(rootDir, platformReport) {
|
|||||||
? 'final live release/npm/plugin/billing URLs and publish approval still pending'
|
? 'final live release/npm/plugin/billing URLs and publish approval still pending'
|
||||||
: 'URL-backed refresh and publish approval still pending'
|
: 'URL-backed refresh and publish approval still pending'
|
||||||
),
|
),
|
||||||
|
buildRequirement(
|
||||||
|
'owner-approval-packet',
|
||||||
|
'Prepare final owner approval packet',
|
||||||
|
'docs/releases/2.0.0-rc.1/owner-approval-packet-2026-05-19.md',
|
||||||
|
ownerApprovalPacketReady ? 'current' : 'not_complete',
|
||||||
|
ownerApprovalPacketReady
|
||||||
|
? 'owner approval packet covers release, package, plugin, video, billing, social, and outbound decisions'
|
||||||
|
: 'owner approval packet is missing or incomplete',
|
||||||
|
ownerApprovalPacketReady
|
||||||
|
? 'review owner approvals from the final release commit before any publication or outbound action'
|
||||||
|
: 'add the owner decision sheet before publication review'
|
||||||
|
),
|
||||||
|
buildRequirement(
|
||||||
|
'hypergrowth-command-center',
|
||||||
|
'Create a second-phase hypergrowth release command center',
|
||||||
|
'docs/releases/2.0.0/ecc-2-hypergrowth-release-command-center.md plus May 19 evidence',
|
||||||
|
hypergrowthCommandCenterReady ? 'current' : 'in_progress',
|
||||||
|
hypergrowthCommandCenterReady
|
||||||
|
? 'current MRR, target MRR, gap, release claim, video lane, distribution plan, and approval boundaries are in-tree'
|
||||||
|
: 'hypergrowth command center or May 19 business baseline evidence is incomplete',
|
||||||
|
hypergrowthCommandCenterReady
|
||||||
|
? 'refresh after every MRR, channel, or approval-state change before public launch'
|
||||||
|
: 'add current MRR, target gap, channel plan, video lane, and approval boundaries'
|
||||||
|
),
|
||||||
|
buildRequirement(
|
||||||
|
'release-video-suite',
|
||||||
|
'Produce the ECC 2.0 release video suite',
|
||||||
|
'docs/releases/2.0.0-rc.1/video-suite-production.md and npm run release:video-suite',
|
||||||
|
releaseVideoPublishCandidatesReady ? 'current' : releaseVideoSuiteReady ? 'in_progress' : 'not_complete',
|
||||||
|
releaseVideoPublishCandidatesReady
|
||||||
|
? 'video-suite gate is ready with 15/15 source assets, 13/13 suite artifacts, 12/12 publish candidates, primary self-eval, and zero detected black-frame segments recorded in May 19 evidence'
|
||||||
|
: releaseVideoSuiteReady
|
||||||
|
? 'video production manifest and deterministic video-suite gate are wired for launch video, short clips, captions, timeline, and self-eval evidence'
|
||||||
|
: 'video production manifest or release:video-suite gate is incomplete',
|
||||||
|
releaseVideoPublishCandidatesReady
|
||||||
|
? 'final owner approval, upload, and public video URLs remain approval-gated'
|
||||||
|
: releaseVideoSuiteReady
|
||||||
|
? 'render final owner-approved MP4s, captions, platform reframes, and editable timeline before posting'
|
||||||
|
: 'wire release:video-suite and production manifest before final content work'
|
||||||
|
),
|
||||||
|
buildRequirement(
|
||||||
|
'partner-sponsor-talks-pack',
|
||||||
|
'Prepare sponsor, partner, consulting, podcast, talk, and Discussion copy',
|
||||||
|
'docs/releases/2.0.0-rc.1/partner-sponsor-talks-pack.md',
|
||||||
|
partnerSponsorTalksReady ? 'in_progress' : 'not_complete',
|
||||||
|
partnerSponsorTalksReady
|
||||||
|
? 'sponsor outbound, platform partner DM, consulting intro, talk/podcast pitch, GitHub Discussion announcement, CTA hooks, and do-not-send gate are drafted'
|
||||||
|
: 'partner, sponsor, consulting, talk, or discussion copy is missing',
|
||||||
|
partnerSponsorTalksReady
|
||||||
|
? 'replace final URLs after publication gates, then get explicit approval before outbound or personal-account posts'
|
||||||
|
: 'draft the full outbound pack and approval gate'
|
||||||
|
),
|
||||||
buildRequirement(
|
buildRequirement(
|
||||||
'agentshield-enterprise-iteration',
|
'agentshield-enterprise-iteration',
|
||||||
'Advance AgentShield enterprise iteration',
|
'Advance AgentShield enterprise iteration',
|
||||||
@@ -801,12 +954,18 @@ function buildReport(options) {
|
|||||||
fix: item.gap,
|
fix: item.gap,
|
||||||
}));
|
}));
|
||||||
const head = runCommand('git', ['rev-parse', 'HEAD'], { cwd: rootDir });
|
const head = runCommand('git', ['rev-parse', 'HEAD'], { cwd: rootDir });
|
||||||
|
const growth = buildGrowthSummary(rootDir);
|
||||||
|
const releaseVideoRequirement = requirements.find(item => item.id === 'release-video-suite');
|
||||||
|
const releaseVideoWorkOrder = releaseVideoRequirement && releaseVideoRequirement.status === 'current'
|
||||||
|
? 'Review the owner-approved primary launch video candidates, choose the final cuts, upload after approval, and attach public video URLs to the release pack.'
|
||||||
|
: 'Render the owner-approved primary launch video, short clips, captions, reframes, and editable timeline from the video-suite production manifest.';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
schema_version: SCHEMA_VERSION,
|
schema_version: SCHEMA_VERSION,
|
||||||
generatedAt,
|
generatedAt,
|
||||||
root: rootDir,
|
root: rootDir,
|
||||||
head,
|
head,
|
||||||
|
growth,
|
||||||
ready: incompleteRequirements.length === 0,
|
ready: incompleteRequirements.length === 0,
|
||||||
dashboardReady: platformReport.ready,
|
dashboardReady: platformReport.ready,
|
||||||
publicationReady: false,
|
publicationReady: false,
|
||||||
@@ -826,9 +985,11 @@ function buildReport(options) {
|
|||||||
top_actions: topActions,
|
top_actions: topActions,
|
||||||
next_work_order: [
|
next_work_order: [
|
||||||
'Regenerate this dashboard from the final release commit before publication evidence is recorded.',
|
'Regenerate this dashboard from the final release commit before publication evidence is recorded.',
|
||||||
|
'Review the owner approval packet from the final release commit and approve, defer, or block each publication and outbound lane.',
|
||||||
|
releaseVideoWorkOrder,
|
||||||
|
'Replace final release, npm, plugin, billing, and video URLs in the partner/sponsor/talk pack, then get explicit approval before outbound.',
|
||||||
'Repeat ITO-57 Linear/project status sync after the next significant merge batch or advisory-source refresh.',
|
'Repeat ITO-57 Linear/project status sync after the next significant merge batch or advisory-source refresh.',
|
||||||
'Create or verify Marketplace-managed Pro target billing-state with webhook provenance, configure the target account and INTERNAL_API_SECRET, then rerun target readback and the live announcement gate before publishing native-payments copy.',
|
'Create or verify Marketplace-managed Pro target billing-state with webhook provenance, configure the target account and INTERNAL_API_SECRET, then rerun target readback and the live announcement gate before publishing native-payments copy.',
|
||||||
'Resume ITO-45, ITO-46, and ITO-56 only after the generated dashboard and final release gates are refreshed.',
|
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -847,6 +1008,9 @@ function renderText(report) {
|
|||||||
`Dashboard ready: ${report.dashboardReady}`,
|
`Dashboard ready: ${report.dashboardReady}`,
|
||||||
`Publication ready: ${report.publicationReady}`,
|
`Publication ready: ${report.publicationReady}`,
|
||||||
'',
|
'',
|
||||||
|
'Growth baseline:',
|
||||||
|
` MRR: ${report.growth ? report.growth.currentMrr : 'unknown'} -> ${report.growth ? report.growth.targetMrr : 'unknown'} (gap ${report.growth ? report.growth.gapMrr : 'unknown'})`,
|
||||||
|
'',
|
||||||
'Platform:',
|
'Platform:',
|
||||||
` PRs: ${report.platform.openPrs}`,
|
` PRs: ${report.platform.openPrs}`,
|
||||||
` Issues: ${report.platform.openIssues}`,
|
` Issues: ${report.platform.openIssues}`,
|
||||||
@@ -894,6 +1058,14 @@ function renderMarkdown(report) {
|
|||||||
`| Dashboard generation | ${report.dashboardReady ? 'Current' : 'Needs work'} | platform audit ready: ${report.platform.ready}; GitHub skipped: ${report.platform.githubSkipped} |`,
|
`| Dashboard generation | ${report.dashboardReady ? 'Current' : 'Needs work'} | platform audit ready: ${report.platform.ready}; GitHub skipped: ${report.platform.githubSkipped} |`,
|
||||||
`| Publication | ${report.publicationReady ? 'Ready' : 'Not complete'} | release, npm, plugin, billing, and announcement gates are tracked below |`,
|
`| Publication | ${report.publicationReady ? 'Ready' : 'Not complete'} | release, npm, plugin, billing, and announcement gates are tracked below |`,
|
||||||
'',
|
'',
|
||||||
|
'## Growth Baseline',
|
||||||
|
'',
|
||||||
|
'| Metric | Current | Target | Gap |',
|
||||||
|
'| --- | ---: | ---: | ---: |',
|
||||||
|
`| MRR | ${markdownEscape(report.growth ? report.growth.currentMrr : 'unknown')} | ${markdownEscape(report.growth ? report.growth.targetMrr : 'unknown')} | ${markdownEscape(report.growth ? report.growth.gapMrr : 'unknown')} |`,
|
||||||
|
'',
|
||||||
|
'Growth lanes: GitHub Sponsors and OSS partner sponsors; ECC Tools Pro subscriptions; consulting and implementation contracts; talks, podcasts, conference demos, and partner webinars.',
|
||||||
|
'',
|
||||||
'## Prompt-To-Artifact Checklist',
|
'## Prompt-To-Artifact Checklist',
|
||||||
'',
|
'',
|
||||||
'| Objective requirement | Artifact or gate | Status | Evidence | Gap |',
|
'| Objective requirement | Artifact or gate | Status | Evidence | Gap |',
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const {
|
|||||||
|
|
||||||
const SCHEMA_VERSION = 'ecc.platform-audit.v1';
|
const SCHEMA_VERSION = 'ecc.platform-audit.v1';
|
||||||
const DEFAULT_REPOS = Object.freeze([
|
const DEFAULT_REPOS = Object.freeze([
|
||||||
'affaan-m/everything-claude-code',
|
'affaan-m/ECC',
|
||||||
'affaan-m/agentshield',
|
'affaan-m/agentshield',
|
||||||
'affaan-m/JARVIS',
|
'affaan-m/JARVIS',
|
||||||
'ECC-Tools/ECC-Tools',
|
'ECC-Tools/ECC-Tools',
|
||||||
@@ -426,8 +426,8 @@ function buildLocalEvidenceChecks(rootDir) {
|
|||||||
const roadmap = readText(rootDir, 'docs/ECC-2.0-GA-ROADMAP.md');
|
const roadmap = readText(rootDir, 'docs/ECC-2.0-GA-ROADMAP.md');
|
||||||
const progressSync = readText(rootDir, 'docs/architecture/progress-sync-contract.md');
|
const progressSync = readText(rootDir, 'docs/architecture/progress-sync-contract.md');
|
||||||
const supplyChain = readText(rootDir, 'docs/security/supply-chain-incident-response.md');
|
const supplyChain = readText(rootDir, 'docs/security/supply-chain-incident-response.md');
|
||||||
const evidence = readText(rootDir, 'docs/releases/2.0.0-rc.1/publication-evidence-2026-05-18.md');
|
const evidence = readText(rootDir, 'docs/releases/2.0.0-rc.1/publication-evidence-2026-05-19.md');
|
||||||
const operatorDashboard = readText(rootDir, 'docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-18.md');
|
const operatorDashboard = readText(rootDir, 'docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-19.md');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
buildCheck(
|
buildCheck(
|
||||||
@@ -472,21 +472,23 @@ function buildLocalEvidenceChecks(rootDir) {
|
|||||||
),
|
),
|
||||||
buildCheck(
|
buildCheck(
|
||||||
'release-evidence-current',
|
'release-evidence-current',
|
||||||
includesAll(evidence, ['TanStack', 'Mini Shai-Hulud', 'Home persistence IOC scan', 'Supply-Chain Watch', 'npm signatures']) ? 'pass' : 'fail',
|
includesAll(evidence, ['Release video suite', 'growth outreach', 'Operator dashboard', 'GitGuardian', 'macOS/Ubuntu/Windows test matrix', '2550 passed']) ? 'pass' : 'fail',
|
||||||
'rc.1 evidence includes current supply-chain verification artifacts',
|
'rc.1 evidence includes current release, video, growth, and CI artifacts',
|
||||||
{ path: 'docs/releases/2.0.0-rc.1/publication-evidence-2026-05-18.md' }
|
{ path: 'docs/releases/2.0.0-rc.1/publication-evidence-2026-05-19.md' }
|
||||||
),
|
),
|
||||||
buildCheck(
|
buildCheck(
|
||||||
'operator-readiness-dashboard',
|
'operator-readiness-dashboard',
|
||||||
includesAll(operatorDashboard, [
|
includesAll(operatorDashboard, [
|
||||||
'This dashboard is generated by `npm run operator:dashboard`',
|
'This dashboard is generated by `npm run operator:dashboard`',
|
||||||
|
'Growth Baseline',
|
||||||
|
'hypergrowth release command center',
|
||||||
'Prompt-To-Artifact Checklist',
|
'Prompt-To-Artifact Checklist',
|
||||||
'PR queue',
|
'PR queue',
|
||||||
'Not complete',
|
'Not complete',
|
||||||
'Next Work Order',
|
'Next Work Order',
|
||||||
]) ? 'pass' : 'fail',
|
]) ? 'pass' : 'fail',
|
||||||
'operator dashboard maps macro-goal requirements to current evidence and open gaps',
|
'operator dashboard maps macro-goal requirements to current evidence and open gaps',
|
||||||
{ path: 'docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-18.md' }
|
{ path: 'docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-19.md' }
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,9 +26,14 @@ const REQUIRED_ARTIFACTS = [
|
|||||||
`${RELEASE_DIR}/publication-evidence-2026-05-16.md`,
|
`${RELEASE_DIR}/publication-evidence-2026-05-16.md`,
|
||||||
`${RELEASE_DIR}/publication-evidence-2026-05-17.md`,
|
`${RELEASE_DIR}/publication-evidence-2026-05-17.md`,
|
||||||
`${RELEASE_DIR}/publication-evidence-2026-05-18.md`,
|
`${RELEASE_DIR}/publication-evidence-2026-05-18.md`,
|
||||||
|
`${RELEASE_DIR}/publication-evidence-2026-05-19.md`,
|
||||||
`${RELEASE_DIR}/operator-readiness-dashboard-2026-05-17.md`,
|
`${RELEASE_DIR}/operator-readiness-dashboard-2026-05-17.md`,
|
||||||
`${RELEASE_DIR}/operator-readiness-dashboard-2026-05-18.md`,
|
`${RELEASE_DIR}/operator-readiness-dashboard-2026-05-18.md`,
|
||||||
`${RELEASE_DIR}/release-url-ledger-2026-05-18.md`,
|
`${RELEASE_DIR}/operator-readiness-dashboard-2026-05-19.md`,
|
||||||
|
`${RELEASE_DIR}/owner-approval-packet-2026-05-19.md`,
|
||||||
|
`${RELEASE_DIR}/release-url-ledger-2026-05-19.md`,
|
||||||
|
`${RELEASE_DIR}/video-suite-production.md`,
|
||||||
|
`${RELEASE_DIR}/partner-sponsor-talks-pack.md`,
|
||||||
`${RELEASE_DIR}/naming-and-publication-matrix.md`,
|
`${RELEASE_DIR}/naming-and-publication-matrix.md`,
|
||||||
`${RELEASE_DIR}/release-name-plugin-publication-checklist-2026-05-18.md`,
|
`${RELEASE_DIR}/release-name-plugin-publication-checklist-2026-05-18.md`,
|
||||||
`${RELEASE_DIR}/x-thread.md`,
|
`${RELEASE_DIR}/x-thread.md`,
|
||||||
@@ -42,6 +47,7 @@ const REQUIRED_VERIFICATION_COMMANDS = [
|
|||||||
'git status --short --branch',
|
'git status --short --branch',
|
||||||
'node scripts/platform-audit.js --json',
|
'node scripts/platform-audit.js --json',
|
||||||
'npm run preview-pack:smoke',
|
'npm run preview-pack:smoke',
|
||||||
|
'npm run release:video-suite -- --format json',
|
||||||
'npm run harness:adapters -- --check',
|
'npm run harness:adapters -- --check',
|
||||||
'npm run harness:audit -- --format json',
|
'npm run harness:audit -- --format json',
|
||||||
'npm run observability:ready',
|
'npm run observability:ready',
|
||||||
|
|||||||
1096
scripts/release-video-suite.js
Normal file
1096
scripts/release-video-suite.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -52,6 +52,9 @@ const expectedReleaseFiles = [
|
|||||||
'quickstart.md',
|
'quickstart.md',
|
||||||
'preview-pack-manifest.md',
|
'preview-pack-manifest.md',
|
||||||
'publication-readiness.md',
|
'publication-readiness.md',
|
||||||
|
'video-suite-production.md',
|
||||||
|
'partner-sponsor-talks-pack.md',
|
||||||
|
'owner-approval-packet-2026-05-19.md',
|
||||||
'release-name-plugin-publication-checklist-2026-05-18.md',
|
'release-name-plugin-publication-checklist-2026-05-18.md',
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -111,12 +114,12 @@ test('business launch copy stays aligned with the rc.1 public surface', () => {
|
|||||||
'business launch copy should stay pre-publication until release URLs exist'
|
'business launch copy should stay pre-publication until release URLs exist'
|
||||||
);
|
);
|
||||||
assert.ok(
|
assert.ok(
|
||||||
source.includes('https://github.com/affaan-m/everything-claude-code'),
|
source.includes('https://github.com/affaan-m/ECC'),
|
||||||
'business launch copy should include the public repo URL'
|
'business launch copy should include the public repo URL'
|
||||||
);
|
);
|
||||||
assert.ok(
|
assert.ok(
|
||||||
source.includes(
|
source.includes(
|
||||||
'https://github.com/affaan-m/everything-claude-code/blob/main/docs/releases/2.0.0-rc.1/release-notes.md'
|
'https://github.com/affaan-m/ECC/blob/main/docs/releases/2.0.0-rc.1/release-notes.md'
|
||||||
),
|
),
|
||||||
'business launch copy should link to the rc.1 release notes'
|
'business launch copy should link to the rc.1 release notes'
|
||||||
);
|
);
|
||||||
@@ -127,6 +130,7 @@ test('business launch copy stays aligned with the rc.1 public surface', () => {
|
|||||||
test('announcement drafts avoid live-release claims before publication', () => {
|
test('announcement drafts avoid live-release claims before publication', () => {
|
||||||
const announcementFiles = [
|
const announcementFiles = [
|
||||||
'docs/releases/2.0.0-rc.1/linkedin-post.md',
|
'docs/releases/2.0.0-rc.1/linkedin-post.md',
|
||||||
|
'docs/releases/2.0.0-rc.1/partner-sponsor-talks-pack.md',
|
||||||
'docs/business/social-launch-copy.md',
|
'docs/business/social-launch-copy.md',
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -175,6 +179,10 @@ test('preview pack manifest assembles release, Hermes, and publication gates', (
|
|||||||
'scripts/preview-pack-smoke.js',
|
'scripts/preview-pack-smoke.js',
|
||||||
'docs/releases/2.0.0-rc.1/publication-readiness.md',
|
'docs/releases/2.0.0-rc.1/publication-readiness.md',
|
||||||
'docs/releases/2.0.0-rc.1/naming-and-publication-matrix.md',
|
'docs/releases/2.0.0-rc.1/naming-and-publication-matrix.md',
|
||||||
|
'docs/releases/2.0.0-rc.1/release-url-ledger-2026-05-19.md',
|
||||||
|
'docs/releases/2.0.0-rc.1/owner-approval-packet-2026-05-19.md',
|
||||||
|
'docs/releases/2.0.0-rc.1/video-suite-production.md',
|
||||||
|
'docs/releases/2.0.0-rc.1/publication-evidence-2026-05-19.md',
|
||||||
'docs/releases/2.0.0-rc.1/release-name-plugin-publication-checklist-2026-05-18.md',
|
'docs/releases/2.0.0-rc.1/release-name-plugin-publication-checklist-2026-05-18.md',
|
||||||
]) {
|
]) {
|
||||||
assert.ok(manifest.includes(artifact), `preview pack manifest missing ${artifact}`);
|
assert.ok(manifest.includes(artifact), `preview pack manifest missing ${artifact}`);
|
||||||
@@ -193,14 +201,83 @@ test('preview pack manifest assembles release, Hermes, and publication gates', (
|
|||||||
assert.ok(manifest.includes('no raw workspace exports'));
|
assert.ok(manifest.includes('no raw workspace exports'));
|
||||||
assert.ok(manifest.includes('Final Verification Commands'));
|
assert.ok(manifest.includes('Final Verification Commands'));
|
||||||
assert.ok(manifest.includes('npm run preview-pack:smoke'));
|
assert.ok(manifest.includes('npm run preview-pack:smoke'));
|
||||||
|
assert.ok(manifest.includes('npm run release:video-suite -- --format json'));
|
||||||
assert.ok(manifest.includes('Reference-Inspired Adapter Direction'));
|
assert.ok(manifest.includes('Reference-Inspired Adapter Direction'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('owner approval packet consolidates the final gated decisions', () => {
|
||||||
|
const packet = read('docs/releases/2.0.0-rc.1/owner-approval-packet-2026-05-19.md');
|
||||||
|
const manifest = read('docs/releases/2.0.0-rc.1/preview-pack-manifest.md');
|
||||||
|
const publicationReadiness = read('docs/releases/2.0.0-rc.1/publication-readiness.md');
|
||||||
|
const hypergrowth = read('docs/releases/2.0.0/ecc-2-hypergrowth-release-command-center.md');
|
||||||
|
|
||||||
|
for (const marker of [
|
||||||
|
'Owner Approval Packet',
|
||||||
|
'Source commit',
|
||||||
|
'Decision Register',
|
||||||
|
'GitHub prerelease',
|
||||||
|
'npm `next` publish',
|
||||||
|
'Claude plugin tag',
|
||||||
|
'Video upload',
|
||||||
|
'Final URL Fill-In',
|
||||||
|
'Do Not Approve If',
|
||||||
|
'No outbound email, personal-account post, package publish, plugin tag, or billing announcement is authorized by this packet alone.',
|
||||||
|
]) {
|
||||||
|
assert.ok(packet.includes(marker), `owner approval packet missing ${marker}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const command of [
|
||||||
|
'node scripts/platform-audit.js --json',
|
||||||
|
'npm run preview-pack:smoke -- --format json',
|
||||||
|
'npm run release:video-suite -- --format json',
|
||||||
|
'node tests/run-all.js',
|
||||||
|
]) {
|
||||||
|
assert.ok(packet.includes(command), `owner approval packet missing command ${command}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const urlSurface of [
|
||||||
|
'GitHub prerelease URL',
|
||||||
|
'npm rc package URL',
|
||||||
|
'Claude plugin tag URL',
|
||||||
|
'Primary launch video URL',
|
||||||
|
'ECC Tools billing/readiness URL',
|
||||||
|
]) {
|
||||||
|
assert.ok(packet.includes(urlSurface), `owner approval packet missing ${urlSurface}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.ok(manifest.includes('owner-approval-packet-2026-05-19.md'));
|
||||||
|
assert.ok(publicationReadiness.includes('owner-approval-packet-2026-05-19.md'));
|
||||||
|
assert.ok(hypergrowth.includes('owner-approval-packet-2026-05-19.md'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('GA roadmap mirrors the current May 19 release evidence', () => {
|
||||||
|
const roadmap = read('docs/ECC-2.0-GA-ROADMAP.md');
|
||||||
|
|
||||||
|
for (const marker of [
|
||||||
|
'owner-approval-packet-2026-05-19.md',
|
||||||
|
'preview-pack smoke digest `790430aef4a8`',
|
||||||
|
'local 2550-test suite',
|
||||||
|
'PR #2001',
|
||||||
|
'GitHub Actions run `26102500291`',
|
||||||
|
'PR #2002',
|
||||||
|
'GitHub Actions run `26103853507`',
|
||||||
|
'ecc-may-19-post-pr-2002-sync-64cef8f668e0',
|
||||||
|
'owner approval packet',
|
||||||
|
]) {
|
||||||
|
assert.ok(roadmap.includes(marker), `GA roadmap missing current evidence marker ${marker}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.ok(!roadmap.includes('preview-pack smoke digest `bc2bf157616e`'));
|
||||||
|
assert.ok(!roadmap.includes('local 2544-test suite'));
|
||||||
|
});
|
||||||
|
|
||||||
test('rc.1 quickstart gives a clone-to-cross-harness path', () => {
|
test('rc.1 quickstart gives a clone-to-cross-harness path', () => {
|
||||||
const quickstart = read('docs/releases/2.0.0-rc.1/quickstart.md');
|
const quickstart = read('docs/releases/2.0.0-rc.1/quickstart.md');
|
||||||
for (const heading of ['Clone', 'Install', 'Verify', 'First Skill', 'Switch Harness']) {
|
for (const heading of ['Clone', 'Install', 'Verify', 'First Skill', 'Switch Harness']) {
|
||||||
assert.ok(quickstart.includes(`## ${heading}`), `Missing ${heading} section`);
|
assert.ok(quickstart.includes(`## ${heading}`), `Missing ${heading} section`);
|
||||||
}
|
}
|
||||||
|
assert.ok(quickstart.includes('git clone https://github.com/affaan-m/ECC.git'));
|
||||||
|
assert.ok(quickstart.includes('cd ECC'));
|
||||||
assert.ok(quickstart.includes('node tests/run-all.js'));
|
assert.ok(quickstart.includes('node tests/run-all.js'));
|
||||||
assert.ok(quickstart.includes('skills/hermes-imports/SKILL.md'));
|
assert.ok(quickstart.includes('skills/hermes-imports/SKILL.md'));
|
||||||
});
|
});
|
||||||
@@ -228,6 +305,97 @@ test('launch checklist records the ecc2 alpha version policy', () => {
|
|||||||
assert.ok(!launchChecklist.includes('confirm whether `ecc2/Cargo.toml` moves'));
|
assert.ok(!launchChecklist.includes('confirm whether `ecc2/Cargo.toml` moves'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('release video suite manifest gates the content launch lane', () => {
|
||||||
|
const videoManifest = read('docs/releases/2.0.0-rc.1/video-suite-production.md');
|
||||||
|
const launchChecklist = read('docs/releases/2.0.0-rc.1/launch-checklist.md');
|
||||||
|
const hypergrowth = read('docs/releases/2.0.0/ecc-2-hypergrowth-release-command-center.md');
|
||||||
|
const packageJson = JSON.parse(read('package.json'));
|
||||||
|
|
||||||
|
for (const marker of [
|
||||||
|
'ECC 2.0 Video Suite Production Manifest',
|
||||||
|
'ECC_VIDEO_SOURCE_ROOT',
|
||||||
|
'ECC_VIDEO_RELEASE_SUITE_ROOT',
|
||||||
|
'video-use compatible workflow',
|
||||||
|
'Self-Eval Gate',
|
||||||
|
'Do Not Publish If',
|
||||||
|
'renders/ecc-2-primary-launch-rough-v1.mp4',
|
||||||
|
'timelines/primary-launch-v1.timeline.json',
|
||||||
|
'Primary launch video',
|
||||||
|
]) {
|
||||||
|
assert.ok(videoManifest.includes(marker), `video suite manifest missing ${marker}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const asset of [
|
||||||
|
'longform-full-wide.mp4',
|
||||||
|
'sf-thread-2-whatisecc.mp4',
|
||||||
|
'thread-2-ghapp-money.mp4',
|
||||||
|
'coverage-montage-wide.mp4',
|
||||||
|
'star_history.png',
|
||||||
|
'x_analytics.png',
|
||||||
|
]) {
|
||||||
|
assert.ok(videoManifest.includes(asset), `video suite manifest missing asset ${asset}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.ok(launchChecklist.includes('npm run release:video-suite -- --format json'));
|
||||||
|
assert.ok(hypergrowth.includes('Pick final video cuts, upload after approval, and attach public URLs'));
|
||||||
|
assert.strictEqual(packageJson.scripts['release:video-suite'], 'node scripts/release-video-suite.js');
|
||||||
|
assert.ok(packageJson.files.includes('scripts/release-video-suite.js'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('partner sponsor talks pack gates the hypergrowth outbound lane', () => {
|
||||||
|
const partnerPack = read('docs/releases/2.0.0-rc.1/partner-sponsor-talks-pack.md');
|
||||||
|
const manifest = read('docs/releases/2.0.0-rc.1/preview-pack-manifest.md');
|
||||||
|
const releaseNotes = read('docs/releases/2.0.0-rc.1/release-notes.md');
|
||||||
|
const launchChecklist = read('docs/releases/2.0.0-rc.1/launch-checklist.md');
|
||||||
|
const hypergrowth = read('docs/releases/2.0.0/ecc-2-hypergrowth-release-command-center.md');
|
||||||
|
|
||||||
|
for (const marker of [
|
||||||
|
'Partner, Sponsor, and Talks Pack',
|
||||||
|
'$1,728/mo',
|
||||||
|
'$10,000/mo',
|
||||||
|
'$8,272/mo',
|
||||||
|
'Pilot sponsor',
|
||||||
|
'Business sponsor',
|
||||||
|
'Strategic partner',
|
||||||
|
'Consulting sprint',
|
||||||
|
'Talk or podcast',
|
||||||
|
'Sponsor Outbound',
|
||||||
|
'Platform Partner DM',
|
||||||
|
'Consulting Intro',
|
||||||
|
'Talk And Podcast Pitch',
|
||||||
|
'GitHub Discussion Announcement',
|
||||||
|
'Video CTA Hooks',
|
||||||
|
'Do Not Send Or Publish If',
|
||||||
|
'The user has not approved outbound sponsor, partner, consulting, or media',
|
||||||
|
]) {
|
||||||
|
assert.ok(partnerPack.includes(marker), `partner pack missing ${marker}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.ok(partnerPack.includes('SPONSORS.md'));
|
||||||
|
assert.ok(partnerPack.includes('SPONSORING.md'));
|
||||||
|
assert.ok(manifest.includes('partner-sponsor-talks-pack.md'));
|
||||||
|
assert.ok(releaseNotes.includes('partner/sponsor/talk outreach'));
|
||||||
|
assert.ok(launchChecklist.includes('partner-sponsor-talks-pack.md'));
|
||||||
|
assert.ok(hypergrowth.includes('partner-sponsor-talks-pack.md'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('release video suite public docs do not expose private media paths', () => {
|
||||||
|
const releaseVideoDocs = [
|
||||||
|
'docs/releases/2.0.0-rc.1/video-suite-production.md',
|
||||||
|
'docs/releases/2.0.0/ecc-2-hypergrowth-release-command-center.md',
|
||||||
|
];
|
||||||
|
|
||||||
|
const offenders = [];
|
||||||
|
for (const relativePath of releaseVideoDocs) {
|
||||||
|
const source = read(relativePath);
|
||||||
|
if (/\/Users\/[A-Za-z0-9._-]+|\/home\/(?!user|runner)[A-Za-z0-9._-]+/.test(source)) {
|
||||||
|
offenders.push(relativePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.deepStrictEqual(offenders, []);
|
||||||
|
});
|
||||||
|
|
||||||
test('publication readiness checklist gates public release actions on evidence', () => {
|
test('publication readiness checklist gates public release actions on evidence', () => {
|
||||||
const source = read('docs/releases/2.0.0-rc.1/publication-readiness.md');
|
const source = read('docs/releases/2.0.0-rc.1/publication-readiness.md');
|
||||||
const may15Evidence = read('docs/releases/2.0.0-rc.1/publication-evidence-2026-05-15.md');
|
const may15Evidence = read('docs/releases/2.0.0-rc.1/publication-evidence-2026-05-15.md');
|
||||||
@@ -320,15 +488,15 @@ test('release name and plugin publication checklist freezes rc.1 surfaces', () =
|
|||||||
const referenceArchitecture = read('docs/ECC-2.0-REFERENCE-ARCHITECTURE.md');
|
const referenceArchitecture = read('docs/ECC-2.0-REFERENCE-ARCHITECTURE.md');
|
||||||
|
|
||||||
for (const value of [
|
for (const value of [
|
||||||
'Everything Claude Code (ECC)',
|
'Ship `v2.0.0-rc.1` as **ECC**',
|
||||||
'`affaan-m/everything-claude-code`',
|
'`affaan-m/ECC`',
|
||||||
'`ecc-universal`',
|
'`ecc-universal`',
|
||||||
'`ecc` on npm is occupied',
|
'`ecc` on npm is occupied',
|
||||||
'`@affaan-m/ecc` is unclaimed on npm',
|
'`@affaan-m/ecc` is unclaimed on npm',
|
||||||
'Claude plugin',
|
'Claude plugin',
|
||||||
'Codex plugin',
|
'Codex plugin',
|
||||||
'do not claim official directory listing until OpenAI publishing path is available',
|
'do not claim official directory listing until OpenAI publishing path is available',
|
||||||
'Do not rename the repo or package until rc.1 is published',
|
'Do not rename the npm package until rc.1 is published',
|
||||||
'Do not announce billing, Marketplace, or native payments',
|
'Do not announce billing, Marketplace, or native payments',
|
||||||
]) {
|
]) {
|
||||||
assert.ok(checklist.includes(value), `release name/plugin checklist missing ${value}`);
|
assert.ok(checklist.includes(value), `release name/plugin checklist missing ${value}`);
|
||||||
@@ -348,6 +516,35 @@ test('release name and plugin publication checklist freezes rc.1 surfaces', () =
|
|||||||
assert.ok(referenceArchitecture.includes('Keep the release/name/plugin publication checklist current'));
|
assert.ok(referenceArchitecture.includes('Keep the release/name/plugin publication checklist current'));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('active release identity surfaces use canonical ECC repo URLs', () => {
|
||||||
|
const activeFiles = [
|
||||||
|
'README.md',
|
||||||
|
'.codex-plugin/README.md',
|
||||||
|
'.codex-plugin/plugin.json',
|
||||||
|
'.opencode/README.md',
|
||||||
|
'.opencode/package.json',
|
||||||
|
'docs/business/metrics-and-sponsorship.md',
|
||||||
|
'docs/releases/2.0.0-rc.1/quickstart.md',
|
||||||
|
'docs/releases/2.0.0-rc.1/x-thread.md',
|
||||||
|
'docs/releases/2.0.0-rc.1/publication-readiness.md',
|
||||||
|
'docs/releases/2.0.0-rc.1/naming-and-publication-matrix.md',
|
||||||
|
'docs/releases/2.0.0-rc.1/release-url-ledger-2026-05-19.md',
|
||||||
|
'ecc2/Cargo.toml',
|
||||||
|
'scripts/platform-audit.js',
|
||||||
|
'scripts/discussion-audit.js',
|
||||||
|
];
|
||||||
|
|
||||||
|
const offenders = [];
|
||||||
|
for (const relativePath of activeFiles) {
|
||||||
|
const source = read(relativePath);
|
||||||
|
if (source.includes('affaan-m/everything-claude-code')) {
|
||||||
|
offenders.push(relativePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.deepStrictEqual(offenders, []);
|
||||||
|
});
|
||||||
|
|
||||||
test('release checklist and roadmap link to publication readiness evidence gate', () => {
|
test('release checklist and roadmap link to publication readiness evidence gate', () => {
|
||||||
const launchChecklist = read('docs/releases/2.0.0-rc.1/launch-checklist.md');
|
const launchChecklist = read('docs/releases/2.0.0-rc.1/launch-checklist.md');
|
||||||
const roadmap = read('docs/ECC-2.0-GA-ROADMAP.md');
|
const roadmap = read('docs/ECC-2.0-GA-ROADMAP.md');
|
||||||
|
|||||||
@@ -2513,6 +2513,29 @@ async function runTests() {
|
|||||||
passed++;
|
passed++;
|
||||||
else failed++;
|
else failed++;
|
||||||
|
|
||||||
|
if (
|
||||||
|
test('inline hook bootstraps avoid escaped double quotes for Git Bash', () => {
|
||||||
|
const hooksPath = path.join(__dirname, '..', '..', 'hooks', 'hooks.json');
|
||||||
|
const hooks = JSON.parse(fs.readFileSync(hooksPath, 'utf8'));
|
||||||
|
|
||||||
|
for (const [eventName, hookArray] of Object.entries(hooks.hooks)) {
|
||||||
|
for (const entry of hookArray) {
|
||||||
|
for (const hook of entry.hooks) {
|
||||||
|
const commandText = Array.isArray(hook.command) ? hook.command.join(' ') : hook.command;
|
||||||
|
if (typeof commandText === 'string' && commandText.startsWith('node -e ')) {
|
||||||
|
assert.ok(
|
||||||
|
!commandText.includes('\\"'),
|
||||||
|
`${eventName}/${entry.id || entry.matcher || 'hook'} should not ship escaped double quotes in node -e payload`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
passed++;
|
||||||
|
else failed++;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
test('all hook commands use node or approved shell wrappers', () => {
|
test('all hook commands use node or approved shell wrappers', () => {
|
||||||
const hooksPath = path.join(__dirname, '..', '..', 'hooks', 'hooks.json');
|
const hooksPath = path.join(__dirname, '..', '..', 'hooks', 'hooks.json');
|
||||||
|
|||||||
@@ -997,6 +997,13 @@ async function runTests() {
|
|||||||
(Array.isArray(command) && typeof command[0] === 'string' && command[0].endsWith('.sh')) ||
|
(Array.isArray(command) && typeof command[0] === 'string' && command[0].endsWith('.sh')) ||
|
||||||
commandText.endsWith('.sh');
|
commandText.endsWith('.sh');
|
||||||
|
|
||||||
|
if (isInline) {
|
||||||
|
assert.ok(
|
||||||
|
!commandText.includes('\\"'),
|
||||||
|
`Hook command in ${hookType} should not include escaped double quotes in node -e payload: ${commandText.substring(0, 80)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
assert.ok(
|
assert.ok(
|
||||||
isInline || isFilePath || isNpx || isShellWrapper || isShellScriptPath,
|
isInline || isFilePath || isNpx || isShellWrapper || isShellScriptPath,
|
||||||
`Hook command in ${hookType} should be node -e, node script, npx, or shell wrapper/script, got: ${commandText.substring(0, 80)}`
|
`Hook command in ${hookType} should be node -e, node script, npx, or shell wrapper/script, got: ${commandText.substring(0, 80)}`
|
||||||
|
|||||||
@@ -38,8 +38,9 @@ test('skill-health command uses shared inline resolver in all shell snippets', (
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('inline resolver covers current and legacy marketplace plugin roots', () => {
|
test('inline resolver covers current and legacy marketplace plugin roots', () => {
|
||||||
assert.ok(INLINE_RESOLVE.includes('"marketplaces","ecc"'));
|
assert.ok(INLINE_RESOLVE.includes("'marketplaces','ecc'"));
|
||||||
assert.ok(INLINE_RESOLVE.includes('"marketplaces","everything-claude-code"'));
|
assert.ok(INLINE_RESOLVE.includes("'marketplaces','everything-claude-code'"));
|
||||||
|
assert.ok(!INLINE_RESOLVE.includes('\\"'), 'Inline resolver should not require escaped double quotes');
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(`Passed: ${passed}`);
|
console.log(`Passed: ${passed}`);
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ function runTests() {
|
|||||||
const adapters = listInstallTargetAdapters();
|
const adapters = listInstallTargetAdapters();
|
||||||
const targets = adapters.map(adapter => adapter.target);
|
const targets = adapters.map(adapter => adapter.target);
|
||||||
assert.ok(targets.includes('claude'), 'Should include claude target');
|
assert.ok(targets.includes('claude'), 'Should include claude target');
|
||||||
|
assert.ok(targets.includes('claude-project'), 'Should include claude-project target');
|
||||||
assert.ok(targets.includes('cursor'), 'Should include cursor target');
|
assert.ok(targets.includes('cursor'), 'Should include cursor target');
|
||||||
assert.ok(targets.includes('antigravity'), 'Should include antigravity target');
|
assert.ok(targets.includes('antigravity'), 'Should include antigravity target');
|
||||||
assert.ok(targets.includes('codex'), 'Should include codex target');
|
assert.ok(targets.includes('codex'), 'Should include codex target');
|
||||||
@@ -865,6 +866,106 @@ function runTests() {
|
|||||||
}
|
}
|
||||||
})) passed++; else failed++;
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('resolves claude-project adapter root and install-state path from project root', () => {
|
||||||
|
const adapter = getInstallTargetAdapter('claude-project');
|
||||||
|
const projectRoot = '/workspace/app';
|
||||||
|
const root = adapter.resolveRoot({ projectRoot });
|
||||||
|
const statePath = adapter.getInstallStatePath({ projectRoot });
|
||||||
|
|
||||||
|
assert.strictEqual(adapter.id, 'claude-project');
|
||||||
|
assert.strictEqual(adapter.target, 'claude-project');
|
||||||
|
assert.strictEqual(adapter.kind, 'project');
|
||||||
|
assert.strictEqual(root, path.join(projectRoot, '.claude'));
|
||||||
|
assert.strictEqual(statePath, path.join(projectRoot, '.claude', 'ecc', 'install-state.json'));
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('claude-project adapter supports lookup by target and adapter id', () => {
|
||||||
|
const byTarget = getInstallTargetAdapter('claude-project');
|
||||||
|
const byId = getInstallTargetAdapter('claude-project');
|
||||||
|
|
||||||
|
assert.strictEqual(byTarget.id, 'claude-project');
|
||||||
|
assert.strictEqual(byId.id, 'claude-project');
|
||||||
|
assert.ok(byTarget.supports('claude-project'));
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('plans claude-project rules and skills under project-scope ECC-managed subdirectories', () => {
|
||||||
|
const repoRoot = path.join(__dirname, '..', '..');
|
||||||
|
const projectRoot = '/workspace/app';
|
||||||
|
|
||||||
|
const plan = planInstallTargetScaffold({
|
||||||
|
target: 'claude-project',
|
||||||
|
repoRoot,
|
||||||
|
projectRoot,
|
||||||
|
modules: [
|
||||||
|
{
|
||||||
|
id: 'rules-core',
|
||||||
|
paths: ['rules'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'workflow-quality',
|
||||||
|
paths: ['skills/tdd-workflow'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(plan.adapter.id, 'claude-project');
|
||||||
|
assert.strictEqual(plan.targetRoot, path.join(projectRoot, '.claude'));
|
||||||
|
assert.strictEqual(plan.installStatePath, path.join(projectRoot, '.claude', 'ecc', 'install-state.json'));
|
||||||
|
assert.ok(
|
||||||
|
plan.operations.some(operation => (
|
||||||
|
normalizedRelativePath(operation.sourceRelativePath) === 'rules'
|
||||||
|
&& operation.destinationPath === path.join(projectRoot, '.claude', 'rules', 'ecc')
|
||||||
|
)),
|
||||||
|
'Should install bundled rules under project-scope rules/ecc'
|
||||||
|
);
|
||||||
|
assert.ok(
|
||||||
|
plan.operations.some(operation => (
|
||||||
|
normalizedRelativePath(operation.sourceRelativePath) === 'skills/tdd-workflow'
|
||||||
|
&& operation.destinationPath === path.join(projectRoot, '.claude', 'skills', 'ecc', 'tdd-workflow')
|
||||||
|
)),
|
||||||
|
'Should install bundled skills under project-scope skills/ecc'
|
||||||
|
);
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('claude-project skips foreign platform source paths', () => {
|
||||||
|
const repoRoot = path.join(__dirname, '..', '..');
|
||||||
|
const projectRoot = '/workspace/app';
|
||||||
|
|
||||||
|
const plan = planInstallTargetScaffold({
|
||||||
|
target: 'claude-project',
|
||||||
|
repoRoot,
|
||||||
|
projectRoot,
|
||||||
|
modules: [
|
||||||
|
{
|
||||||
|
id: 'platform-configs',
|
||||||
|
paths: ['.cursor', '.zed', 'rules'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
plan.operations.some(operation => (
|
||||||
|
normalizedRelativePath(operation.sourceRelativePath) === 'rules'
|
||||||
|
&& operation.destinationPath === path.join(projectRoot, '.claude', 'rules', 'ecc')
|
||||||
|
)),
|
||||||
|
'Should still include non-foreign rules path (guards against empty-plan regression)'
|
||||||
|
);
|
||||||
|
assert.ok(
|
||||||
|
!plan.operations.some(operation => (
|
||||||
|
normalizedRelativePath(operation.sourceRelativePath) === '.cursor'
|
||||||
|
|| normalizedRelativePath(operation.sourceRelativePath).startsWith('.cursor/')
|
||||||
|
)),
|
||||||
|
'Should skip foreign Cursor platform paths'
|
||||||
|
);
|
||||||
|
assert.ok(
|
||||||
|
!plan.operations.some(operation => (
|
||||||
|
normalizedRelativePath(operation.sourceRelativePath) === '.zed'
|
||||||
|
|| normalizedRelativePath(operation.sourceRelativePath).startsWith('.zed/')
|
||||||
|
)),
|
||||||
|
'Should skip foreign Zed platform paths'
|
||||||
|
);
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`);
|
console.log(`\nResults: Passed: ${passed}, Failed: ${failed}`);
|
||||||
process.exit(failed > 0 ? 1 : 0);
|
process.exit(failed > 0 ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -134,6 +134,11 @@ test('agent.yaml version matches package.json', () => {
|
|||||||
assert.strictEqual(match[1], expectedVersion);
|
assert.strictEqual(match[1], expectedVersion);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('agent.yaml uses canonical ECC identity', () => {
|
||||||
|
const agentYamlSource = fs.readFileSync(agentYamlPath, 'utf8');
|
||||||
|
assert.ok(/^name:\s*ecc$/m.test(agentYamlSource), 'Expected agent.yaml to use the ecc name');
|
||||||
|
});
|
||||||
|
|
||||||
test('VERSION file matches package.json', () => {
|
test('VERSION file matches package.json', () => {
|
||||||
const versionFile = fs.readFileSync(versionFilePath, 'utf8').trim();
|
const versionFile = fs.readFileSync(versionFilePath, 'utf8').trim();
|
||||||
assert.ok(versionFile, 'Expected VERSION file to be non-empty');
|
assert.ok(versionFile, 'Expected VERSION file to be non-empty');
|
||||||
@@ -149,7 +154,7 @@ test('docs/SELECTIVE-INSTALL-ARCHITECTURE.md repoVersion example matches package
|
|||||||
|
|
||||||
test('.opencode/plugins/ecc-hooks.ts active plugin banner matches package.json', () => {
|
test('.opencode/plugins/ecc-hooks.ts active plugin banner matches package.json', () => {
|
||||||
const source = fs.readFileSync(opencodeHooksPluginPath, 'utf8');
|
const source = fs.readFileSync(opencodeHooksPluginPath, 'utf8');
|
||||||
const match = source.match(new RegExp(`## Active Plugin: Everything Claude Code v(${semverPattern})`));
|
const match = source.match(new RegExp(`## Active Plugin: ECC v(${semverPattern})`));
|
||||||
assert.ok(match, 'Expected .opencode/plugins/ecc-hooks.ts to declare an active plugin banner');
|
assert.ok(match, 'Expected .opencode/plugins/ecc-hooks.ts to declare an active plugin banner');
|
||||||
assert.strictEqual(match[1], expectedVersion);
|
assert.strictEqual(match[1], expectedVersion);
|
||||||
});
|
});
|
||||||
@@ -346,6 +351,11 @@ test('codex plugin.json has interface.displayName', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('codex plugin.json uses canonical ECC repo and display name', () => {
|
||||||
|
assert.strictEqual(codexPlugin.repository, 'https://github.com/affaan-m/ECC');
|
||||||
|
assert.strictEqual(codexPlugin.interface.displayName, 'ECC');
|
||||||
|
});
|
||||||
|
|
||||||
// ── .mcp.json at plugin root ──────────────────────────────────────────────────
|
// ── .mcp.json at plugin root ──────────────────────────────────────────────────
|
||||||
// Per official docs: keep .mcp.json at plugin root, NOT inside .codex-plugin/
|
// Per official docs: keep .mcp.json at plugin root, NOT inside .codex-plugin/
|
||||||
console.log('\n=== .mcp.json (plugin root) ===\n');
|
console.log('\n=== .mcp.json (plugin root) ===\n');
|
||||||
@@ -522,6 +532,10 @@ test('.codex-plugin README uses current marketplace add flow', () => {
|
|||||||
readme.includes('codex plugin marketplace add'),
|
readme.includes('codex plugin marketplace add'),
|
||||||
'Expected .codex-plugin README to document codex plugin marketplace add',
|
'Expected .codex-plugin README to document codex plugin marketplace add',
|
||||||
);
|
);
|
||||||
|
assert.ok(
|
||||||
|
readme.includes('codex plugin marketplace add affaan-m/ECC'),
|
||||||
|
'Expected .codex-plugin README to document the canonical ECC repo marketplace source',
|
||||||
|
);
|
||||||
assert.ok(
|
assert.ok(
|
||||||
readme.includes('Official Plugin Directory publishing is coming soon'),
|
readme.includes('Official Plugin Directory publishing is coming soon'),
|
||||||
'Expected .codex-plugin README to document current official directory status',
|
'Expected .codex-plugin README to document current official directory status',
|
||||||
|
|||||||
@@ -102,10 +102,10 @@ function runTests() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const shimPath = writeGhShim(rootDir, {
|
const shimPath = writeGhShim(rootDir, {
|
||||||
[discussionEnabledGhKey('affaan-m', 'everything-claude-code')]: {
|
[discussionEnabledGhKey('affaan-m', 'ECC')]: {
|
||||||
data: { repository: { hasDiscussionsEnabled: true } }
|
data: { repository: { hasDiscussionsEnabled: true } }
|
||||||
},
|
},
|
||||||
[discussionGhKey('affaan-m', 'everything-claude-code')]: {
|
[discussionGhKey('affaan-m', 'ECC')]: {
|
||||||
data: {
|
data: {
|
||||||
repository: {
|
repository: {
|
||||||
hasDiscussionsEnabled: true,
|
hasDiscussionsEnabled: true,
|
||||||
@@ -142,7 +142,7 @@ function runTests() {
|
|||||||
const parsed = JSON.parse(run([
|
const parsed = JSON.parse(run([
|
||||||
'--json',
|
'--json',
|
||||||
'--repo',
|
'--repo',
|
||||||
'affaan-m/everything-claude-code'
|
'affaan-m/ECC'
|
||||||
], {
|
], {
|
||||||
cwd: rootDir,
|
cwd: rootDir,
|
||||||
env: {
|
env: {
|
||||||
@@ -165,10 +165,10 @@ function runTests() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const shimPath = writeGhShim(rootDir, {
|
const shimPath = writeGhShim(rootDir, {
|
||||||
[discussionEnabledGhKey('affaan-m', 'everything-claude-code')]: {
|
[discussionEnabledGhKey('affaan-m', 'ECC')]: {
|
||||||
data: { repository: { hasDiscussionsEnabled: true } }
|
data: { repository: { hasDiscussionsEnabled: true } }
|
||||||
},
|
},
|
||||||
[discussionGhKey('affaan-m', 'everything-claude-code')]: {
|
[discussionGhKey('affaan-m', 'ECC')]: {
|
||||||
data: {
|
data: {
|
||||||
repository: {
|
repository: {
|
||||||
hasDiscussionsEnabled: true,
|
hasDiscussionsEnabled: true,
|
||||||
@@ -195,7 +195,7 @@ function runTests() {
|
|||||||
const result = runProcess([
|
const result = runProcess([
|
||||||
'--json',
|
'--json',
|
||||||
'--repo',
|
'--repo',
|
||||||
'affaan-m/everything-claude-code',
|
'affaan-m/ECC',
|
||||||
'--exit-code'
|
'--exit-code'
|
||||||
], {
|
], {
|
||||||
cwd: rootDir,
|
cwd: rootDir,
|
||||||
@@ -220,10 +220,10 @@ function runTests() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const shimPath = writeGhShim(rootDir, {
|
const shimPath = writeGhShim(rootDir, {
|
||||||
[discussionEnabledGhKey('affaan-m', 'everything-claude-code')]: {
|
[discussionEnabledGhKey('affaan-m', 'ECC')]: {
|
||||||
data: { repository: { hasDiscussionsEnabled: true } }
|
data: { repository: { hasDiscussionsEnabled: true } }
|
||||||
},
|
},
|
||||||
[discussionGhKey('affaan-m', 'everything-claude-code')]: {
|
[discussionGhKey('affaan-m', 'ECC')]: {
|
||||||
data: {
|
data: {
|
||||||
repository: {
|
repository: {
|
||||||
hasDiscussionsEnabled: true,
|
hasDiscussionsEnabled: true,
|
||||||
@@ -237,7 +237,7 @@ function runTests() {
|
|||||||
'--write',
|
'--write',
|
||||||
outputPath,
|
outputPath,
|
||||||
'--repo',
|
'--repo',
|
||||||
'affaan-m/everything-claude-code'
|
'affaan-m/ECC'
|
||||||
], {
|
], {
|
||||||
cwd: rootDir,
|
cwd: rootDir,
|
||||||
env: { ECC_GH_SHIM: shimPath }
|
env: { ECC_GH_SHIM: shimPath }
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ function runTests() {
|
|||||||
const parsed = JSON.parse(run(['repo', '--format', 'json']));
|
const parsed = JSON.parse(run(['repo', '--format', 'json']));
|
||||||
|
|
||||||
assert.strictEqual(parsed.deterministic, true);
|
assert.strictEqual(parsed.deterministic, true);
|
||||||
assert.strictEqual(parsed.rubric_version, '2026-03-30');
|
assert.strictEqual(parsed.rubric_version, '2026-05-19');
|
||||||
assert.strictEqual(parsed.target_mode, 'repo');
|
assert.strictEqual(parsed.target_mode, 'repo');
|
||||||
assert.ok(parsed.overall_score >= 0);
|
assert.ok(parsed.overall_score >= 0);
|
||||||
assert.ok(parsed.max_score > 0);
|
assert.ok(parsed.max_score > 0);
|
||||||
@@ -140,6 +140,192 @@ function runTests() {
|
|||||||
assert.ok(categoryNames.includes('Eval Coverage'));
|
assert.ok(categoryNames.includes('Eval Coverage'));
|
||||||
assert.ok(categoryNames.includes('Security Guardrails'));
|
assert.ok(categoryNames.includes('Security Guardrails'));
|
||||||
assert.ok(categoryNames.includes('Cost Efficiency'));
|
assert.ok(categoryNames.includes('Cost Efficiency'));
|
||||||
|
assert.ok(categoryNames.includes('GitHub Integration'));
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('report exposes applicable_categories and category_count', () => {
|
||||||
|
const parsed = JSON.parse(run(['repo', '--format', 'json']));
|
||||||
|
|
||||||
|
assert.ok(Array.isArray(parsed.applicable_categories), 'applicable_categories must be an array');
|
||||||
|
assert.ok(parsed.applicable_categories.length > 0);
|
||||||
|
assert.strictEqual(parsed.category_count, parsed.applicable_categories.length);
|
||||||
|
for (const name of parsed.applicable_categories) {
|
||||||
|
assert.ok(parsed.categories[name].max > 0, `${name} must have max > 0 to be applicable`);
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('GitHub Integration category scores against a fully-wired consumer fixture', () => {
|
||||||
|
const homeDir = createTempDir('harness-audit-home-gh-');
|
||||||
|
const projectRoot = createTempDir('harness-audit-project-gh-');
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.mkdirSync(path.join(homeDir, '.claude', 'plugins', 'ecc', '.claude-plugin'), { recursive: true });
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(homeDir, '.claude', 'plugins', 'ecc', '.claude-plugin', 'plugin.json'),
|
||||||
|
JSON.stringify({ name: 'ecc' }, null, 2)
|
||||||
|
);
|
||||||
|
|
||||||
|
fs.mkdirSync(path.join(projectRoot, '.github', 'workflows'), { recursive: true });
|
||||||
|
fs.mkdirSync(path.join(projectRoot, '.github', 'ISSUE_TEMPLATE'), { recursive: true });
|
||||||
|
fs.writeFileSync(path.join(projectRoot, '.github', 'workflows', 'ci.yml'), 'name: ci\n');
|
||||||
|
fs.writeFileSync(path.join(projectRoot, '.github', 'PULL_REQUEST_TEMPLATE.md'), '# PR\n');
|
||||||
|
fs.writeFileSync(path.join(projectRoot, '.github', 'ISSUE_TEMPLATE', 'bug.md'), '# Bug\n');
|
||||||
|
fs.writeFileSync(path.join(projectRoot, '.github', 'CODEOWNERS'), '* @owner\n');
|
||||||
|
fs.writeFileSync(path.join(projectRoot, '.github', 'dependabot.yml'), 'version: 2\n');
|
||||||
|
fs.writeFileSync(path.join(projectRoot, 'package.json'), JSON.stringify({ name: 'gh-test' }));
|
||||||
|
|
||||||
|
const parsed = JSON.parse(run(['repo', '--format', 'json'], { cwd: projectRoot, homeDir }));
|
||||||
|
const github = parsed.categories['GitHub Integration'];
|
||||||
|
|
||||||
|
assert.ok(github, 'GitHub Integration category must exist');
|
||||||
|
assert.strictEqual(github.score, 10, `GitHub Integration should score 10/10, got ${github.score}`);
|
||||||
|
assert.strictEqual(github.earned, github.max);
|
||||||
|
assert.ok(parsed.applicable_categories.includes('GitHub Integration'));
|
||||||
|
} finally {
|
||||||
|
cleanup(homeDir);
|
||||||
|
cleanup(projectRoot);
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('provider categories are omitted unless a marker is present', () => {
|
||||||
|
const homeDir = createTempDir('harness-audit-home-no-provider-');
|
||||||
|
const projectRoot = createTempDir('harness-audit-project-no-provider-');
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.mkdirSync(path.join(homeDir, '.claude', 'plugins', 'ecc', '.claude-plugin'), { recursive: true });
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(homeDir, '.claude', 'plugins', 'ecc', '.claude-plugin', 'plugin.json'),
|
||||||
|
JSON.stringify({ name: 'ecc' }, null, 2)
|
||||||
|
);
|
||||||
|
fs.writeFileSync(path.join(projectRoot, 'package.json'), JSON.stringify({ name: 'p' }));
|
||||||
|
|
||||||
|
const parsed = JSON.parse(run(['repo', '--format', 'json'], { cwd: projectRoot, homeDir }));
|
||||||
|
|
||||||
|
assert.ok(!parsed.applicable_categories.includes('Vercel Integration'));
|
||||||
|
const vercel = parsed.categories['Vercel Integration'];
|
||||||
|
assert.ok(!vercel || vercel.max === 0, 'Vercel Integration should not contribute when no marker');
|
||||||
|
} finally {
|
||||||
|
cleanup(homeDir);
|
||||||
|
cleanup(projectRoot);
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('Vercel Integration category scores when vercel.json present', () => {
|
||||||
|
const homeDir = createTempDir('harness-audit-home-vercel-');
|
||||||
|
const projectRoot = createTempDir('harness-audit-project-vercel-');
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.mkdirSync(path.join(homeDir, '.claude', 'plugins', 'ecc', '.claude-plugin'), { recursive: true });
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(homeDir, '.claude', 'plugins', 'ecc', '.claude-plugin', 'plugin.json'),
|
||||||
|
JSON.stringify({ name: 'ecc' }, null, 2)
|
||||||
|
);
|
||||||
|
|
||||||
|
fs.mkdirSync(path.join(projectRoot, '.github', 'workflows'), { recursive: true });
|
||||||
|
fs.writeFileSync(path.join(projectRoot, 'vercel.json'), '{}\n');
|
||||||
|
fs.writeFileSync(path.join(projectRoot, '.env.example'), 'VERCEL_TOKEN=\n');
|
||||||
|
fs.writeFileSync(path.join(projectRoot, '.github', 'workflows', 'deploy.yml'), 'uses: amondnet/vercel-action@v25\n');
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(projectRoot, 'package.json'),
|
||||||
|
JSON.stringify({ name: 'p', scripts: { build: 'next build', deploy: 'vercel deploy' } })
|
||||||
|
);
|
||||||
|
|
||||||
|
const parsed = JSON.parse(run(['repo', '--format', 'json'], { cwd: projectRoot, homeDir }));
|
||||||
|
const vercel = parsed.categories['Vercel Integration'];
|
||||||
|
|
||||||
|
assert.ok(vercel, 'Vercel Integration category must exist when vercel.json present');
|
||||||
|
assert.ok(vercel.max > 0);
|
||||||
|
assert.ok(parsed.applicable_categories.includes('Vercel Integration'));
|
||||||
|
assert.strictEqual(vercel.score, 10, `Vercel should score 10/10 with full wiring, got ${vercel.score}`);
|
||||||
|
} finally {
|
||||||
|
cleanup(homeDir);
|
||||||
|
cleanup(projectRoot);
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('detector map: Netlify, Cloudflare, Fly each trigger their category', () => {
|
||||||
|
const homeDir = createTempDir('harness-audit-home-multi-');
|
||||||
|
|
||||||
|
function probe(markerFile, markerContents, expectedCategory) {
|
||||||
|
const root = createTempDir('harness-audit-project-multi-');
|
||||||
|
try {
|
||||||
|
fs.writeFileSync(path.join(root, 'package.json'), JSON.stringify({ name: 'p' }));
|
||||||
|
fs.writeFileSync(path.join(root, markerFile), markerContents);
|
||||||
|
const parsed = JSON.parse(run(['repo', '--format', 'json'], { cwd: root, homeDir }));
|
||||||
|
assert.ok(
|
||||||
|
parsed.applicable_categories.includes(expectedCategory),
|
||||||
|
`${markerFile} should activate ${expectedCategory}`
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
cleanup(root);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.mkdirSync(path.join(homeDir, '.claude', 'plugins', 'ecc', '.claude-plugin'), { recursive: true });
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(homeDir, '.claude', 'plugins', 'ecc', '.claude-plugin', 'plugin.json'),
|
||||||
|
JSON.stringify({ name: 'ecc' }, null, 2)
|
||||||
|
);
|
||||||
|
|
||||||
|
probe('netlify.toml', '[build]\n', 'Netlify Integration');
|
||||||
|
probe('wrangler.toml', 'name = "p"\n', 'Cloudflare Integration');
|
||||||
|
probe('fly.toml', 'app = "p"\n', 'Fly Integration');
|
||||||
|
} finally {
|
||||||
|
cleanup(homeDir);
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('max_score reflects only applicable categories', () => {
|
||||||
|
const homeDir = createTempDir('harness-audit-home-max-');
|
||||||
|
const noVercel = createTempDir('harness-audit-project-max-novercel-');
|
||||||
|
const withVercel = createTempDir('harness-audit-project-max-vercel-');
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.mkdirSync(path.join(homeDir, '.claude', 'plugins', 'ecc', '.claude-plugin'), { recursive: true });
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(homeDir, '.claude', 'plugins', 'ecc', '.claude-plugin', 'plugin.json'),
|
||||||
|
JSON.stringify({ name: 'ecc' }, null, 2)
|
||||||
|
);
|
||||||
|
|
||||||
|
fs.writeFileSync(path.join(noVercel, 'package.json'), JSON.stringify({ name: 'p' }));
|
||||||
|
fs.writeFileSync(path.join(withVercel, 'package.json'), JSON.stringify({ name: 'p' }));
|
||||||
|
fs.writeFileSync(path.join(withVercel, 'vercel.json'), '{}\n');
|
||||||
|
|
||||||
|
const noVercelParsed = JSON.parse(run(['repo', '--format', 'json'], { cwd: noVercel, homeDir }));
|
||||||
|
const withVercelParsed = JSON.parse(run(['repo', '--format', 'json'], { cwd: withVercel, homeDir }));
|
||||||
|
|
||||||
|
assert.ok(
|
||||||
|
withVercelParsed.max_score > noVercelParsed.max_score,
|
||||||
|
`with-vercel max_score (${withVercelParsed.max_score}) should exceed no-vercel (${noVercelParsed.max_score})`
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
cleanup(homeDir);
|
||||||
|
cleanup(noVercel);
|
||||||
|
cleanup(withVercel);
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('non-git directory does not crash the script', () => {
|
||||||
|
const homeDir = createTempDir('harness-audit-home-bare-');
|
||||||
|
const bare = createTempDir('harness-audit-project-bare-');
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.mkdirSync(path.join(homeDir, '.claude', 'plugins', 'ecc', '.claude-plugin'), { recursive: true });
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(homeDir, '.claude', 'plugins', 'ecc', '.claude-plugin', 'plugin.json'),
|
||||||
|
JSON.stringify({ name: 'ecc' }, null, 2)
|
||||||
|
);
|
||||||
|
fs.writeFileSync(path.join(bare, 'package.json'), JSON.stringify({ name: 'p' }));
|
||||||
|
|
||||||
|
const output = run(['repo', '--format', 'json'], { cwd: bare, homeDir });
|
||||||
|
const parsed = JSON.parse(output);
|
||||||
|
assert.ok(parsed.overall_score >= 0);
|
||||||
|
assert.ok(parsed.max_score > 0);
|
||||||
|
} finally {
|
||||||
|
cleanup(homeDir);
|
||||||
|
cleanup(bare);
|
||||||
|
}
|
||||||
})) passed++; else failed++;
|
})) passed++; else failed++;
|
||||||
|
|
||||||
if (test('scope filtering changes max score and check list', () => {
|
if (test('scope filtering changes max score and check list', () => {
|
||||||
@@ -251,6 +437,7 @@ function runTests() {
|
|||||||
);
|
);
|
||||||
fs.mkdirSync(path.join(projectRoot, '.claude'), { recursive: true });
|
fs.mkdirSync(path.join(projectRoot, '.claude'), { recursive: true });
|
||||||
fs.mkdirSync(path.join(projectRoot, '.github', 'workflows', 'nested'), { recursive: true });
|
fs.mkdirSync(path.join(projectRoot, '.github', 'workflows', 'nested'), { recursive: true });
|
||||||
|
fs.mkdirSync(path.join(projectRoot, '.github', 'ISSUE_TEMPLATE'), { recursive: true });
|
||||||
fs.mkdirSync(path.join(projectRoot, 'docs', 'adr'), { recursive: true });
|
fs.mkdirSync(path.join(projectRoot, 'docs', 'adr'), { recursive: true });
|
||||||
fs.mkdirSync(path.join(projectRoot, 'evals'), { recursive: true });
|
fs.mkdirSync(path.join(projectRoot, 'evals'), { recursive: true });
|
||||||
fs.mkdirSync(path.join(projectRoot, 'src'), { recursive: true });
|
fs.mkdirSync(path.join(projectRoot, 'src'), { recursive: true });
|
||||||
@@ -259,6 +446,9 @@ function runTests() {
|
|||||||
fs.writeFileSync(path.join(projectRoot, 'CLAUDE.md'), '# Consumer instructions\n');
|
fs.writeFileSync(path.join(projectRoot, 'CLAUDE.md'), '# Consumer instructions\n');
|
||||||
fs.writeFileSync(path.join(projectRoot, 'src', 'app.spec.ts'), 'test placeholder\n');
|
fs.writeFileSync(path.join(projectRoot, 'src', 'app.spec.ts'), 'test placeholder\n');
|
||||||
fs.writeFileSync(path.join(projectRoot, '.github', 'workflows', 'nested', 'ci.yaml'), 'name: ci\n');
|
fs.writeFileSync(path.join(projectRoot, '.github', 'workflows', 'nested', 'ci.yaml'), 'name: ci\n');
|
||||||
|
fs.writeFileSync(path.join(projectRoot, '.github', 'PULL_REQUEST_TEMPLATE.md'), '# PR\n');
|
||||||
|
fs.writeFileSync(path.join(projectRoot, '.github', 'ISSUE_TEMPLATE', 'bug.md'), '# Bug\n');
|
||||||
|
fs.writeFileSync(path.join(projectRoot, '.github', 'CODEOWNERS'), '* @owner\n');
|
||||||
fs.writeFileSync(path.join(projectRoot, 'docs', 'adr', '001.md'), '# Record\n');
|
fs.writeFileSync(path.join(projectRoot, 'docs', 'adr', '001.md'), '# Record\n');
|
||||||
fs.writeFileSync(path.join(projectRoot, 'evals', 'smoke.json'), '{}\n');
|
fs.writeFileSync(path.join(projectRoot, 'evals', 'smoke.json'), '{}\n');
|
||||||
fs.writeFileSync(path.join(projectRoot, '.github', 'dependabot.yml'), 'version: 2\n');
|
fs.writeFileSync(path.join(projectRoot, '.github', 'dependabot.yml'), 'version: 2\n');
|
||||||
@@ -274,7 +464,7 @@ function runTests() {
|
|||||||
|
|
||||||
const text = run(['repo'], { cwd: projectRoot, homeDir });
|
const text = run(['repo'], { cwd: projectRoot, homeDir });
|
||||||
assert.ok(text.includes(`Harness Audit (repo, consumer): ${parsed.max_score}/${parsed.max_score}`));
|
assert.ok(text.includes(`Harness Audit (repo, consumer): ${parsed.max_score}/${parsed.max_score}`));
|
||||||
assert.ok(text.includes('Checks: 11 total, 0 failing'));
|
assert.ok(text.includes('Checks: 16 total, 0 failing'));
|
||||||
assert.ok(!text.includes('Top 3 Actions:'));
|
assert.ok(!text.includes('Top 3 Actions:'));
|
||||||
|
|
||||||
const scopedText = run(['agents'], { cwd: projectRoot, homeDir });
|
const scopedText = run(['agents'], { cwd: projectRoot, homeDir });
|
||||||
|
|||||||
@@ -531,6 +531,10 @@ function runTests() {
|
|||||||
installedBashDispatcherEntry.hooks[0].command.includes('pre-bash-dispatcher.js'),
|
installedBashDispatcherEntry.hooks[0].command.includes('pre-bash-dispatcher.js'),
|
||||||
'hooks/hooks.json should point the Bash preflight contract at the consolidated dispatcher'
|
'hooks/hooks.json should point the Bash preflight contract at the consolidated dispatcher'
|
||||||
);
|
);
|
||||||
|
assert.ok(
|
||||||
|
!installedBashDispatcherEntry.hooks[0].command.includes('\\"'),
|
||||||
|
'hooks/hooks.json should avoid escaped double quotes that break Windows Git Bash parsing'
|
||||||
|
);
|
||||||
assert.ok(
|
assert.ok(
|
||||||
!installedBashDispatcherEntry.hooks[0].command.includes('${CLAUDE_PLUGIN_ROOT}'),
|
!installedBashDispatcherEntry.hooks[0].command.includes('${CLAUDE_PLUGIN_ROOT}'),
|
||||||
'hooks/hooks.json should not retain raw CLAUDE_PLUGIN_ROOT shell placeholders after install'
|
'hooks/hooks.json should not retain raw CLAUDE_PLUGIN_ROOT shell placeholders after install'
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ function buildExpectedPublishPaths(repoRoot) {
|
|||||||
"scripts/operator-readiness-dashboard.js",
|
"scripts/operator-readiness-dashboard.js",
|
||||||
"scripts/platform-audit.js",
|
"scripts/platform-audit.js",
|
||||||
"scripts/preview-pack-smoke.js",
|
"scripts/preview-pack-smoke.js",
|
||||||
|
"scripts/release-video-suite.js",
|
||||||
"scripts/skill-create-output.js",
|
"scripts/skill-create-output.js",
|
||||||
"scripts/repair.js",
|
"scripts/repair.js",
|
||||||
"scripts/harness-adapter-compliance.js",
|
"scripts/harness-adapter-compliance.js",
|
||||||
@@ -131,6 +132,7 @@ function main() {
|
|||||||
"scripts/discussion-audit.js",
|
"scripts/discussion-audit.js",
|
||||||
"scripts/operator-readiness-dashboard.js",
|
"scripts/operator-readiness-dashboard.js",
|
||||||
"scripts/preview-pack-smoke.js",
|
"scripts/preview-pack-smoke.js",
|
||||||
|
"scripts/release-video-suite.js",
|
||||||
"scripts/work-items.js",
|
"scripts/work-items.js",
|
||||||
"scripts/platform-audit.js",
|
"scripts/platform-audit.js",
|
||||||
".gemini/GEMINI.md",
|
".gemini/GEMINI.md",
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ function seedRepo(rootDir, overrides = {}) {
|
|||||||
'scripts/observability-readiness.js',
|
'scripts/observability-readiness.js',
|
||||||
'scripts/operator-readiness-dashboard.js',
|
'scripts/operator-readiness-dashboard.js',
|
||||||
'scripts/platform-audit.js',
|
'scripts/platform-audit.js',
|
||||||
'scripts/preview-pack-smoke.js'
|
'scripts/preview-pack-smoke.js',
|
||||||
|
'scripts/release-video-suite.js'
|
||||||
],
|
],
|
||||||
scripts: {
|
scripts: {
|
||||||
'discussion:audit': 'node scripts/discussion-audit.js',
|
'discussion:audit': 'node scripts/discussion-audit.js',
|
||||||
@@ -41,6 +42,7 @@ function seedRepo(rootDir, overrides = {}) {
|
|||||||
'operator:dashboard': 'node scripts/operator-readiness-dashboard.js',
|
'operator:dashboard': 'node scripts/operator-readiness-dashboard.js',
|
||||||
'platform:audit': 'node scripts/platform-audit.js',
|
'platform:audit': 'node scripts/platform-audit.js',
|
||||||
'preview-pack:smoke': 'node scripts/preview-pack-smoke.js',
|
'preview-pack:smoke': 'node scripts/preview-pack-smoke.js',
|
||||||
|
'release:video-suite': 'node scripts/release-video-suite.js',
|
||||||
'security:ioc-scan': 'node scripts/ci/scan-supply-chain-iocs.js',
|
'security:ioc-scan': 'node scripts/ci/scan-supply-chain-iocs.js',
|
||||||
'security:advisory-sources': 'node scripts/ci/supply-chain-advisory-sources.js'
|
'security:advisory-sources': 'node scripts/ci/supply-chain-advisory-sources.js'
|
||||||
}
|
}
|
||||||
@@ -52,6 +54,11 @@ function seedRepo(rootDir, overrides = {}) {
|
|||||||
'hermes-boundary-sanitized',
|
'hermes-boundary-sanitized',
|
||||||
'publication-blockers-preserved'
|
'publication-blockers-preserved'
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
|
'scripts/release-video-suite.js': [
|
||||||
|
'ecc.release-video-suite.v1',
|
||||||
|
'video-source-assets-present',
|
||||||
|
'video-release-artifacts-present'
|
||||||
|
].join('\n'),
|
||||||
'docs/ECC-2.0-GA-ROADMAP.md': [
|
'docs/ECC-2.0-GA-ROADMAP.md': [
|
||||||
'https://linear.app/itomarkets/project/ecc-platform-roadmap-52b328ee03e1',
|
'https://linear.app/itomarkets/project/ecc-platform-roadmap-52b328ee03e1',
|
||||||
'Linear ITO-44 ITO-59',
|
'Linear ITO-44 ITO-59',
|
||||||
@@ -83,18 +90,31 @@ function seedRepo(rootDir, overrides = {}) {
|
|||||||
'docs/releases/2.0.0-rc.1/publication-readiness.md': 'Claude plugin Codex plugin release-name-plugin-publication-checklist-2026-05-18.md',
|
'docs/releases/2.0.0-rc.1/publication-readiness.md': 'Claude plugin Codex plugin release-name-plugin-publication-checklist-2026-05-18.md',
|
||||||
'docs/releases/2.0.0-rc.1/naming-and-publication-matrix.md': 'Claude plugin Codex plugin npm package Publication Paths',
|
'docs/releases/2.0.0-rc.1/naming-and-publication-matrix.md': 'Claude plugin Codex plugin npm package Publication Paths',
|
||||||
'docs/releases/2.0.0-rc.1/release-name-plugin-publication-checklist-2026-05-18.md': [
|
'docs/releases/2.0.0-rc.1/release-name-plugin-publication-checklist-2026-05-18.md': [
|
||||||
'Everything Claude Code (ECC)',
|
'Ship `v2.0.0-rc.1` as **ECC**',
|
||||||
|
'affaan-m/ECC',
|
||||||
'ecc-universal',
|
'ecc-universal',
|
||||||
'claude plugin tag .claude-plugin --dry-run',
|
'claude plugin tag .claude-plugin --dry-run',
|
||||||
'codex plugin marketplace add',
|
'codex plugin marketplace add',
|
||||||
'Do not rename the repo or package until rc.1 is published'
|
'Do not rename the npm package until rc.1 is published'
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
'docs/releases/2.0.0-rc.1/preview-pack-manifest.md': [
|
'docs/releases/2.0.0-rc.1/preview-pack-manifest.md': [
|
||||||
'publication-readiness.md release-notes.md quickstart.md',
|
'publication-readiness.md release-notes.md quickstart.md',
|
||||||
'release-name-plugin-publication-checklist-2026-05-18.md',
|
'release-name-plugin-publication-checklist-2026-05-18.md',
|
||||||
|
'owner-approval-packet-2026-05-19.md',
|
||||||
'`scripts/preview-pack-smoke.js`',
|
'`scripts/preview-pack-smoke.js`',
|
||||||
'npm run preview-pack:smoke'
|
'npm run preview-pack:smoke'
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
|
'docs/releases/2.0.0-rc.1/owner-approval-packet-2026-05-19.md': [
|
||||||
|
'Owner Approval Packet',
|
||||||
|
'Decision Register',
|
||||||
|
'GitHub prerelease',
|
||||||
|
'npm `next` publish',
|
||||||
|
'Claude plugin tag',
|
||||||
|
'Video upload',
|
||||||
|
'Final URL Fill-In',
|
||||||
|
'Do Not Approve If',
|
||||||
|
'No outbound email, personal-account post, package publish, plugin tag, or billing announcement is authorized by this packet alone.'
|
||||||
|
].join('\n'),
|
||||||
'docs/releases/2.0.0-rc.1/release-notes.md': 'release notes',
|
'docs/releases/2.0.0-rc.1/release-notes.md': 'release notes',
|
||||||
'docs/releases/2.0.0-rc.1/x-thread.md': 'x thread',
|
'docs/releases/2.0.0-rc.1/x-thread.md': 'x thread',
|
||||||
'docs/releases/2.0.0-rc.1/linkedin-post.md': 'linkedin post',
|
'docs/releases/2.0.0-rc.1/linkedin-post.md': 'linkedin post',
|
||||||
@@ -108,6 +128,18 @@ function seedRepo(rootDir, overrides = {}) {
|
|||||||
'PR queue',
|
'PR queue',
|
||||||
'Not complete'
|
'Not complete'
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
|
'docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-19.md': [
|
||||||
|
'This dashboard is generated by `npm run operator:dashboard`',
|
||||||
|
'operator:dashboard',
|
||||||
|
'Growth Baseline',
|
||||||
|
'hypergrowth release command center',
|
||||||
|
'Prompt-To-Artifact Checklist',
|
||||||
|
'Next Work Order',
|
||||||
|
'ITO-44',
|
||||||
|
'ITO-59',
|
||||||
|
'PR queue',
|
||||||
|
'Not complete'
|
||||||
|
].join('\n'),
|
||||||
'docs/releases/2.0.0-rc.1/owner-queue-cleanup-2026-05-18.md': [
|
'docs/releases/2.0.0-rc.1/owner-queue-cleanup-2026-05-18.md': [
|
||||||
'Owner-wide open PRs after cleanup: 0.',
|
'Owner-wide open PRs after cleanup: 0.',
|
||||||
'Owner-wide open issues after cleanup: 0.',
|
'Owner-wide open issues after cleanup: 0.',
|
||||||
@@ -152,6 +184,38 @@ function seedRepo(rootDir, overrides = {}) {
|
|||||||
'npm signatures',
|
'npm signatures',
|
||||||
'Node IPC follow-up node-ipc IOC scan'
|
'Node IPC follow-up node-ipc IOC scan'
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
|
'docs/releases/2.0.0-rc.1/publication-evidence-2026-05-19.md': [
|
||||||
|
'Release video suite',
|
||||||
|
'growth outreach',
|
||||||
|
'Operator dashboard',
|
||||||
|
'GitGuardian',
|
||||||
|
'macOS/Ubuntu/Windows test matrix',
|
||||||
|
'2550 passed',
|
||||||
|
'Business baseline',
|
||||||
|
'$1,728/mo',
|
||||||
|
'$8,272/mo'
|
||||||
|
].join('\n'),
|
||||||
|
'docs/releases/2.0.0/ecc-2-hypergrowth-release-command-center.md': [
|
||||||
|
'harness-native operator system',
|
||||||
|
'| MRR | `$1,728/mo` | `$10,000/mo` | `$8,272/mo` |',
|
||||||
|
'Video Suite',
|
||||||
|
'Distribution Plan',
|
||||||
|
'Owner Approvals'
|
||||||
|
].join('\n'),
|
||||||
|
'docs/releases/2.0.0-rc.1/video-suite-production.md': [
|
||||||
|
'ECC 2.0 Video Suite Production Manifest',
|
||||||
|
'Primary launch video',
|
||||||
|
'Self-Eval Gate',
|
||||||
|
'timeline'
|
||||||
|
].join('\n'),
|
||||||
|
'docs/releases/2.0.0-rc.1/partner-sponsor-talks-pack.md': [
|
||||||
|
'Sponsor Outbound',
|
||||||
|
'Platform Partner DM',
|
||||||
|
'Consulting Intro',
|
||||||
|
'Talk And Podcast Pitch',
|
||||||
|
'GitHub Discussion Announcement',
|
||||||
|
'Do Not Send Or Publish If'
|
||||||
|
].join('\n'),
|
||||||
'.github/workflows/supply-chain-watch.yml': 'name: Supply-Chain Watch supply-chain-advisory-sources.js supply-chain-advisory-sources.json'
|
'.github/workflows/supply-chain-watch.yml': 'name: Supply-Chain Watch supply-chain-advisory-sources.js supply-chain-advisory-sources.json'
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -228,7 +292,7 @@ function runTests() {
|
|||||||
'--allow-untracked',
|
'--allow-untracked',
|
||||||
'docs/drafts/',
|
'docs/drafts/',
|
||||||
'--repo',
|
'--repo',
|
||||||
'affaan-m/everything-claude-code',
|
'affaan-m/ECC',
|
||||||
'--generated-at',
|
'--generated-at',
|
||||||
'2026-05-15T00:00:00.000Z'
|
'2026-05-15T00:00:00.000Z'
|
||||||
]);
|
]);
|
||||||
@@ -237,7 +301,7 @@ function runTests() {
|
|||||||
assert.strictEqual(parsed.root, path.resolve(rootDir));
|
assert.strictEqual(parsed.root, path.resolve(rootDir));
|
||||||
assert.strictEqual(parsed.skipGithub, true);
|
assert.strictEqual(parsed.skipGithub, true);
|
||||||
assert.deepStrictEqual(parsed.allowUntracked, ['docs/drafts/']);
|
assert.deepStrictEqual(parsed.allowUntracked, ['docs/drafts/']);
|
||||||
assert.deepStrictEqual(parsed.repos, ['affaan-m/everything-claude-code']);
|
assert.deepStrictEqual(parsed.repos, ['affaan-m/ECC']);
|
||||||
assert.strictEqual(parsed.generatedAt, '2026-05-15T00:00:00.000Z');
|
assert.strictEqual(parsed.generatedAt, '2026-05-15T00:00:00.000Z');
|
||||||
|
|
||||||
assert.throws(() => parseArgs(['node', 'script', '--format', 'xml']), /Invalid format/);
|
assert.throws(() => parseArgs(['node', 'script', '--format', 'xml']), /Invalid format/);
|
||||||
@@ -300,6 +364,41 @@ function runTests() {
|
|||||||
&& item.evidence.includes('release publication checklist')
|
&& item.evidence.includes('release publication checklist')
|
||||||
&& item.gap === 'real tag/push, marketplace submission, and final channel choice remain approval-gated'
|
&& item.gap === 'real tag/push, marketplace submission, and final channel choice remain approval-gated'
|
||||||
)));
|
)));
|
||||||
|
assert.deepStrictEqual(report.growth, {
|
||||||
|
currentMrr: '$1,728/mo',
|
||||||
|
targetMrr: '$10,000/mo',
|
||||||
|
gapMrr: '$8,272/mo',
|
||||||
|
lanes: [
|
||||||
|
'GitHub Sponsors and OSS partner sponsors',
|
||||||
|
'ECC Tools Pro subscriptions',
|
||||||
|
'consulting and implementation contracts',
|
||||||
|
'talks, podcasts, conference demos, and partner webinars',
|
||||||
|
],
|
||||||
|
});
|
||||||
|
assert.ok(report.requirements.some(item => (
|
||||||
|
item.id === 'hypergrowth-command-center'
|
||||||
|
&& item.status === 'current'
|
||||||
|
&& item.evidence.includes('current MRR')
|
||||||
|
&& item.gap === 'refresh after every MRR, channel, or approval-state change before public launch'
|
||||||
|
)));
|
||||||
|
assert.ok(report.requirements.some(item => (
|
||||||
|
item.id === 'release-video-suite'
|
||||||
|
&& item.status === 'in_progress'
|
||||||
|
&& item.evidence.includes('deterministic video-suite gate')
|
||||||
|
&& item.gap === 'render final owner-approved MP4s, captions, platform reframes, and editable timeline before posting'
|
||||||
|
)));
|
||||||
|
assert.ok(report.requirements.some(item => (
|
||||||
|
item.id === 'partner-sponsor-talks-pack'
|
||||||
|
&& item.status === 'in_progress'
|
||||||
|
&& item.evidence.includes('sponsor outbound')
|
||||||
|
&& item.gap === 'replace final URLs after publication gates, then get explicit approval before outbound or personal-account posts'
|
||||||
|
)));
|
||||||
|
assert.ok(report.requirements.some(item => (
|
||||||
|
item.id === 'owner-approval-packet'
|
||||||
|
&& item.status === 'current'
|
||||||
|
&& item.evidence.includes('release, package, plugin, video, billing, social, and outbound decisions')
|
||||||
|
&& item.gap === 'review owner approvals from the final release commit before any publication or outbound action'
|
||||||
|
)));
|
||||||
assert.ok(report.requirements.some(item => (
|
assert.ok(report.requirements.some(item => (
|
||||||
item.id === 'supply-chain-local-protection'
|
item.id === 'supply-chain-local-protection'
|
||||||
&& item.artifact.includes('AgentShield package-manager hardening')
|
&& item.artifact.includes('AgentShield package-manager hardening')
|
||||||
@@ -320,8 +419,12 @@ function runTests() {
|
|||||||
&& item.gap === 'repeat Linear/project status update and local work-items sync after each significant merge batch'
|
&& item.gap === 'repeat Linear/project status update and local work-items sync after each significant merge batch'
|
||||||
)));
|
)));
|
||||||
assert.ok(report.top_actions.some(item => item.id === 'naming-and-plugin-publication'));
|
assert.ok(report.top_actions.some(item => item.id === 'naming-and-plugin-publication'));
|
||||||
|
assert.ok(report.top_actions.some(item => item.id === 'release-video-suite'));
|
||||||
|
assert.ok(report.top_actions.some(item => item.id === 'partner-sponsor-talks-pack'));
|
||||||
|
assert.ok(!report.top_actions.some(item => item.id === 'owner-approval-packet'));
|
||||||
assert.ok(!report.top_actions.some(item => item.id === 'ecc-preview-pack'));
|
assert.ok(!report.top_actions.some(item => item.id === 'ecc-preview-pack'));
|
||||||
assert.ok(!report.top_actions.some(item => item.id === 'hermes-specialized-skills'));
|
assert.ok(!report.top_actions.some(item => item.id === 'hermes-specialized-skills'));
|
||||||
|
assert.ok(!report.top_actions.some(item => item.id === 'hypergrowth-command-center'));
|
||||||
assert.ok(!report.top_actions.some(item => item.id === 'legacy-salvage'));
|
assert.ok(!report.top_actions.some(item => item.id === 'legacy-salvage'));
|
||||||
assert.ok(!report.top_actions.some(item => item.id === 'linear-roadmap-and-progress'));
|
assert.ok(!report.top_actions.some(item => item.id === 'linear-roadmap-and-progress'));
|
||||||
} finally {
|
} finally {
|
||||||
@@ -329,6 +432,44 @@ function runTests() {
|
|||||||
}
|
}
|
||||||
})) passed++; else failed++;
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('release video suite moves current when publish-candidate evidence is recorded', () => {
|
||||||
|
const rootDir = createTempDir('operator-dashboard-video-current-');
|
||||||
|
|
||||||
|
try {
|
||||||
|
seedRepo(rootDir, {
|
||||||
|
'docs/releases/2.0.0-rc.1/publication-evidence-2026-05-19.md': [
|
||||||
|
'Release video suite',
|
||||||
|
'growth outreach',
|
||||||
|
'Operator dashboard',
|
||||||
|
'GitGuardian',
|
||||||
|
'macOS/Ubuntu/Windows test matrix',
|
||||||
|
'2550 passed',
|
||||||
|
'Business baseline',
|
||||||
|
'$1,728/mo',
|
||||||
|
'$8,272/mo',
|
||||||
|
'Ready true',
|
||||||
|
'15/15 source assets present',
|
||||||
|
'13/13 render, timeline, caption, EDL, and segment artifacts present',
|
||||||
|
'12/12 publish-candidate outputs present with zero detected black-frame segments',
|
||||||
|
'primary rough render self-eval passed'
|
||||||
|
].join('\n')
|
||||||
|
});
|
||||||
|
|
||||||
|
const report = buildSeededReport(rootDir);
|
||||||
|
const releaseVideo = report.requirements.find(item => item.id === 'release-video-suite');
|
||||||
|
|
||||||
|
assert.strictEqual(releaseVideo.status, 'current');
|
||||||
|
assert.ok(releaseVideo.evidence.includes('15/15 source assets'));
|
||||||
|
assert.ok(releaseVideo.evidence.includes('12/12 publish candidates'));
|
||||||
|
assert.ok(releaseVideo.evidence.includes('zero detected black-frame segments'));
|
||||||
|
assert.strictEqual(releaseVideo.gap, 'final owner approval, upload, and public video URLs remain approval-gated');
|
||||||
|
assert.ok(!report.top_actions.some(item => item.id === 'release-video-suite'));
|
||||||
|
assert.ok(report.next_work_order.some(item => item.includes('Review the owner-approved primary launch video candidates')));
|
||||||
|
} finally {
|
||||||
|
cleanup(rootDir);
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
if (test('Linear progress stays in progress until live sync evidence is mirrored', () => {
|
if (test('Linear progress stays in progress until live sync evidence is mirrored', () => {
|
||||||
const rootDir = createTempDir('operator-dashboard-linear-progress-');
|
const rootDir = createTempDir('operator-dashboard-linear-progress-');
|
||||||
|
|
||||||
@@ -395,6 +536,32 @@ function runTests() {
|
|||||||
}
|
}
|
||||||
})) passed++; else failed++;
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('owner approval packet fails closed when it is missing from the release pack', () => {
|
||||||
|
const rootDir = createTempDir('operator-dashboard-owner-packet-');
|
||||||
|
|
||||||
|
try {
|
||||||
|
seedRepo(rootDir, {
|
||||||
|
'docs/releases/2.0.0-rc.1/owner-approval-packet-2026-05-19.md': null,
|
||||||
|
'docs/releases/2.0.0-rc.1/preview-pack-manifest.md': [
|
||||||
|
'publication-readiness.md release-notes.md quickstart.md',
|
||||||
|
'release-name-plugin-publication-checklist-2026-05-18.md',
|
||||||
|
'`scripts/preview-pack-smoke.js`',
|
||||||
|
'npm run preview-pack:smoke'
|
||||||
|
].join('\n')
|
||||||
|
});
|
||||||
|
|
||||||
|
const report = buildSeededReport(rootDir);
|
||||||
|
const ownerPacket = report.requirements.find(item => item.id === 'owner-approval-packet');
|
||||||
|
|
||||||
|
assert.strictEqual(ownerPacket.status, 'not_complete');
|
||||||
|
assert.strictEqual(ownerPacket.evidence, 'owner approval packet is missing or incomplete');
|
||||||
|
assert.strictEqual(ownerPacket.gap, 'add the owner decision sheet before publication review');
|
||||||
|
assert.ok(report.top_actions.some(item => item.id === 'owner-approval-packet'));
|
||||||
|
} finally {
|
||||||
|
cleanup(rootDir);
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
if (test('AgentShield enterprise evidence covers export and policy promotion markers', () => {
|
if (test('AgentShield enterprise evidence covers export and policy promotion markers', () => {
|
||||||
const cases = [
|
const cases = [
|
||||||
{
|
{
|
||||||
@@ -518,6 +685,8 @@ function runTests() {
|
|||||||
assert.strictEqual(stdout, written);
|
assert.strictEqual(stdout, written);
|
||||||
assert.ok(written.includes('# ECC Operator Readiness Dashboard'));
|
assert.ok(written.includes('# ECC Operator Readiness Dashboard'));
|
||||||
assert.ok(written.includes('Generated: 2026-05-15T00:00:00.000Z'));
|
assert.ok(written.includes('Generated: 2026-05-15T00:00:00.000Z'));
|
||||||
|
assert.ok(written.includes('## Growth Baseline'));
|
||||||
|
assert.ok(written.includes('| MRR | $1,728/mo | $10,000/mo | $8,272/mo |'));
|
||||||
assert.ok(written.includes('## Prompt-To-Artifact Checklist'));
|
assert.ok(written.includes('## Prompt-To-Artifact Checklist'));
|
||||||
assert.ok(written.includes('Build ITO-44 completion dashboard into a repeatable command'));
|
assert.ok(written.includes('Build ITO-44 completion dashboard into a repeatable command'));
|
||||||
assert.ok(written.includes('## Next Work Order'));
|
assert.ok(written.includes('## Next Work Order'));
|
||||||
@@ -542,6 +711,7 @@ function runTests() {
|
|||||||
assert.ok(stdout.includes('work remaining'));
|
assert.ok(stdout.includes('work remaining'));
|
||||||
assert.ok(stdout.includes('Dashboard ready: true'));
|
assert.ok(stdout.includes('Dashboard ready: true'));
|
||||||
assert.ok(stdout.includes('Publication ready: false'));
|
assert.ok(stdout.includes('Publication ready: false'));
|
||||||
|
assert.ok(stdout.includes('MRR: $1,728/mo -> $10,000/mo (gap $8,272/mo)'));
|
||||||
assert.ok(stdout.includes('Top actions:'));
|
assert.ok(stdout.includes('Top actions:'));
|
||||||
assert.ok(stdout.includes('naming-and-plugin-publication'));
|
assert.ok(stdout.includes('naming-and-plugin-publication'));
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -62,15 +62,18 @@ function seedRepo(rootDir, overrides = {}) {
|
|||||||
'scan-supply-chain-iocs.js',
|
'scan-supply-chain-iocs.js',
|
||||||
'supply-chain-advisory-sources.js'
|
'supply-chain-advisory-sources.js'
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
'docs/releases/2.0.0-rc.1/publication-evidence-2026-05-18.md': [
|
'docs/releases/2.0.0-rc.1/publication-evidence-2026-05-19.md': [
|
||||||
'TanStack',
|
'Release video suite',
|
||||||
'Mini Shai-Hulud',
|
'growth outreach',
|
||||||
'Home persistence IOC scan',
|
'Operator dashboard',
|
||||||
'Supply-Chain Watch',
|
'GitGuardian',
|
||||||
'npm signatures'
|
'macOS/Ubuntu/Windows test matrix',
|
||||||
|
'2550 passed'
|
||||||
].join('\n'),
|
].join('\n'),
|
||||||
'docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-18.md': [
|
'docs/releases/2.0.0-rc.1/operator-readiness-dashboard-2026-05-19.md': [
|
||||||
'This dashboard is generated by `npm run operator:dashboard`',
|
'This dashboard is generated by `npm run operator:dashboard`',
|
||||||
|
'Growth Baseline',
|
||||||
|
'hypergrowth release command center',
|
||||||
'Prompt-To-Artifact Checklist',
|
'Prompt-To-Artifact Checklist',
|
||||||
'ITO-44',
|
'ITO-44',
|
||||||
'ITO-59',
|
'ITO-59',
|
||||||
@@ -177,7 +180,7 @@ function runTests() {
|
|||||||
`--root=${rootDir}`,
|
`--root=${rootDir}`,
|
||||||
'--json',
|
'--json',
|
||||||
'--repo',
|
'--repo',
|
||||||
'affaan-m/everything-claude-code',
|
'affaan-m/ECC',
|
||||||
'--max-open-prs',
|
'--max-open-prs',
|
||||||
'5',
|
'5',
|
||||||
'--max-open-issues',
|
'--max-open-issues',
|
||||||
@@ -188,7 +191,7 @@ function runTests() {
|
|||||||
|
|
||||||
assert.strictEqual(parsed.format, 'json');
|
assert.strictEqual(parsed.format, 'json');
|
||||||
assert.strictEqual(parsed.root, path.resolve(rootDir));
|
assert.strictEqual(parsed.root, path.resolve(rootDir));
|
||||||
assert.deepStrictEqual(parsed.repos, ['affaan-m/everything-claude-code']);
|
assert.deepStrictEqual(parsed.repos, ['affaan-m/ECC']);
|
||||||
assert.strictEqual(parsed.thresholds.maxOpenPrs, 5);
|
assert.strictEqual(parsed.thresholds.maxOpenPrs, 5);
|
||||||
assert.strictEqual(parsed.thresholds.maxOpenIssues, 6);
|
assert.strictEqual(parsed.thresholds.maxOpenIssues, 6);
|
||||||
assert.deepStrictEqual(parsed.allowUntracked, ['docs/drafts/']);
|
assert.deepStrictEqual(parsed.allowUntracked, ['docs/drafts/']);
|
||||||
@@ -217,12 +220,38 @@ function runTests() {
|
|||||||
assert.ok(parsed.checks.some(check => check.id === 'supply-chain-runbook' && check.status === 'pass'));
|
assert.ok(parsed.checks.some(check => check.id === 'supply-chain-runbook' && check.status === 'pass'));
|
||||||
assert.ok(parsed.checks.some(check => check.id === 'operator-dashboard-command' && check.status === 'pass'));
|
assert.ok(parsed.checks.some(check => check.id === 'operator-dashboard-command' && check.status === 'pass'));
|
||||||
assert.ok(parsed.checks.some(check => check.id === 'operator-readiness-dashboard' && check.status === 'pass'));
|
assert.ok(parsed.checks.some(check => check.id === 'operator-readiness-dashboard' && check.status === 'pass'));
|
||||||
|
assert.ok(parsed.checks.some(check => check.id === 'release-evidence-current' && check.status === 'pass'));
|
||||||
assert.deepStrictEqual(parsed.top_actions, []);
|
assert.deepStrictEqual(parsed.top_actions, []);
|
||||||
} finally {
|
} finally {
|
||||||
cleanup(projectRoot);
|
cleanup(projectRoot);
|
||||||
}
|
}
|
||||||
})) passed++; else failed++;
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('release evidence gate rejects stale root suite counts', () => {
|
||||||
|
const projectRoot = createTempDir('platform-audit-stale-release-evidence-');
|
||||||
|
|
||||||
|
try {
|
||||||
|
seedRepo(projectRoot, {
|
||||||
|
'docs/releases/2.0.0-rc.1/publication-evidence-2026-05-19.md': [
|
||||||
|
'Release video suite',
|
||||||
|
'growth outreach',
|
||||||
|
'Operator dashboard',
|
||||||
|
'GitGuardian',
|
||||||
|
'macOS/Ubuntu/Windows test matrix',
|
||||||
|
'2546 passed'
|
||||||
|
].join('\n')
|
||||||
|
});
|
||||||
|
|
||||||
|
const parsed = JSON.parse(run(['--format=json', `--root=${projectRoot}`, '--skip-github'], { cwd: projectRoot }));
|
||||||
|
const releaseEvidence = parsed.checks.find(check => check.id === 'release-evidence-current');
|
||||||
|
|
||||||
|
assert.strictEqual(releaseEvidence.status, 'fail');
|
||||||
|
assert.ok(parsed.top_actions.some(action => action.id === 'release-evidence-current'));
|
||||||
|
} finally {
|
||||||
|
cleanup(projectRoot);
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
if (test('markdown output can be written as an operator artifact', () => {
|
if (test('markdown output can be written as an operator artifact', () => {
|
||||||
const projectRoot = createTempDir('platform-audit-markdown-');
|
const projectRoot = createTempDir('platform-audit-markdown-');
|
||||||
const outputPath = path.join(projectRoot, 'artifacts', 'platform-audit.md');
|
const outputPath = path.join(projectRoot, 'artifacts', 'platform-audit.md');
|
||||||
@@ -256,12 +285,12 @@ function runTests() {
|
|||||||
try {
|
try {
|
||||||
seedRepo(projectRoot);
|
seedRepo(projectRoot);
|
||||||
const shimPath = writeGhShim(projectRoot, {
|
const shimPath = writeGhShim(projectRoot, {
|
||||||
'pr list --repo affaan-m/everything-claude-code --state open --json number,title,isDraft,mergeStateStatus,updatedAt,url,author': [],
|
'pr list --repo affaan-m/ECC --state open --json number,title,isDraft,mergeStateStatus,updatedAt,url,author': [],
|
||||||
'issue list --repo affaan-m/everything-claude-code --state open --json number,title,updatedAt,url,author,labels': [],
|
'issue list --repo affaan-m/ECC --state open --json number,title,updatedAt,url,author,labels': [],
|
||||||
[discussionEnabledGhKey('affaan-m', 'everything-claude-code')]: {
|
[discussionEnabledGhKey('affaan-m', 'ECC')]: {
|
||||||
data: { repository: { hasDiscussionsEnabled: true } }
|
data: { repository: { hasDiscussionsEnabled: true } }
|
||||||
},
|
},
|
||||||
[discussionGhKey('affaan-m', 'everything-claude-code')]: {
|
[discussionGhKey('affaan-m', 'ECC')]: {
|
||||||
data: {
|
data: {
|
||||||
repository: {
|
repository: {
|
||||||
hasDiscussionsEnabled: true,
|
hasDiscussionsEnabled: true,
|
||||||
@@ -289,7 +318,7 @@ function runTests() {
|
|||||||
'--format=json',
|
'--format=json',
|
||||||
`--root=${projectRoot}`,
|
`--root=${projectRoot}`,
|
||||||
'--repo',
|
'--repo',
|
||||||
'affaan-m/everything-claude-code'
|
'affaan-m/ECC'
|
||||||
], {
|
], {
|
||||||
cwd: projectRoot,
|
cwd: projectRoot,
|
||||||
env: {
|
env: {
|
||||||
@@ -325,12 +354,12 @@ function runTests() {
|
|||||||
author: { login: 'contributor' }
|
author: { login: 'contributor' }
|
||||||
}));
|
}));
|
||||||
const shimPath = writeGhShim(projectRoot, {
|
const shimPath = writeGhShim(projectRoot, {
|
||||||
'pr list --repo affaan-m/everything-claude-code --state open --json number,title,isDraft,mergeStateStatus,updatedAt,url,author': prs,
|
'pr list --repo affaan-m/ECC --state open --json number,title,isDraft,mergeStateStatus,updatedAt,url,author': prs,
|
||||||
'issue list --repo affaan-m/everything-claude-code --state open --json number,title,updatedAt,url,author,labels': [],
|
'issue list --repo affaan-m/ECC --state open --json number,title,updatedAt,url,author,labels': [],
|
||||||
[discussionEnabledGhKey('affaan-m', 'everything-claude-code')]: {
|
[discussionEnabledGhKey('affaan-m', 'ECC')]: {
|
||||||
data: { repository: { hasDiscussionsEnabled: true } }
|
data: { repository: { hasDiscussionsEnabled: true } }
|
||||||
},
|
},
|
||||||
[discussionGhKey('affaan-m', 'everything-claude-code')]: {
|
[discussionGhKey('affaan-m', 'ECC')]: {
|
||||||
data: {
|
data: {
|
||||||
repository: {
|
repository: {
|
||||||
hasDiscussionsEnabled: true,
|
hasDiscussionsEnabled: true,
|
||||||
@@ -358,7 +387,7 @@ function runTests() {
|
|||||||
'--format=json',
|
'--format=json',
|
||||||
`--root=${projectRoot}`,
|
`--root=${projectRoot}`,
|
||||||
'--repo',
|
'--repo',
|
||||||
'affaan-m/everything-claude-code',
|
'affaan-m/ECC',
|
||||||
'--max-open-prs',
|
'--max-open-prs',
|
||||||
'2'
|
'2'
|
||||||
], {
|
], {
|
||||||
|
|||||||
327
tests/scripts/release-video-suite.test.js
Normal file
327
tests/scripts/release-video-suite.test.js
Normal file
@@ -0,0 +1,327 @@
|
|||||||
|
/**
|
||||||
|
* Tests for scripts/release-video-suite.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
const assert = require('assert');
|
||||||
|
const fs = require('fs');
|
||||||
|
const os = require('os');
|
||||||
|
const path = require('path');
|
||||||
|
const { execFileSync, spawnSync } = require('child_process');
|
||||||
|
|
||||||
|
const SCRIPT = path.join(__dirname, '..', '..', 'scripts', 'release-video-suite.js');
|
||||||
|
const {
|
||||||
|
REQUIRED_PUBLISH_CANDIDATES,
|
||||||
|
REQUIRED_SOURCE_ASSETS,
|
||||||
|
REQUIRED_SUITE_ARTIFACTS,
|
||||||
|
buildReport,
|
||||||
|
parseArgs,
|
||||||
|
renderText,
|
||||||
|
summarizeReport,
|
||||||
|
} = require(SCRIPT);
|
||||||
|
|
||||||
|
function createTempDir(prefix) {
|
||||||
|
return fs.mkdtempSync(path.join(os.tmpdir(), prefix));
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanup(dirPath) {
|
||||||
|
fs.rmSync(dirPath, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
function writeFile(rootDir, relativePath, content = 'fixture') {
|
||||||
|
const targetPath = path.join(rootDir, relativePath);
|
||||||
|
fs.mkdirSync(path.dirname(targetPath), { recursive: true });
|
||||||
|
fs.writeFileSync(targetPath, content);
|
||||||
|
}
|
||||||
|
|
||||||
|
function seedRepo(rootDir, overrides = {}) {
|
||||||
|
const files = {
|
||||||
|
'package.json': JSON.stringify({
|
||||||
|
name: 'ecc-universal',
|
||||||
|
files: ['scripts/release-video-suite.js'],
|
||||||
|
scripts: {
|
||||||
|
'release:video-suite': 'node scripts/release-video-suite.js',
|
||||||
|
},
|
||||||
|
}, null, 2),
|
||||||
|
'docs/releases/2.0.0-rc.1/video-suite-production.md': [
|
||||||
|
'# ECC 2.0 Video Suite Production Manifest',
|
||||||
|
'ECC_VIDEO_SOURCE_ROOT',
|
||||||
|
'ECC_VIDEO_RELEASE_SUITE_ROOT',
|
||||||
|
'Primary launch video',
|
||||||
|
'video-use compatible workflow',
|
||||||
|
'Self-Eval Gate',
|
||||||
|
'Do Not Publish If',
|
||||||
|
'Do not commit raw footage, transcript JSON, or timeline exports',
|
||||||
|
].join('\n'),
|
||||||
|
'docs/releases/2.0.0/ecc-2-hypergrowth-release-command-center.md': [
|
||||||
|
'Keep raw absolute paths out of public docs',
|
||||||
|
'Pick final video cuts, upload after approval, and attach public URLs',
|
||||||
|
].join('\n'),
|
||||||
|
'docs/releases/2.0.0-rc.1/preview-pack-manifest.md': 'video-suite-production.md',
|
||||||
|
'docs/releases/2.0.0-rc.1/launch-checklist.md': 'release video suite',
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const [relativePath, content] of Object.entries({ ...files, ...overrides })) {
|
||||||
|
if (content === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
writeFile(rootDir, relativePath, content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function seedMedia(sourceRoot, suiteRoot) {
|
||||||
|
for (const asset of REQUIRED_SOURCE_ASSETS) {
|
||||||
|
writeFile(sourceRoot, asset.file, `source ${asset.id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const artifact of REQUIRED_SUITE_ARTIFACTS) {
|
||||||
|
writeFile(suiteRoot, artifact.relativePath, `artifact ${artifact.id}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const candidate of REQUIRED_PUBLISH_CANDIDATES) {
|
||||||
|
writeFile(suiteRoot, candidate.relativePath, `candidate ${candidate.id}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function run(args = [], options = {}) {
|
||||||
|
return execFileSync('node', [SCRIPT, ...args], {
|
||||||
|
cwd: options.cwd || path.join(__dirname, '..', '..'),
|
||||||
|
encoding: 'utf8',
|
||||||
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
|
timeout: 10000,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function runProcess(args = [], options = {}) {
|
||||||
|
return spawnSync('node', [SCRIPT, ...args], {
|
||||||
|
cwd: options.cwd || path.join(__dirname, '..', '..'),
|
||||||
|
encoding: 'utf8',
|
||||||
|
stdio: ['pipe', 'pipe', 'pipe'],
|
||||||
|
timeout: 10000,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function test(name, fn) {
|
||||||
|
try {
|
||||||
|
fn();
|
||||||
|
console.log(` PASS ${name}`);
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(` FAIL ${name}`);
|
||||||
|
console.log(` Error: ${error.message}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests() {
|
||||||
|
console.log('\n=== Testing release-video-suite.js ===\n');
|
||||||
|
|
||||||
|
let passed = 0;
|
||||||
|
let failed = 0;
|
||||||
|
|
||||||
|
if (test('parseArgs accepts release video flags and rejects invalid values', () => {
|
||||||
|
const rootDir = createTempDir('release-video-args-');
|
||||||
|
const sourceRoot = createTempDir('release-video-source-');
|
||||||
|
const suiteRoot = createTempDir('release-video-suite-');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const parsed = parseArgs([
|
||||||
|
'node',
|
||||||
|
'script',
|
||||||
|
'--json',
|
||||||
|
`--root=${rootDir}`,
|
||||||
|
'--source-root',
|
||||||
|
sourceRoot,
|
||||||
|
`--suite-root=${suiteRoot}`,
|
||||||
|
'--skip-probe',
|
||||||
|
'--summary',
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert.strictEqual(parsed.format, 'json');
|
||||||
|
assert.strictEqual(parsed.root, path.resolve(rootDir));
|
||||||
|
assert.strictEqual(parsed.sourceRoot, path.resolve(sourceRoot));
|
||||||
|
assert.strictEqual(parsed.suiteRoot, path.resolve(suiteRoot));
|
||||||
|
assert.strictEqual(parsed.skipProbe, true);
|
||||||
|
assert.strictEqual(parsed.summary, true);
|
||||||
|
|
||||||
|
assert.throws(() => parseArgs(['node', 'script', '--format', 'xml']), /Invalid format/);
|
||||||
|
assert.throws(() => parseArgs(['node', 'script', '--source-root']), /--source-root requires a value/);
|
||||||
|
assert.throws(() => parseArgs(['node', 'script', '--unknown']), /Unknown argument/);
|
||||||
|
} finally {
|
||||||
|
cleanup(rootDir);
|
||||||
|
cleanup(sourceRoot);
|
||||||
|
cleanup(suiteRoot);
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('buildReport passes with a sanitized manifest and complete local media fixture', () => {
|
||||||
|
const rootDir = createTempDir('release-video-report-');
|
||||||
|
const sourceRoot = createTempDir('release-video-source-');
|
||||||
|
const suiteRoot = createTempDir('release-video-suite-');
|
||||||
|
|
||||||
|
try {
|
||||||
|
seedRepo(rootDir);
|
||||||
|
seedMedia(sourceRoot, suiteRoot);
|
||||||
|
|
||||||
|
const report = buildReport({
|
||||||
|
root: rootDir,
|
||||||
|
sourceRoot,
|
||||||
|
suiteRoot,
|
||||||
|
skipProbe: true,
|
||||||
|
generatedAt: '2026-05-19T00:00:00.000Z',
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(report.schema_version, 'ecc.release-video-suite.v1');
|
||||||
|
assert.strictEqual(report.ready, true);
|
||||||
|
assert.strictEqual(report.mediaPathsRedacted, true);
|
||||||
|
assert.ok(report.checks.every(check => check.status === 'pass'));
|
||||||
|
assert.ok(report.checks.some(check => (
|
||||||
|
check.id === 'video-primary-render-self-eval'
|
||||||
|
&& check.summary.includes('skipped by --skip-probe')
|
||||||
|
)));
|
||||||
|
assert.strictEqual(report.sourceAssets.length, REQUIRED_SOURCE_ASSETS.length);
|
||||||
|
assert.strictEqual(report.suiteArtifacts.length, REQUIRED_SUITE_ARTIFACTS.length);
|
||||||
|
assert.strictEqual(report.publishCandidates.length, REQUIRED_PUBLISH_CANDIDATES.length);
|
||||||
|
assert.ok(renderText(report).includes('Ready: yes'));
|
||||||
|
assert.strictEqual(summarizeReport(report).sourceAssetSummary.present, REQUIRED_SOURCE_ASSETS.length);
|
||||||
|
assert.strictEqual(
|
||||||
|
summarizeReport(report).publishCandidateSummary.present,
|
||||||
|
REQUIRED_PUBLISH_CANDIDATES.length
|
||||||
|
);
|
||||||
|
} finally {
|
||||||
|
cleanup(rootDir);
|
||||||
|
cleanup(sourceRoot);
|
||||||
|
cleanup(suiteRoot);
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('publish candidate videos require visual blank-frame QA', () => {
|
||||||
|
const publishVideos = REQUIRED_PUBLISH_CANDIDATES.filter(candidate => candidate.kind === 'video');
|
||||||
|
|
||||||
|
assert.ok(publishVideos.length > 0);
|
||||||
|
assert.ok(publishVideos.every(candidate => candidate.noBlackFrames === true));
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('missing local roots keep the release video gate blocked', () => {
|
||||||
|
const rootDir = createTempDir('release-video-missing-roots-');
|
||||||
|
|
||||||
|
try {
|
||||||
|
seedRepo(rootDir);
|
||||||
|
|
||||||
|
const report = buildReport({
|
||||||
|
root: rootDir,
|
||||||
|
skipProbe: true,
|
||||||
|
generatedAt: '2026-05-19T00:00:00.000Z',
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(report.ready, false);
|
||||||
|
assert.ok(report.top_actions.some(action => action.includes('ECC_VIDEO_SOURCE_ROOT')));
|
||||||
|
assert.ok(report.top_actions.some(action => action.includes('ECC_VIDEO_RELEASE_SUITE_ROOT')));
|
||||||
|
assert.ok(report.checks.some(check => check.id === 'video-source-assets-present' && check.status === 'fail'));
|
||||||
|
assert.ok(report.checks.some(check => check.id === 'video-release-artifacts-present' && check.status === 'fail'));
|
||||||
|
assert.ok(report.checks.some(check => check.id === 'video-primary-render-self-eval' && check.status === 'fail'));
|
||||||
|
assert.ok(report.checks.some(check => check.id === 'video-publish-candidates-present' && check.status === 'fail'));
|
||||||
|
} finally {
|
||||||
|
cleanup(rootDir);
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('private media paths in public docs fail sanitization', () => {
|
||||||
|
const rootDir = createTempDir('release-video-private-path-');
|
||||||
|
const sourceRoot = createTempDir('release-video-source-');
|
||||||
|
const suiteRoot = createTempDir('release-video-suite-');
|
||||||
|
|
||||||
|
try {
|
||||||
|
seedRepo(rootDir, {
|
||||||
|
'docs/releases/2.0.0-rc.1/video-suite-production.md': [
|
||||||
|
'# ECC 2.0 Video Suite Production Manifest',
|
||||||
|
'ECC_VIDEO_SOURCE_ROOT',
|
||||||
|
'ECC_VIDEO_RELEASE_SUITE_ROOT',
|
||||||
|
'Primary launch video',
|
||||||
|
'video-use compatible workflow',
|
||||||
|
'Self-Eval Gate',
|
||||||
|
'Do Not Publish If',
|
||||||
|
'Do not commit raw footage, transcript JSON, or timeline exports',
|
||||||
|
'/Users/affoon/private-media',
|
||||||
|
].join('\n'),
|
||||||
|
});
|
||||||
|
seedMedia(sourceRoot, suiteRoot);
|
||||||
|
|
||||||
|
const report = buildReport({
|
||||||
|
root: rootDir,
|
||||||
|
sourceRoot,
|
||||||
|
suiteRoot,
|
||||||
|
skipProbe: true,
|
||||||
|
generatedAt: '2026-05-19T00:00:00.000Z',
|
||||||
|
});
|
||||||
|
|
||||||
|
assert.strictEqual(report.ready, false);
|
||||||
|
assert.ok(report.checks.some(check => check.id === 'video-suite-public-sanitization' && check.status === 'fail'));
|
||||||
|
} finally {
|
||||||
|
cleanup(rootDir);
|
||||||
|
cleanup(sourceRoot);
|
||||||
|
cleanup(suiteRoot);
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('CLI emits JSON and exits successfully for complete fixture', () => {
|
||||||
|
const rootDir = createTempDir('release-video-cli-');
|
||||||
|
const sourceRoot = createTempDir('release-video-source-');
|
||||||
|
const suiteRoot = createTempDir('release-video-suite-');
|
||||||
|
|
||||||
|
try {
|
||||||
|
seedRepo(rootDir);
|
||||||
|
seedMedia(sourceRoot, suiteRoot);
|
||||||
|
|
||||||
|
const output = run([
|
||||||
|
'--format=json',
|
||||||
|
`--root=${rootDir}`,
|
||||||
|
`--source-root=${sourceRoot}`,
|
||||||
|
`--suite-root=${suiteRoot}`,
|
||||||
|
'--skip-probe',
|
||||||
|
'--summary',
|
||||||
|
], { cwd: rootDir });
|
||||||
|
const parsed = JSON.parse(output);
|
||||||
|
|
||||||
|
assert.strictEqual(parsed.ready, true);
|
||||||
|
assert.strictEqual(parsed.sourceRootConfigured, true);
|
||||||
|
assert.strictEqual(parsed.suiteRootConfigured, true);
|
||||||
|
assert.strictEqual(parsed.sourceAssetSummary.present, REQUIRED_SOURCE_ASSETS.length);
|
||||||
|
assert.strictEqual(parsed.suiteArtifactSummary.present, REQUIRED_SUITE_ARTIFACTS.length);
|
||||||
|
assert.strictEqual(parsed.publishCandidateSummary.present, REQUIRED_PUBLISH_CANDIDATES.length);
|
||||||
|
} finally {
|
||||||
|
cleanup(rootDir);
|
||||||
|
cleanup(sourceRoot);
|
||||||
|
cleanup(suiteRoot);
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
if (test('CLI exits nonzero when media roots are missing', () => {
|
||||||
|
const rootDir = createTempDir('release-video-cli-blocked-');
|
||||||
|
|
||||||
|
try {
|
||||||
|
seedRepo(rootDir);
|
||||||
|
|
||||||
|
const result = runProcess([
|
||||||
|
'--format=json',
|
||||||
|
`--root=${rootDir}`,
|
||||||
|
'--skip-probe',
|
||||||
|
'--summary',
|
||||||
|
], { cwd: rootDir });
|
||||||
|
|
||||||
|
assert.strictEqual(result.status, 1);
|
||||||
|
const parsed = JSON.parse(result.stdout);
|
||||||
|
assert.strictEqual(parsed.ready, false);
|
||||||
|
} finally {
|
||||||
|
cleanup(rootDir);
|
||||||
|
}
|
||||||
|
})) passed++; else failed++;
|
||||||
|
|
||||||
|
console.log(`\nPassed: ${passed}`);
|
||||||
|
console.log(`Failed: ${failed}`);
|
||||||
|
|
||||||
|
process.exit(failed > 0 ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (require.main === module) {
|
||||||
|
runTests();
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user