Compare commits

..

7 Commits

Author SHA1 Message Date
Affaan Mustafa
0197d08fb5 docs: restore hero banner with ECC wordmark, v2.0.0 badge, and brand lettermark
Recreates the v1.10 hero banner design (sourced from commit 602894ef)
that PR #2225 replaced with a plain HTML header:

- Wordmark and breadcrumb now read ECC / affaan-m/ECC
- Version badge reads v2.0.0 · Jun 2026, eyebrow updated to V2.0
- Top-left mark is the actual assets/ecc-icon.svg lettermark (amber E,
  coral CC) instead of a generic coral square
- Catalog columns refreshed with live counts (261 skills, 64 agents,
  84 commands, 409 catalog) and real item names from the repo
- Harness pills updated to the current README list (Claude Code, Codex,
  Cursor, OpenCode, Gemini, Zed, Copilot)
- SVG source committed as assets/hero.svg so future edits never need
  image archaeology; rendered to PNG at 2400x1350 via sharp

README hero line restored to the markdown image; badges, sponsor table,
and guide cards from #2225 kept intact.
2026-06-11 01:15:08 -04:00
Affaan Mustafa
3bdb4a5e12 docs: restore on-brand ECC header, consolidate sponsor placement, make guide links visual (#2225)
- Replace off-brand hero PNG (wrong product name + baked version) with a
  centered HTML header using assets/ecc-icon.svg, h1, and tagline
- Consolidate duplicated sponsor sections: polished centered sponsor table
  at top (CodeRabbit, Greptile, community sponsors, sponsor links); bottom
  section reduced to a one-liner pointing to SPONSORS.md
- Convert guide links to visual cards using the guides' own header images,
  linked to the local guide files
- Fix broken tmux video URL in the shortform guide to the in-repo asset
2026-06-10 23:48:02 -04:00
dependabot[bot]
3aab460b14 chore(deps): bump the cargo-minor-and-patch group (#2207)
Bumps the cargo-minor-and-patch group in /ecc2 with 8 updates:

| Package | From | To |
| --- | --- | --- |
| [ratatui](https://github.com/ratatui/ratatui) | `0.30.0` | `0.30.1` |
| [tokio](https://github.com/tokio-rs/tokio) | `1.50.0` | `1.52.3` |
| [serde_json](https://github.com/serde-rs/json) | `1.0.149` | `1.0.150` |
| [regex](https://github.com/rust-lang/regex) | `1.12.3` | `1.12.4` |
| [clap](https://github.com/clap-rs/clap) | `4.6.0` | `4.6.1` |
| [libc](https://github.com/rust-lang/libc) | `0.2.183` | `0.2.186` |
| [chrono](https://github.com/chronotope/chrono) | `0.4.44` | `0.4.45` |
| [uuid](https://github.com/uuid-rs/uuid) | `1.22.0` | `1.23.3` |


Updates `ratatui` from 0.30.0 to 0.30.1
- [Release notes](https://github.com/ratatui/ratatui/releases)
- [Changelog](https://github.com/ratatui/ratatui/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ratatui/ratatui/compare/ratatui-v0.30.0...ratatui-v0.30.1)

Updates `tokio` from 1.50.0 to 1.52.3
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.50.0...tokio-1.52.3)

Updates `serde_json` from 1.0.149 to 1.0.150
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.149...v1.0.150)

Updates `regex` from 1.12.3 to 1.12.4
- [Release notes](https://github.com/rust-lang/regex/releases)
- [Changelog](https://github.com/rust-lang/regex/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/regex/compare/1.12.3...1.12.4)

Updates `clap` from 4.6.0 to 4.6.1
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.6.0...clap_complete-v4.6.1)

Updates `libc` from 0.2.183 to 0.2.186
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.186/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.183...0.2.186)

Updates `chrono` from 0.4.44 to 0.4.45
- [Release notes](https://github.com/chronotope/chrono/releases)
- [Changelog](https://github.com/chronotope/chrono/blob/main/CHANGELOG.md)
- [Commits](https://github.com/chronotope/chrono/compare/v0.4.44...v0.4.45)

Updates `uuid` from 1.22.0 to 1.23.3
- [Release notes](https://github.com/uuid-rs/uuid/releases)
- [Commits](https://github.com/uuid-rs/uuid/compare/v1.22.0...v1.23.3)

---
updated-dependencies:
- dependency-name: ratatui
  dependency-version: 0.30.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-minor-and-patch
- dependency-name: tokio
  dependency-version: 1.52.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: cargo-minor-and-patch
- dependency-name: serde_json
  dependency-version: 1.0.150
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-minor-and-patch
- dependency-name: regex
  dependency-version: 1.12.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-minor-and-patch
- dependency-name: clap
  dependency-version: 4.6.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-minor-and-patch
- dependency-name: libc
  dependency-version: 0.2.186
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-minor-and-patch
- dependency-name: chrono
  dependency-version: 0.4.45
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-minor-and-patch
- dependency-name: uuid
  dependency-version: 1.23.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: cargo-minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-10 23:39:05 -04:00
dependabot[bot]
7ccc65f550 chore(deps-dev): bump the npm-minor-and-patch group across 1 directory with 2 updates (#2205)
Bumps the npm-minor-and-patch group with 2 updates in the / directory: @opencode-ai/plugin and [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node).


Updates `@opencode-ai/plugin` from 1.15.3 to 1.16.2

Updates `@types/node` from 25.7.0 to 25.9.2
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node)

---
updated-dependencies:
- dependency-name: "@opencode-ai/plugin"
  dependency-version: 1.16.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-minor-and-patch
- dependency-name: "@types/node"
  dependency-version: 25.9.2
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: npm-minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-10 23:39:03 -04:00
dependabot[bot]
d71ffd56b9 chore(deps): bump actions/setup-node (#2204)
Bumps the actions-minor-and-patch group with 1 update in the / directory: [actions/setup-node](https://github.com/actions/setup-node).


Updates `actions/setup-node` from 6.3.0 to 6.4.0
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](53b83947a5...48b55a011b)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: 6.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions-minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-10 23:39:00 -04:00
ECC Test
c888d2b73f docs: update Greptile sponsor placement 2026-06-09 23:53:13 -04:00
Affaan Mustafa
ff768db363 feat(mcp): single-connector default set + connector policy (#2219)
Reduce the default .mcp.json to one connector (chrome-devtools) per the
new policy in docs/MCP-CONNECTOR-POLICY.md: a default earns its slot only
if it is universal AND MCP beats a CLI/API wrapped in a skill. June 2026
audit verdicts: github -> gh via github-ops skill; context7 -> REST via
documentation-lookup; exa -> harness-native search (+ exa-search skill);
memory -> native harness memory + instincts; playwright -> playwright CLI
skills (vendor moved agent flows off MCP); sequential-thinking -> native
extended thinking. All six remain opt-in in mcp-configs/mcp-servers.json.
Tests updated: plugin-manifest policy assertions + install-apply Cursor
expectations.

Co-authored-by: ECC Test <ecc@example.test>
2026-06-09 23:28:35 -04:00
22 changed files with 407 additions and 374 deletions

View File

@@ -49,12 +49,9 @@ stay below provider length limits.
| Server | Purpose |
|---|---|
| `github` | GitHub API access |
| `context7` | Live documentation lookup |
| `exa` | Neural web search |
| `memory` | Persistent memory across sessions |
| `playwright` | Browser automation & E2E testing |
| `sequential-thinking` | Step-by-step reasoning |
| `chrome-devtools` | Interactive browser debugging via Chrome DevTools (CDP sessions, performance traces, console/network inspection) |
The former defaults (`github`, `context7`, `exa`, `memory`, `playwright`, `sequential-thinking`) were retired in the June 2026 connector audit — their jobs are covered by skills wrapping CLIs/REST APIs or by harness-native features. They remain available as opt-in entries in `mcp-configs/mcp-servers.json`. See `docs/MCP-CONNECTOR-POLICY.md` for the policy and the per-connector rationale.
## Notes

View File

@@ -40,7 +40,7 @@ jobs:
persist-credentials: false
- name: Setup Node.js ${{ matrix.node }}
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: ${{ matrix.node }}
@@ -120,7 +120,7 @@ jobs:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '20.x'
@@ -183,7 +183,7 @@ jobs:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '20.x'
@@ -210,7 +210,7 @@ jobs:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '20.x'
@@ -239,7 +239,7 @@ jobs:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '20.x'

View File

@@ -18,7 +18,7 @@ jobs:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '20.x'
- name: Check for outdated packages
@@ -31,7 +31,7 @@ jobs:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
persist-credentials: false
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '20.x'
- name: Run security audit

View File

@@ -24,7 +24,7 @@ jobs:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '20.x'
registry-url: 'https://registry.npmjs.org'
@@ -131,7 +131,7 @@ jobs:
name: ecc-release-artifacts
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '20.x'
registry-url: 'https://registry.npmjs.org'

View File

@@ -48,7 +48,7 @@ jobs:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '20.x'
registry-url: 'https://registry.npmjs.org'
@@ -148,7 +148,7 @@ jobs:
name: ecc-release-artifacts
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '20.x'
registry-url: 'https://registry.npmjs.org'

View File

@@ -32,7 +32,7 @@ jobs:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: ${{ inputs.node-version }}

View File

@@ -22,7 +22,7 @@ jobs:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: ${{ inputs.node-version }}

View File

@@ -25,7 +25,7 @@ jobs:
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version: '20.x'

View File

@@ -1,28 +1,8 @@
{
"mcpServers": {
"github": {
"chrome-devtools": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github@2025.4.8"]
},
"context7": {
"command": "npx",
"args": ["-y", "@upstash/context7-mcp@2.1.4"]
},
"exa": {
"type": "http",
"url": "https://mcp.exa.ai/mcp"
},
"memory": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-memory@2026.1.26"]
},
"playwright": {
"command": "npx",
"args": ["-y", "@playwright/mcp@0.0.69", "--extension"]
},
"sequential-thinking": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-sequential-thinking@2025.12.18"]
"args": ["-y", "chrome-devtools-mcp@latest"]
}
}
}

View File

@@ -1,5 +1,11 @@
# Changelog
## Unreleased
### Changed
- Default MCP connector set reduced to a single connector (`chrome-devtools`) per the new connector policy (`docs/MCP-CONNECTOR-POLICY.md`). The six previous defaults (`github`, `context7`, `exa`, `memory`, `playwright`, `sequential-thinking`) were retired after the June 2026 audit: their jobs are covered by skills wrapping CLIs/REST APIs (`github-ops`, `documentation-lookup`, `exa-search`, e2e skills) or by harness-native features (memory, extended thinking, web search). All six remain opt-in via `mcp-configs/mcp-servers.json`.
## 2.0.0 - 2026-06-09
### Added

View File

@@ -1,8 +1,6 @@
**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) | [Deutsch](docs/de-DE/README.md) | [Español](docs/es/README.md)
# ECC
![ECC - the harness-native operator system for agentic work](assets/hero.png)
![ECC — the agent harness operating system](assets/hero.png)
[![Stars](https://img.shields.io/github/stars/affaan-m/ECC?style=flat)](https://github.com/affaan-m/ECC/stargazers)
[![Forks](https://img.shields.io/github/forks/affaan-m/ECC?style=flat)](https://github.com/affaan-m/ECC/network/members)
@@ -77,10 +75,30 @@ ECC v2.0.0 adds the public Hermes operator story on top of that reusable layer:
<sub>**OSS stays free.** This repo is MIT-licensed forever. ECC Pro is the hosted GitHub App for private repos. <a href="https://github.com/sponsors/affaan-m">Sponsors</a> and <a href="https://ecc.tools/pricing">Pro subscribers</a> fund the work — that's why a single maintainer ships weekly across 7 harnesses.</sub>
<div align="center">
<sub><strong>Business sponsors</strong></sub><br />
<a href="https://www.coderabbit.ai"><img src="assets/images/sponsors/coderabbit.png" width="72" alt="CodeRabbit logo" /></a>
&nbsp;&nbsp;
<a href="https://greptile.com"><img src="assets/images/sponsors/greptile.png" width="72" alt="Greptile logo" /></a>
<sub><strong>Business sponsors</strong></sub>
<table>
<tr>
<td align="center" width="220">
<a href="https://www.coderabbit.ai">
<img src="assets/images/sponsors/coderabbit.png" width="96" alt="CodeRabbit logo" /><br />
<strong>CodeRabbit</strong>
</a>
</td>
<td align="center" width="220">
<a href="https://www.greptile.com/go/ecc">
<img src="assets/images/sponsors/greptile.png" width="96" alt="Greptile logo" /><br />
<strong>Greptile</strong>
</a>
</td>
</tr>
</table>
<sub><strong>Community sponsors:</strong> <a href="https://github.com/mikejmorgan-ai">Mike Morgan</a> · <a href="https://github.com/jasonwu513">@jasonwu513</a> · <a href="https://github.com/1anter">@1anter</a> · <a href="https://github.com/massimotodaro">@massimotodaro</a> · <a href="https://github.com/meadmccabe">@meadmccabe</a></sub>
<sub><a href="https://github.com/sponsors/affaan-m"><strong>Become a Sponsor</strong></a> · <a href="SPONSORS.md">Sponsor Tiers</a> · <a href="SPONSORING.md">Sponsorship Program</a></sub>
</div>
---
@@ -91,29 +109,31 @@ This repo is the raw code only. The guides explain everything.
<table>
<tr>
<td width="33%">
<a href="https://x.com/affaan/status/2012378465664745795">
<img src="./assets/images/guides/shorthand-guide.png" alt="The Shorthand Guide to ECC" />
<td width="50%" align="center">
<a href="./the-shortform-guide.md">
<img src="./assets/images/shortform/00-header.png" width="420" alt="The Shorthand Guide to ECC" /><br />
<b>The Shorthand Guide</b>
</a>
<br /><sub>Setup, foundations, philosophy. <b>Read this first.</b> (<a href="https://x.com/affaan/status/2012378465664745795">thread</a>)</sub>
</td>
<td width="33%">
<a href="https://x.com/affaan/status/2014040193557471352">
<img src="./assets/images/guides/longform-guide.png" alt="The Longform Guide to ECC" />
<td width="50%" align="center">
<a href="./the-longform-guide.md">
<img src="./assets/images/longform/01-header.png" width="420" alt="The Longform Guide to ECC" /><br />
<b>The Longform Guide</b>
</a>
<br /><sub>Token optimization, memory persistence, evals, parallelization. (<a href="https://x.com/affaan/status/2014040193557471352">thread</a>)</sub>
</td>
<td width="33%">
<a href="https://x.com/affaan/status/2033263813387223421">
<img src="./assets/images/security/security-guide-header.png" alt="The Shorthand Guide to Everything Agentic Security" />
</a>
</td>
</tr>
<tr>
<td align="center"><b>Shorthand Guide</b><br/>Setup, foundations, philosophy. <b>Read this first.</b></td>
<td align="center"><b>Longform Guide</b><br/>Token optimization, memory persistence, evals, parallelization.</td>
<td align="center"><b>Security Guide</b><br/>Attack vectors, sandboxing, sanitization, CVEs, AgentShield.</td>
</tr>
</table>
<div align="center">
<a href="./the-security-guide.md">
<img src="./assets/images/security/security-guide-header.png" width="420" alt="The Shorthand Guide to Everything Agentic Security" /><br />
<b>The Security Guide</b>
</a>
<br /><sub>Attack vectors, sandboxing, sanitization, CVEs, AgentShield. (<a href="https://x.com/affaan/status/2033263813387223421">thread</a>)</sub>
</div>
| Topic | What You'll Learn |
|-------|-------------------|
| Token Optimization | Model selection, system prompt slimming, background processes |
@@ -982,10 +1002,12 @@ Use Claude Code's `/mcp` command or CLI-managed MCP setup for live Claude Code s
For repo-local MCP access, copy desired MCP server definitions from `mcp-configs/mcp-servers.json` into a project-scoped `.mcp.json`.
ECC ships exactly one default connector (`chrome-devtools`); everything else is a skill wrapping a CLI/REST API or an opt-in catalog entry. The rule and the June 2026 audit that retired the previous six defaults live in [docs/MCP-CONNECTOR-POLICY.md](docs/MCP-CONNECTOR-POLICY.md).
If you already run your own copies of ECC-bundled MCPs, set:
```bash
export ECC_DISABLED_MCPS="github,context7,exa,playwright,sequential-thinking,memory"
export ECC_DISABLED_MCPS="chrome-devtools"
```
ECC-managed install and Codex sync flows will skip or remove those bundled servers instead of re-adding duplicates. `ECC_DISABLED_MCPS` is an ECC install/sync filter, not a live Claude Code toggle.
@@ -1769,17 +1791,7 @@ These configs work for my workflow. You should:
## Sponsors
ECC stays free because paid sponsors fund the work. Featured README placement is reserved for active sponsors.
<div align="center">
<a href="https://www.coderabbit.ai"><img src="assets/images/sponsors/coderabbit.png" width="80" alt="CodeRabbit logo" /></a>
&nbsp;&nbsp;&nbsp;
<a href="https://greptile.com"><img src="assets/images/sponsors/greptile.png" width="80" alt="Greptile logo" /></a>
<br />
<sub><strong>CodeRabbit</strong> · <strong>Greptile</strong></sub>
</div>
[**Become a Sponsor**](https://github.com/sponsors/affaan-m) | [Sponsor Tiers](SPONSORS.md) | [Sponsorship Program](SPONSORING.md)
Featured sponsors are at the top of this README — full list and tiers in [SPONSORS.md](SPONSORS.md). [Become a sponsor](https://github.com/sponsors/affaan-m).
---

View File

@@ -11,7 +11,7 @@ Thank you to everyone funding ECC's open-source work. Your sponsorship is what l
| Sponsor | Logo | Since |
|---------|------|-------|
| [**CodeRabbit**](https://www.coderabbit.ai) | <img src="assets/images/sponsors/coderabbit.png" width="60" alt="CodeRabbit logo" /> | 2026 |
| [**Greptile**](https://greptile.com) | <img src="assets/images/sponsors/greptile.png" width="60" alt="Greptile logo" /> | 2026 |
| [**Greptile**](https://www.greptile.com/go/ecc) | <img src="assets/images/sponsors/greptile.png" width="60" alt="Greptile logo" /> | 2026 |
*[Become a Business sponsor](https://github.com/sponsors/affaan-m) to get README sponsor placement + SPONSORS.md listing. No seats, SLA, custom development, or preferential technical placement is bundled unless separately agreed.*

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 138 KiB

29
assets/hero.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 9.5 KiB

View File

@@ -0,0 +1,43 @@
# MCP Connector Policy
ECC ships exactly one default MCP connector. Everything else is a skill wrapping a CLI or REST API, or an opt-in entry in `mcp-configs/mcp-servers.json`.
## The rule
A default connector earns its slot only if both hold:
1. **Universal** — it applies to essentially every user of a coding agent, on every harness ECC targets.
2. **MCP beats a CLI/API wrapped in a skill** — the job genuinely needs what MCP provides: interactive session state, streaming, an auth handshake, or structured browsing. Stateless request/response work is a skill, not a server. Tool schemas load into every session; each default connector taxes every user's context window whether they use it or not.
The default set stays well under ten. In practice the 2026 field default across serious harnesses is zero to two connectors plus native built-ins.
## Current default set
| Server | Why it passes |
|---|---|
| `chrome-devtools` | Google's official DevTools MCP. Interactive CDP sessions — live debugging, performance traces, console and network inspection on a stateful browser. This is the textbook case where MCP beats a CLI: the value is the held-open session, not a one-shot command. Keyless. |
## The six it replaced (June 2026 audit)
| Former default | Verdict | Replacement |
|---|---|---|
| `github` | drop for skill | `gh` CLI via the `github-ops` skill. `gh` is in every model's training data, composes one-shot commands with minimal token overhead, and auths once via `gh auth login`. The MCP server's ~30 tool schemas taxed every session. |
| `context7` | drop for skill | The `documentation-lookup` skill targeting Context7's public REST API (`/api/v2/libs/search`, `/api/v2/context`). Two stateless calls with a bearer key — no session state to justify a server. |
| `exa` | drop for skill | Harness-native search (Claude Code WebSearch, Codex web_search, Cursor @Web) by default; the `exa-search` skill remains for API-key holders. Also required an API key, which fails the universality test for a default. |
| `memory` | drop entirely | Native harness memory (Claude Code auto-memory directories, Cursor memories, AGENTS.md conventions) plus ECC's instinct/continuous-learning system. The knowledge-graph server solved a 2024 problem harnesses have since absorbed. |
| `playwright` | drop for skill | Microsoft's own `@playwright/cli` agent surface — the vendor itself moved agent workflows off MCP because returning full accessibility trees per step burns context. ECC's e2e skills already drive the CLI. Browser *debugging* (the interactive case) is covered by `chrome-devtools`. |
| `sequential-thinking` | drop entirely | Native extended thinking in every modern harness. The server wrapped no external system — a prompting pattern dressed as a connector. |
All six remain available as opt-in entries in `mcp-configs/mcp-servers.json` for users who want them.
## Opt-out
`ECC_DISABLED_MCPS` filters ECC-generated MCP configs at install/sync time:
```bash
export ECC_DISABLED_MCPS="chrome-devtools"
```
## Adding a connector
Open a PR that argues both prongs of the rule explicitly. "Popular" is not an argument; "the job is stateful and universal" is.

191
ecc2/Cargo.lock generated
View File

@@ -100,6 +100,15 @@ version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
[[package]]
name = "approx"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6"
dependencies = [
"num-traits",
]
[[package]]
name = "atomic"
version = "0.6.1"
@@ -144,9 +153,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.11.0"
version = "2.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8"
[[package]]
name = "block-buffer"
@@ -163,6 +172,12 @@ version = "3.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
[[package]]
name = "by_address"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06"
[[package]]
name = "bytemuck"
version = "1.25.0"
@@ -210,9 +225,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "chrono"
version = "0.4.44"
version = "0.4.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327"
dependencies = [
"iana-time-zone",
"js-sys",
@@ -224,9 +239,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.6.0"
version = "4.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351"
checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51"
dependencies = [
"clap_builder",
"clap_derive",
@@ -246,9 +261,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.6.0"
version = "4.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a"
checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9"
dependencies = [
"heck",
"proc-macro2",
@@ -315,6 +330,12 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "critical-section"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
[[package]]
name = "cron"
version = "0.12.1"
@@ -332,7 +353,7 @@ version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6"
dependencies = [
"bitflags 2.11.0",
"bitflags 2.13.0",
"crossterm_winapi",
"mio",
"parking_lot",
@@ -348,7 +369,7 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b"
dependencies = [
"bitflags 2.11.0",
"bitflags 2.13.0",
"crossterm_winapi",
"derive_more",
"document-features",
@@ -591,6 +612,12 @@ dependencies = [
"regex",
]
[[package]]
name = "fast-srgb8"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1"
[[package]]
name = "filedescriptor"
version = "0.8.3"
@@ -709,7 +736,7 @@ version = "0.20.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b"
dependencies = [
"bitflags 2.11.0",
"bitflags 2.13.0",
"libc",
"libgit2-sys",
"log",
@@ -747,6 +774,17 @@ dependencies = [
"foldhash 0.2.0",
]
[[package]]
name = "hashbrown"
version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
dependencies = [
"allocator-api2",
"equivalent",
"foldhash 0.2.0",
]
[[package]]
name = "hashlink"
version = "0.9.1"
@@ -1012,9 +1050,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
[[package]]
name = "libc"
version = "0.2.183"
version = "0.2.186"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
[[package]]
name = "libgit2-sys"
@@ -1030,6 +1068,12 @@ dependencies = [
"pkg-config",
]
[[package]]
name = "libm"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
[[package]]
name = "libredox"
version = "0.1.14"
@@ -1082,7 +1126,7 @@ version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f50e8f47623268b5407192d26876c4d7f89d686ca130fdc53bced4814cd29f8"
dependencies = [
"bitflags 2.11.0",
"bitflags 2.13.0",
]
[[package]]
@@ -1126,11 +1170,11 @@ checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "lru"
version = "0.16.3"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593"
checksum = "8a860605968fce16869fd239cf4237a82f3ac470723415db603b0e8b6c8d4fb9"
dependencies = [
"hashbrown 0.16.1",
"hashbrown 0.17.1",
]
[[package]]
@@ -1191,9 +1235,9 @@ dependencies = [
[[package]]
name = "mio"
version = "1.1.1"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc"
checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda"
dependencies = [
"libc",
"log",
@@ -1207,7 +1251,7 @@ version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
dependencies = [
"bitflags 2.11.0",
"bitflags 2.13.0",
"cfg-if",
"cfg_aliases",
"libc",
@@ -1323,6 +1367,30 @@ dependencies = [
"num-traits",
]
[[package]]
name = "palette"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cbf71184cc5ecc2e4e1baccdb21026c20e5fc3dcf63028a086131b3ab00b6e6"
dependencies = [
"approx",
"fast-srgb8",
"libm",
"palette_derive",
]
[[package]]
name = "palette_derive"
version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5030daf005bface118c096f510ffb781fc28f9ab6a32ab224d8631be6851d30"
dependencies = [
"by_address",
"proc-macro2",
"quote",
"syn 2.0.117",
]
[[package]]
name = "parking_lot"
version = "0.12.5"
@@ -1537,9 +1605,9 @@ checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
[[package]]
name = "ratatui"
version = "0.30.0"
version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d1ce67fb8ba4446454d1c8dbaeda0557ff5e94d39d5e5ed7f10a65eb4c8266bc"
checksum = "1695748e3a735b34968c887ceea5a380b43545903868ae8f5b666593100f6b68"
dependencies = [
"instability",
"ratatui-core",
@@ -1547,21 +1615,25 @@ dependencies = [
"ratatui-macros",
"ratatui-termwiz",
"ratatui-widgets",
"serde",
]
[[package]]
name = "ratatui-core"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ef8dea09a92caaf73bff7adb70b76162e5937524058a7e5bff37869cbbec293"
checksum = "42d3603f354bba8c595fa47860e60142d7372b7210c27044c6a7d0e1a4336b44"
dependencies = [
"bitflags 2.11.0",
"bitflags 2.13.0",
"compact_str",
"hashbrown 0.16.1",
"critical-section",
"hashbrown 0.17.1",
"indoc",
"itertools",
"kasuari",
"lru",
"palette",
"serde",
"strum",
"thiserror 2.0.18",
"unicode-segmentation",
@@ -1571,9 +1643,9 @@ dependencies = [
[[package]]
name = "ratatui-crossterm"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "577c9b9f652b4c121fb25c6a391dd06406d3b092ba68827e6d2f09550edc54b3"
checksum = "2b2867bedcbd6a690ca4f8672a687b730ec07660c79844517b084311b529980c"
dependencies = [
"cfg-if",
"crossterm 0.28.1",
@@ -1584,9 +1656,9 @@ dependencies = [
[[package]]
name = "ratatui-macros"
version = "0.7.0"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7f1342a13e83e4bb9d0b793d0ea762be633f9582048c892ae9041ef39c936f4"
checksum = "80fac59720679490d89d200df411faa249be728681adcabed3d047ae72c48f1d"
dependencies = [
"ratatui-core",
"ratatui-widgets",
@@ -1594,9 +1666,9 @@ dependencies = [
[[package]]
name = "ratatui-termwiz"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f76fe0bd0ed4295f0321b1676732e2454024c15a35d01904ddb315afd3d545c"
checksum = "386b8ff8f74ed749509391c56d549761a2fcdb408e1f42e467286bcb7dac8967"
dependencies = [
"ratatui-core",
"termwiz",
@@ -1604,17 +1676,18 @@ dependencies = [
[[package]]
name = "ratatui-widgets"
version = "0.3.0"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7dbfa023cd4e604c2553483820c5fe8aa9d71a42eea5aa77c6e7f35756612db"
checksum = "7ef4f17dd7ac3abf5adc2b920a03c61eee4bfe6a88fa5191936895525371d79c"
dependencies = [
"bitflags 2.11.0",
"hashbrown 0.16.1",
"bitflags 2.13.0",
"hashbrown 0.17.1",
"indoc",
"instability",
"itertools",
"line-clipping",
"ratatui-core",
"serde",
"strum",
"time",
"unicode-segmentation",
@@ -1627,7 +1700,7 @@ version = "0.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
dependencies = [
"bitflags 2.11.0",
"bitflags 2.13.0",
]
[[package]]
@@ -1643,9 +1716,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.12.3"
version = "1.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276"
checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba"
dependencies = [
"aho-corasick",
"memchr",
@@ -1666,9 +1739,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.8.10"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
[[package]]
name = "ring"
@@ -1690,7 +1763,7 @@ version = "0.32.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7753b721174eb8ff87a9a0e799e2d7bc3749323e773db92e0984debb00019d6e"
dependencies = [
"bitflags 2.11.0",
"bitflags 2.13.0",
"fallible-iterator",
"fallible-streaming-iterator",
"hashlink",
@@ -1713,7 +1786,7 @@ version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [
"bitflags 2.11.0",
"bitflags 2.13.0",
"errno",
"libc",
"linux-raw-sys 0.4.15",
@@ -1726,7 +1799,7 @@ version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
dependencies = [
"bitflags 2.11.0",
"bitflags 2.13.0",
"errno",
"libc",
"linux-raw-sys 0.12.1",
@@ -1824,9 +1897,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.149"
version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
dependencies = [
"itoa",
"memchr",
@@ -1949,18 +2022,18 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "strum"
version = "0.27.2"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf"
checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd"
dependencies = [
"strum_macros",
]
[[package]]
name = "strum_macros"
version = "0.27.2"
version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7"
checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664"
dependencies = [
"heck",
"proc-macro2",
@@ -2036,7 +2109,7 @@ checksum = "4676b37242ccbd1aabf56edb093a4827dc49086c0ffd764a5705899e0f35f8f7"
dependencies = [
"anyhow",
"base64",
"bitflags 2.11.0",
"bitflags 2.13.0",
"fancy-regex",
"filedescriptor",
"finl_unicode",
@@ -2152,9 +2225,9 @@ dependencies = [
[[package]]
name = "tokio"
version = "1.50.0"
version = "1.52.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d"
checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
dependencies = [
"bytes",
"libc",
@@ -2169,9 +2242,9 @@ dependencies = [
[[package]]
name = "tokio-macros"
version = "2.6.1"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c"
checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
dependencies = [
"proc-macro2",
"quote",
@@ -2377,9 +2450,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "uuid"
version = "1.22.0"
version = "1.23.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37"
checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7"
dependencies = [
"atomic",
"getrandom 0.4.2",
@@ -2511,7 +2584,7 @@ version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
dependencies = [
"bitflags 2.11.0",
"bitflags 2.13.0",
"hashbrown 0.15.5",
"indexmap",
"semver",
@@ -2846,7 +2919,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
dependencies = [
"anyhow",
"bitflags 2.11.0",
"bitflags 2.13.0",
"indexmap",
"log",
"serde",

View File

@@ -358,8 +358,8 @@
},
"devDependencies": {
"@eslint/js": "^9.39.2",
"@opencode-ai/plugin": "^1.0.0",
"@types/node": "25.7.0",
"@opencode-ai/plugin": "^1.16.2",
"@types/node": "25.9.2",
"c8": "^11.0.0",
"eslint": "^9.39.2",
"globals": "^17.4.0",

View File

@@ -61,10 +61,7 @@ function loadJsonObject(filePath, label) {
assert.fail(`Expected ${label} to contain valid JSON: ${error.message}`);
}
assert.ok(
parsed && typeof parsed === 'object' && !Array.isArray(parsed),
`Expected ${label} to contain a JSON object`,
);
assert.ok(parsed && typeof parsed === 'object' && !Array.isArray(parsed), `Expected ${label} to contain a JSON object`);
return parsed;
}
@@ -161,34 +158,22 @@ test('.opencode/plugins/ecc-hooks.ts active plugin banner matches package.json',
test('docs/pt-BR/README.md latest release heading matches package.json', () => {
const source = fs.readFileSync(ptBrReadmePath, 'utf8');
assert.ok(
source.includes(`### v${expectedVersion} `),
'Expected docs/pt-BR/README.md to advertise the current release heading',
);
assert.ok(source.includes(`### v${expectedVersion} `), 'Expected docs/pt-BR/README.md to advertise the current release heading');
});
test('docs/tr/README.md latest release heading matches package.json', () => {
const source = fs.readFileSync(trReadmePath, 'utf8');
assert.ok(
source.includes(`### v${expectedVersion} `),
'Expected docs/tr/README.md to advertise the current release heading',
);
assert.ok(source.includes(`### v${expectedVersion} `), 'Expected docs/tr/README.md to advertise the current release heading');
});
test('README.zh-CN.md latest release heading matches package.json', () => {
const source = fs.readFileSync(rootZhCnReadmePath, 'utf8');
assert.ok(
source.includes(`### v${expectedVersion} `),
'Expected README.zh-CN.md to advertise the current release heading',
);
assert.ok(source.includes(`### v${expectedVersion} `), 'Expected README.zh-CN.md to advertise the current release heading');
});
test('docs/zh-CN/README.md latest release heading matches package.json', () => {
const source = fs.readFileSync(zhCnReadmePath, 'utf8');
assert.ok(
source.includes(`### v${expectedVersion} `),
'Expected docs/zh-CN/README.md to advertise the current release heading',
);
assert.ok(source.includes(`### v${expectedVersion} `), 'Expected docs/zh-CN/README.md to advertise the current release heading');
});
// ── Claude plugin manifest ────────────────────────────────────────────────────
@@ -216,10 +201,7 @@ test('claude plugin.json uses short plugin slug', () => {
});
test('claude plugin.json does NOT have agents field (unsupported by Claude Code validator)', () => {
assert.ok(
!('agents' in claudePlugin),
'agents field must NOT be declared — Claude Code plugin validator rejects it',
);
assert.ok(!('agents' in claudePlugin), 'agents field must NOT be declared — Claude Code plugin validator rejects it');
});
test('claude plugin.json skills is an array', () => {
@@ -234,26 +216,13 @@ test('claude plugin.json disables bundled MCP servers for provider tool-name com
const legacyPluginName = 'everything-claude-code';
const reportedOverlongToolName = `mcp__plugin_${legacyPluginName}_github__create_pull_request_review`;
assert.ok(
reportedOverlongToolName.length > 64,
'Expected the reported GitHub MCP tool name to exceed strict provider limits without the MCP opt-out',
);
assert.ok(
Object.prototype.hasOwnProperty.call(claudePlugin, 'mcpServers'),
'Expected mcpServers to be explicitly declared so Claude Code does not auto-load root .mcp.json',
);
assert.deepStrictEqual(
claudePlugin.mcpServers,
{},
'Claude plugin installs must not auto-bundle root MCP servers; document/manual MCP install remains supported',
);
assert.ok(reportedOverlongToolName.length > 64, 'Expected the reported GitHub MCP tool name to exceed strict provider limits without the MCP opt-out');
assert.ok(Object.prototype.hasOwnProperty.call(claudePlugin, 'mcpServers'), 'Expected mcpServers to be explicitly declared so Claude Code does not auto-load root .mcp.json');
assert.deepStrictEqual(claudePlugin.mcpServers, {}, 'Claude plugin installs must not auto-bundle root MCP servers; document/manual MCP install remains supported');
});
test('claude plugin.json does NOT have explicit hooks declaration', () => {
assert.ok(
!('hooks' in claudePlugin),
'hooks field must NOT be declared — Claude Code v2.1+ auto-loads hooks/hooks.json by convention',
);
assert.ok(!('hooks' in claudePlugin), 'hooks field must NOT be declared — Claude Code v2.1+ auto-loads hooks/hooks.json by convention');
});
console.log('\n=== .claude-plugin/marketplace.json ===\n');
@@ -267,10 +236,7 @@ const claudeMarketplace = loadJsonObject(claudeMarketplacePath, '.claude-plugin/
test('claude marketplace.json keeps only Claude-supported top-level keys', () => {
const unsupportedTopLevelKeys = ['$schema', 'description'];
for (const key of unsupportedTopLevelKeys) {
assert.ok(
!(key in claudeMarketplace),
`.claude-plugin/marketplace.json must not declare unsupported top-level key "${key}"`,
);
assert.ok(!(key in claudeMarketplace), `.claude-plugin/marketplace.json must not declare unsupported top-level key "${key}"`);
}
});
@@ -316,39 +282,21 @@ test('codex plugin.json version matches package.json', () => {
});
test('codex plugin.json skills is a string (not array) per official spec', () => {
assert.strictEqual(
typeof codexPlugin.skills,
'string',
'skills must be a string path per Codex official docs, not an array',
);
assert.strictEqual(typeof codexPlugin.skills, 'string', 'skills must be a string path per Codex official docs, not an array');
});
test('codex plugin.json mcpServers is a string path (not array) per official spec', () => {
assert.strictEqual(
typeof codexPlugin.mcpServers,
'string',
'mcpServers must be a string path per Codex official docs',
);
assert.strictEqual(typeof codexPlugin.mcpServers, 'string', 'mcpServers must be a string path per Codex official docs');
});
test('codex plugin.json mcpServers exactly matches "./.mcp.json"', () => {
assert.strictEqual(
codexPlugin.mcpServers,
'./.mcp.json',
'mcpServers must point exactly to "./.mcp.json" per official docs',
);
assert.strictEqual(codexPlugin.mcpServers, './.mcp.json', 'mcpServers must point exactly to "./.mcp.json" per official docs');
const mcpPath = path.join(repoRoot, codexPlugin.mcpServers.replace(/^\.\//, ''));
assert.ok(
fs.existsSync(mcpPath),
`mcpServers file missing at plugin root: ${codexPlugin.mcpServers}`,
);
assert.ok(fs.existsSync(mcpPath), `mcpServers file missing at plugin root: ${codexPlugin.mcpServers}`);
});
test('codex plugin.json has interface.displayName', () => {
assert.ok(
codexPlugin.interface && codexPlugin.interface.displayName,
'Expected interface.displayName for plugin directory presentation',
);
assert.ok(codexPlugin.interface && codexPlugin.interface.displayName, 'Expected interface.displayName for plugin directory presentation');
});
test('codex plugin.json uses canonical ECC repo and display name', () => {
@@ -363,20 +311,11 @@ test('codex plugin presentation assets exist and ship in npm package', () => {
for (const field of ['composerIcon', 'logo']) {
const assetPath = codexPlugin.interface[field];
assert.ok(assetPath, `Expected interface.${field}`);
assert.ok(
assetPath.startsWith('./assets/'),
`Expected interface.${field} to point at a root assets path, got ${assetPath}`,
);
assert.ok(assetPath.startsWith('./assets/'), `Expected interface.${field} to point at a root assets path, got ${assetPath}`);
const packagePath = assetPath.replace(/^\.\//, '');
assert.ok(
fs.existsSync(path.join(repoRoot, packagePath)),
`Expected interface.${field} asset to exist: ${packagePath}`,
);
assert.ok(
packageFiles.has(packagePath),
`Expected package.json files to include interface.${field} asset: ${packagePath}`,
);
assert.ok(fs.existsSync(path.join(repoRoot, packagePath)), `Expected interface.${field} asset to exist: ${packagePath}`);
assert.ok(packageFiles.has(packagePath), `Expected package.json files to include interface.${field} asset: ${packagePath}`);
}
});
@@ -388,31 +327,27 @@ const mcpJsonPath = path.join(repoRoot, '.mcp.json');
test('.mcp.json exists at plugin root (not inside .codex-plugin/)', () => {
assert.ok(fs.existsSync(mcpJsonPath), 'Expected .mcp.json at repo root (plugin root)');
assert.ok(
!fs.existsSync(path.join(repoRoot, '.codex-plugin', '.mcp.json')),
'.mcp.json must NOT be inside .codex-plugin/ — only plugin.json belongs there',
);
assert.ok(!fs.existsSync(path.join(repoRoot, '.codex-plugin', '.mcp.json')), '.mcp.json must NOT be inside .codex-plugin/ — only plugin.json belongs there');
});
const mcpConfig = loadJsonObject(mcpJsonPath, '.mcp.json');
test('.mcp.json has mcpServers object', () => {
assert.ok(
mcpConfig.mcpServers && typeof mcpConfig.mcpServers === 'object',
'Expected mcpServers object',
);
assert.ok(mcpConfig.mcpServers && typeof mcpConfig.mcpServers === 'object', 'Expected mcpServers object');
});
test('.mcp.json includes at least github, context7, and exa servers', () => {
test('.mcp.json default set follows the connector policy', () => {
const servers = Object.keys(mcpConfig.mcpServers);
assert.ok(servers.includes('github'), 'Expected github MCP server');
assert.ok(servers.includes('context7'), 'Expected context7 MCP server');
assert.ok(servers.includes('exa'), 'Expected exa MCP server');
assert.ok(servers.includes('chrome-devtools'), 'Expected chrome-devtools as the default browser connector');
assert.ok(servers.length <= 2, `Default connector set must stay minimal per docs/MCP-CONNECTOR-POLICY.md (found ${servers.length})`);
});
test('.mcp.json declares exa as an http MCP server', () => {
assert.strictEqual(mcpConfig.mcpServers.exa.type, 'http', 'Expected exa MCP server to declare type=http');
assert.strictEqual(mcpConfig.mcpServers.exa.url, 'https://mcp.exa.ai/mcp', 'Expected exa MCP server URL to remain unchanged');
test('.mcp.json does not reintroduce retired default connectors', () => {
const retired = ['github', 'context7', 'exa', 'memory', 'playwright', 'sequential-thinking'];
const servers = Object.keys(mcpConfig.mcpServers);
for (const name of retired) {
assert.ok(!servers.includes(name), `${name} was retired from the default set (June 2026 audit) — it lives in mcp-configs/mcp-servers.json as opt-in; see docs/MCP-CONNECTOR-POLICY.md`);
}
});
// ── Codex marketplace file ────────────────────────────────────────────────────
@@ -422,10 +357,7 @@ console.log('\n=== .agents/plugins/marketplace.json ===\n');
const marketplacePath = path.join(repoRoot, '.agents', 'plugins', 'marketplace.json');
test('marketplace.json exists at .agents/plugins/', () => {
assert.ok(
fs.existsSync(marketplacePath),
'Expected .agents/plugins/marketplace.json for Codex repo marketplace discovery',
);
assert.ok(fs.existsSync(marketplacePath), 'Expected .agents/plugins/marketplace.json for Codex repo marketplace discovery');
});
const marketplace = loadJsonObject(marketplacePath, '.agents/plugins/marketplace.json');
@@ -467,24 +399,11 @@ test('marketplace local plugin path resolves to the repo-root Codex bundle', ()
continue;
}
assert.ok(
plugin.source.path.startsWith('./'),
`Codex marketplace source.path must be ./-prefixed: ${plugin.source.path}`,
);
assert.ok(plugin.source.path.startsWith('./'), `Codex marketplace source.path must be ./-prefixed: ${plugin.source.path}`);
const resolvedRoot = path.resolve(repoRoot, plugin.source.path);
assert.strictEqual(
resolvedRoot,
repoRoot,
`Expected local marketplace path to resolve to repo root from marketplace root, got: ${plugin.source.path}`,
);
assert.ok(
fs.existsSync(path.join(resolvedRoot, '.codex-plugin', 'plugin.json')),
`Codex plugin manifest missing under resolved marketplace root: ${plugin.source.path}`,
);
assert.ok(
fs.existsSync(path.join(resolvedRoot, '.mcp.json')),
`Root MCP config missing under resolved marketplace root: ${plugin.source.path}`,
);
assert.strictEqual(resolvedRoot, repoRoot, `Expected local marketplace path to resolve to repo root from marketplace root, got: ${plugin.source.path}`);
assert.ok(fs.existsSync(path.join(resolvedRoot, '.codex-plugin', 'plugin.json')), `Codex plugin manifest missing under resolved marketplace root: ${plugin.source.path}`);
assert.ok(fs.existsSync(path.join(resolvedRoot, '.mcp.json')), `Root MCP config missing under resolved marketplace root: ${plugin.source.path}`);
}
});
@@ -510,7 +429,7 @@ test('user-facing docs do not use overlong legacy marketplace install commands',
path.join(repoRoot, 'README.md'),
path.join(repoRoot, 'README.zh-CN.md'),
path.join(repoRoot, 'skills', 'configure-ecc', 'SKILL.md'),
...collectMarkdownFiles(path.join(repoRoot, 'docs')),
...collectMarkdownFiles(path.join(repoRoot, 'docs'))
].filter(filePath => !path.relative(repoRoot, filePath).startsWith(`docs${path.sep}drafts${path.sep}`));
const offenders = [];
@@ -521,19 +440,11 @@ test('user-facing docs do not use overlong legacy marketplace install commands',
}
}
assert.deepStrictEqual(
offenders,
[],
`Overlong legacy install commands must not appear in user-facing docs: ${offenders.join(', ')}`,
);
assert.deepStrictEqual(offenders, [], `Overlong legacy install commands must not appear in user-facing docs: ${offenders.join(', ')}`);
});
test('user-facing docs do not use the legacy non-URL marketplace add form', () => {
const markdownFiles = [
path.join(repoRoot, 'README.md'),
path.join(repoRoot, 'README.zh-CN.md'),
...collectMarkdownFiles(path.join(repoRoot, 'docs')),
];
const markdownFiles = [path.join(repoRoot, 'README.md'), path.join(repoRoot, 'README.zh-CN.md'), ...collectMarkdownFiles(path.join(repoRoot, 'docs'))];
const offenders = [];
for (const filePath of markdownFiles) {
@@ -543,31 +454,15 @@ test('user-facing docs do not use the legacy non-URL marketplace add form', () =
}
}
assert.deepStrictEqual(
offenders,
[],
`Legacy non-URL marketplace add form must not appear in user-facing docs: ${offenders.join(', ')}`,
);
assert.deepStrictEqual(offenders, [], `Legacy non-URL marketplace add form must not appear in user-facing docs: ${offenders.join(', ')}`);
});
test('.codex-plugin README uses current marketplace add flow', () => {
const readme = fs.readFileSync(path.join(repoRoot, '.codex-plugin', 'README.md'), 'utf8');
assert.ok(
readme.includes('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(
readme.includes('Official Plugin Directory publishing is coming soon'),
'Expected .codex-plugin README to document current official directory status',
);
assert.ok(
!/\bcodex plugin install\b/.test(readme),
'codex plugin install is not a current Codex CLI command',
);
assert.ok(readme.includes('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(readme.includes('Official Plugin Directory publishing is coming soon'), 'Expected .codex-plugin README to document current official directory status');
assert.ok(!/\bcodex plugin install\b/.test(readme), 'codex plugin install is not a current Codex CLI command');
});
test('docs/zh-CN/README.md version row matches package.json', () => {

View File

@@ -150,8 +150,7 @@ function runTests() {
const mcpConfig = readJson(path.join(projectDir, '.cursor', 'mcp.json'));
assert.strictEqual(hooksConfig.version, 1);
assert.ok(hooksConfig.hooks.sessionStart, 'Should keep Cursor sessionStart hooks');
assert.ok(mcpConfig.mcpServers.github, 'Should install shared MCP servers into Cursor');
assert.ok(mcpConfig.mcpServers.context7, 'Should include bundled documentation MCPs');
assert.ok(mcpConfig.mcpServers['chrome-devtools'], 'Should install shared MCP servers into Cursor');
const statePath = path.join(projectDir, '.cursor', 'ecc-install-state.json');
const state = readJson(statePath);
@@ -194,8 +193,7 @@ function runTests() {
const mcpConfig = readJson(path.join(projectDir, '.cursor', 'mcp.json'));
assert.ok(mcpConfig.mcpServers.custom, 'Should preserve existing custom Cursor MCP servers');
assert.ok(mcpConfig.mcpServers.github, 'Should merge bundled GitHub MCP server');
assert.ok(mcpConfig.mcpServers.playwright, 'Should merge bundled Playwright MCP server');
assert.ok(mcpConfig.mcpServers['chrome-devtools'], 'Should merge the bundled chrome-devtools MCP server');
} finally {
cleanup(homeDir);
cleanup(projectDir);

View File

@@ -211,7 +211,7 @@ git worktree add ../feature-branch feature-branch
Stream and watch logs/bash processes Claude runs:
<https://github.com/user-attachments/assets/shortform/07-tmux-video.mp4>
[Watch: tmux session streaming a long-running command (video)](./assets/images/shortform/07-tmux-video.mp4)
```bash
tmux new -s dev

164
yarn.lock
View File

@@ -178,59 +178,59 @@ __metadata:
languageName: node
linkType: hard
"@msgpackr-extract/msgpackr-extract-darwin-arm64@npm:3.0.3":
version: 3.0.3
resolution: "@msgpackr-extract/msgpackr-extract-darwin-arm64@npm:3.0.3"
"@msgpackr-extract/msgpackr-extract-darwin-arm64@npm:3.0.4":
version: 3.0.4
resolution: "@msgpackr-extract/msgpackr-extract-darwin-arm64@npm:3.0.4"
conditions: os=darwin & cpu=arm64
languageName: node
linkType: hard
"@msgpackr-extract/msgpackr-extract-darwin-x64@npm:3.0.3":
version: 3.0.3
resolution: "@msgpackr-extract/msgpackr-extract-darwin-x64@npm:3.0.3"
"@msgpackr-extract/msgpackr-extract-darwin-x64@npm:3.0.4":
version: 3.0.4
resolution: "@msgpackr-extract/msgpackr-extract-darwin-x64@npm:3.0.4"
conditions: os=darwin & cpu=x64
languageName: node
linkType: hard
"@msgpackr-extract/msgpackr-extract-linux-arm64@npm:3.0.3":
version: 3.0.3
resolution: "@msgpackr-extract/msgpackr-extract-linux-arm64@npm:3.0.3"
"@msgpackr-extract/msgpackr-extract-linux-arm64@npm:3.0.4":
version: 3.0.4
resolution: "@msgpackr-extract/msgpackr-extract-linux-arm64@npm:3.0.4"
conditions: os=linux & cpu=arm64
languageName: node
linkType: hard
"@msgpackr-extract/msgpackr-extract-linux-arm@npm:3.0.3":
version: 3.0.3
resolution: "@msgpackr-extract/msgpackr-extract-linux-arm@npm:3.0.3"
"@msgpackr-extract/msgpackr-extract-linux-arm@npm:3.0.4":
version: 3.0.4
resolution: "@msgpackr-extract/msgpackr-extract-linux-arm@npm:3.0.4"
conditions: os=linux & cpu=arm
languageName: node
linkType: hard
"@msgpackr-extract/msgpackr-extract-linux-x64@npm:3.0.3":
version: 3.0.3
resolution: "@msgpackr-extract/msgpackr-extract-linux-x64@npm:3.0.3"
"@msgpackr-extract/msgpackr-extract-linux-x64@npm:3.0.4":
version: 3.0.4
resolution: "@msgpackr-extract/msgpackr-extract-linux-x64@npm:3.0.4"
conditions: os=linux & cpu=x64
languageName: node
linkType: hard
"@msgpackr-extract/msgpackr-extract-win32-x64@npm:3.0.3":
version: 3.0.3
resolution: "@msgpackr-extract/msgpackr-extract-win32-x64@npm:3.0.3"
"@msgpackr-extract/msgpackr-extract-win32-x64@npm:3.0.4":
version: 3.0.4
resolution: "@msgpackr-extract/msgpackr-extract-win32-x64@npm:3.0.4"
conditions: os=win32 & cpu=x64
languageName: node
linkType: hard
"@opencode-ai/plugin@npm:^1.0.0":
version: 1.15.3
resolution: "@opencode-ai/plugin@npm:1.15.3"
"@opencode-ai/plugin@npm:^1.16.2":
version: 1.16.2
resolution: "@opencode-ai/plugin@npm:1.16.2"
dependencies:
"@opencode-ai/sdk": "npm:1.15.3"
effect: "npm:4.0.0-beta.65"
"@opencode-ai/sdk": "npm:1.16.2"
effect: "npm:4.0.0-beta.74"
zod: "npm:4.1.8"
peerDependencies:
"@opentui/core": ">=0.2.11"
"@opentui/keymap": ">=0.2.11"
"@opentui/solid": ">=0.2.11"
"@opentui/core": ">=0.3.2"
"@opentui/keymap": ">=0.3.2"
"@opentui/solid": ">=0.3.2"
peerDependenciesMeta:
"@opentui/core":
optional: true
@@ -238,16 +238,16 @@ __metadata:
optional: true
"@opentui/solid":
optional: true
checksum: 10c0/8f680d7e318e3a8b64314c9923e00ecbbde33b195651b59ca4bbfb7cbf0a90a5ea30df7c806ec9611482fef96dfd6b48432267af6df3bde068535774a97d5fe9
checksum: 10c0/a10d6259557c2b587afd93dc690bf5b3b0132272c0b0bca1f77c5a7ea9e3440ebbf1fbdf0a24e4a20ae05f23961c546a2feab53c8f50b10a9d237090c41d2146
languageName: node
linkType: hard
"@opencode-ai/sdk@npm:1.15.3":
version: 1.15.3
resolution: "@opencode-ai/sdk@npm:1.15.3"
"@opencode-ai/sdk@npm:1.16.2":
version: 1.16.2
resolution: "@opencode-ai/sdk@npm:1.16.2"
dependencies:
cross-spawn: "npm:7.0.6"
checksum: 10c0/b9345d31fa53f2f22cb1a63e7fe39d3e260ea2d0ca65ae27525c203beefd5db0ce7854eeaa5054b2cf1680164f19cc9e90c2e049dfac9cdc804a4b53a9128a4c
checksum: 10c0/0f8de5a64bfb4411ecddd0bb2c3049df07a5661a05e7c965e2404692f80394652b00a4d46985e97aabf8b26ac85e4313d8dbf7bce2280a297eb4fa88bf700a6a
languageName: node
linkType: hard
@@ -302,12 +302,12 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:25.7.0":
version: 25.7.0
resolution: "@types/node@npm:25.7.0"
"@types/node@npm:25.9.2":
version: 25.9.2
resolution: "@types/node@npm:25.9.2"
dependencies:
undici-types: "npm:~7.21.0"
checksum: 10c0/47ec7eaca154c36ad6d1ac0270e6e254eedf20b9dc49afe3bc76e4f7eba29ceac705f8903b162aeaf40e3941101ffe76ffb374989359ea3ef8c8509d8b443f55
undici-types: "npm:>=7.24.0 <7.24.7"
checksum: 10c0/f14c0d56361febb985eccc45cf0834ee6e2f07c4389a636f3e1a55ebde320077a80bface18c9afd3092f5fa295925502c1a9d55f805efa813f634aa9c941cbac
languageName: node
linkType: hard
@@ -631,8 +631,8 @@ __metadata:
dependencies:
"@eslint/js": "npm:^9.39.2"
"@iarna/toml": "npm:^2.2.5"
"@opencode-ai/plugin": "npm:^1.0.0"
"@types/node": "npm:25.7.0"
"@opencode-ai/plugin": "npm:^1.16.2"
"@types/node": "npm:25.9.2"
ajv: "npm:^8.18.0"
c8: "npm:^11.0.0"
eslint: "npm:^9.39.2"
@@ -647,21 +647,21 @@ __metadata:
languageName: unknown
linkType: soft
"effect@npm:4.0.0-beta.65":
version: 4.0.0-beta.65
resolution: "effect@npm:4.0.0-beta.65"
"effect@npm:4.0.0-beta.74":
version: 4.0.0-beta.74
resolution: "effect@npm:4.0.0-beta.74"
dependencies:
"@standard-schema/spec": "npm:^1.1.0"
fast-check: "npm:^4.6.0"
fast-check: "npm:^4.8.0"
find-my-way-ts: "npm:^0.1.6"
ini: "npm:^6.0.0"
ini: "npm:^7.0.0"
kubernetes-types: "npm:^1.30.0"
msgpackr: "npm:^1.11.9"
msgpackr: "npm:^2.0.1"
multipasta: "npm:^0.2.7"
toml: "npm:^4.1.1"
uuid: "npm:^13.0.0"
yaml: "npm:^2.8.3"
checksum: 10c0/ed89d877461414af2bbfccc0c7b66a3f5a46d08e7e7d8b10bec9f969db97180b916e8c079138dab985937c8e9297fa003ef2d1d560458924cd2308203baf305c
uuid: "npm:^14.0.0"
yaml: "npm:^2.9.0"
checksum: 10c0/3dfc7ce7b58bbe9e8459ea9eba0abdcef7d9e7082643c64f4cc5165632777aa163f20d7b5f86372f819e6b60154e44cea125abb71be01da667a330c10a9b5892
languageName: node
linkType: hard
@@ -823,12 +823,12 @@ __metadata:
languageName: node
linkType: hard
"fast-check@npm:^4.6.0":
version: 4.7.0
resolution: "fast-check@npm:4.7.0"
"fast-check@npm:^4.8.0":
version: 4.8.0
resolution: "fast-check@npm:4.8.0"
dependencies:
pure-rand: "npm:^8.0.0"
checksum: 10c0/7edce2b82d11d5325e9e79a2377e1f6e7200d27219edda2e3449d827e994c34461132fc149c90e41b78fc8e6ef4aae77d45350ac7bb1bc4a81110401d0a49fbc
checksum: 10c0/f72556a29db4ff386a8b6e50d420b06c7e5eaafff7db5560a99136c57d8d4777998155eb02d1bbeff396f575cc0b1442c8a1c4ddb798c4a919b542de1a1904ff
languageName: node
linkType: hard
@@ -1025,10 +1025,10 @@ __metadata:
languageName: node
linkType: hard
"ini@npm:^6.0.0":
version: 6.0.0
resolution: "ini@npm:6.0.0"
checksum: 10c0/9a7f55f306e2b25b41ae67c8b526e8f4673f057b70852b9025816ef4f15f07bf1ba35ed68ea4471ff7b31718f7ef1bc50d709f8d03cb012e10a3135eb99c7206
"ini@npm:^7.0.0":
version: 7.0.0
resolution: "ini@npm:7.0.0"
checksum: 10c0/7520cae38bd5587e1cbca4637bb5fc0e157f38e0816522756456010ef703772d0018f9f4987cb9977bf3b10c1feccaad7800744dd1f5d85fb435e58a1baa9754
languageName: node
linkType: hard
@@ -1671,16 +1671,16 @@ __metadata:
languageName: node
linkType: hard
"msgpackr-extract@npm:^3.0.2":
version: 3.0.3
resolution: "msgpackr-extract@npm:3.0.3"
"msgpackr-extract@npm:^3.0.4":
version: 3.0.4
resolution: "msgpackr-extract@npm:3.0.4"
dependencies:
"@msgpackr-extract/msgpackr-extract-darwin-arm64": "npm:3.0.3"
"@msgpackr-extract/msgpackr-extract-darwin-x64": "npm:3.0.3"
"@msgpackr-extract/msgpackr-extract-linux-arm": "npm:3.0.3"
"@msgpackr-extract/msgpackr-extract-linux-arm64": "npm:3.0.3"
"@msgpackr-extract/msgpackr-extract-linux-x64": "npm:3.0.3"
"@msgpackr-extract/msgpackr-extract-win32-x64": "npm:3.0.3"
"@msgpackr-extract/msgpackr-extract-darwin-arm64": "npm:3.0.4"
"@msgpackr-extract/msgpackr-extract-darwin-x64": "npm:3.0.4"
"@msgpackr-extract/msgpackr-extract-linux-arm": "npm:3.0.4"
"@msgpackr-extract/msgpackr-extract-linux-arm64": "npm:3.0.4"
"@msgpackr-extract/msgpackr-extract-linux-x64": "npm:3.0.4"
"@msgpackr-extract/msgpackr-extract-win32-x64": "npm:3.0.4"
node-gyp: "npm:latest"
node-gyp-build-optional-packages: "npm:5.2.2"
dependenciesMeta:
@@ -1698,19 +1698,19 @@ __metadata:
optional: true
bin:
download-msgpackr-prebuilds: bin/download-prebuilds.js
checksum: 10c0/e504fd8bf86a29d7527c83776530ee6dc92dcb0273bb3679fd4a85173efead7f0ee32fb82c8410a13c33ef32828c45f81118ffc0fbed5d6842e72299894623b4
checksum: 10c0/582a9d17abbf3019e600e948736695056280ce401fd0235ee2474e95f9952208b9f6cce4d0e355b03b7d3c5630e6c3d11fe5fc27fdedb2311cce48de464338d8
languageName: node
linkType: hard
"msgpackr@npm:^1.11.9":
version: 1.11.12
resolution: "msgpackr@npm:1.11.12"
"msgpackr@npm:^2.0.1":
version: 2.0.4
resolution: "msgpackr@npm:2.0.4"
dependencies:
msgpackr-extract: "npm:^3.0.2"
msgpackr-extract: "npm:^3.0.4"
dependenciesMeta:
msgpackr-extract:
optional: true
checksum: 10c0/e9f1460e363dbd8c81a5c1b5829980edea7d76e91d570d094d0a4dae0d8ad12f64dea11b2be15f3d7b48d615fa9d3c9b600a6894fd272526087fa33753b5fd16
checksum: 10c0/b72e8de59ce82a29cd5ca6d93ceec589367dd742a75fb04b6d26d6e0c5863f1000d0b27979469f18ca4554f3ccabe620524013268d5387415bcab495cca4ae73
languageName: node
linkType: hard
@@ -2117,10 +2117,10 @@ __metadata:
languageName: node
linkType: hard
"undici-types@npm:~7.21.0":
version: 7.21.0
resolution: "undici-types@npm:7.21.0"
checksum: 10c0/c3b4ae5f066c398acb1962505b56214ecd72843f7d7827fcc2df7a48a63d1639d3608c580ac09f836253d21fa7ba8f1a04440569ed9d332474ad01b8a010db87
"undici-types@npm:>=7.24.0 <7.24.7":
version: 7.24.6
resolution: "undici-types@npm:7.24.6"
checksum: 10c0/d9cd8befb643ac904615c280a095ba4240531f6bb4a5e75a22a7483630ca8d3f1016d2ab6ace6ceda1f63b3a2db2fe037fafe121d6917a0187573aa548ff78ca
languageName: node
linkType: hard
@@ -2140,12 +2140,12 @@ __metadata:
languageName: node
linkType: hard
"uuid@npm:^13.0.0":
version: 13.0.1
resolution: "uuid@npm:13.0.1"
"uuid@npm:^14.0.0":
version: 14.0.0
resolution: "uuid@npm:14.0.0"
bin:
uuid: dist-node/bin/uuid
checksum: 10c0/7bb8ad18b11871b7bd1b9161a60610c2b6ce8f7300d93932f92117a2ab9b40479dd23e81929ac848e8a7c45f78b8ed3333f88694b71c17ff3265e443f8684642
checksum: 10c0/a57ae7794c45005c1a9208989196c5baf79a7679c30f43c1bee9033a2c4d113a2cea216fa6fcc9663b08b0d55635df1a7c6eb7e7f3d21c3e50688c698fa39a50
languageName: node
linkType: hard
@@ -2214,12 +2214,12 @@ __metadata:
languageName: node
linkType: hard
"yaml@npm:^2.8.3":
version: 2.8.4
resolution: "yaml@npm:2.8.4"
"yaml@npm:^2.9.0":
version: 2.9.0
resolution: "yaml@npm:2.9.0"
bin:
yaml: bin.mjs
checksum: 10c0/0a33a1fa28d4bc79f61a12ec7ef7a2bce0ce5f8e80c6eaecfb4a0c88c08767dd1ede372b6a3bcd70891213b8c9f3169b355c97e77026d3b3459e10d2cccaef1e
checksum: 10c0/f340718df45e97a9551b9bf9dac61c80050bc464513b710debfb5067c380c8472e3b67809cffacb4ab5ffb5e66ef9310816c88b05f371cec60abfedd8c88e0a2
languageName: node
linkType: hard