mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-03-30 13:43:26 +08:00
docs: add sponsorship playbook and monthly metrics automation
This commit is contained in:
185
.github/workflows/monthly-metrics.yml
vendored
Normal file
185
.github/workflows/monthly-metrics.yml
vendored
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
name: Monthly Metrics Snapshot
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 14 1 * *' # Monthly on the 1st at 14:00 UTC
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
snapshot:
|
||||||
|
name: Update metrics issue
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Update monthly metrics issue
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const owner = context.repo.owner;
|
||||||
|
const repo = context.repo.repo;
|
||||||
|
const title = "Monthly Metrics Snapshot";
|
||||||
|
const label = "metrics-snapshot";
|
||||||
|
const monthKey = new Date().toISOString().slice(0, 7);
|
||||||
|
|
||||||
|
function parseLastPage(linkHeader) {
|
||||||
|
if (!linkHeader) return null;
|
||||||
|
const match = linkHeader.match(/&page=(\d+)>; rel="last"/);
|
||||||
|
return match ? Number(match[1]) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function fmt(value) {
|
||||||
|
if (value === null || value === undefined) return "n/a";
|
||||||
|
return Number(value).toLocaleString("en-US");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getNpmDownloads(range, pkg) {
|
||||||
|
try {
|
||||||
|
const res = await fetch(`https://api.npmjs.org/downloads/point/${range}/${pkg}`);
|
||||||
|
if (!res.ok) return null;
|
||||||
|
const data = await res.json();
|
||||||
|
return data.downloads ?? null;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getContributorsCount() {
|
||||||
|
try {
|
||||||
|
const resp = await github.rest.repos.listContributors({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
per_page: 1,
|
||||||
|
anon: "false"
|
||||||
|
});
|
||||||
|
return parseLastPage(resp.headers.link) ?? resp.data.length;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getReleasesCount() {
|
||||||
|
try {
|
||||||
|
const resp = await github.rest.repos.listReleases({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
per_page: 1
|
||||||
|
});
|
||||||
|
return parseLastPage(resp.headers.link) ?? resp.data.length;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getTraffic(metric) {
|
||||||
|
try {
|
||||||
|
const route = metric === "clones"
|
||||||
|
? "GET /repos/{owner}/{repo}/traffic/clones"
|
||||||
|
: "GET /repos/{owner}/{repo}/traffic/views";
|
||||||
|
const resp = await github.request(route, { owner, repo });
|
||||||
|
return resp.data?.count ?? null;
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const [
|
||||||
|
mainWeek,
|
||||||
|
shieldWeek,
|
||||||
|
mainMonth,
|
||||||
|
shieldMonth,
|
||||||
|
repoData,
|
||||||
|
contributors,
|
||||||
|
releases,
|
||||||
|
views14d,
|
||||||
|
clones14d
|
||||||
|
] = await Promise.all([
|
||||||
|
getNpmDownloads("last-week", "ecc-universal"),
|
||||||
|
getNpmDownloads("last-week", "ecc-agentshield"),
|
||||||
|
getNpmDownloads("last-month", "ecc-universal"),
|
||||||
|
getNpmDownloads("last-month", "ecc-agentshield"),
|
||||||
|
github.rest.repos.get({ owner, repo }),
|
||||||
|
getContributorsCount(),
|
||||||
|
getReleasesCount(),
|
||||||
|
getTraffic("views"),
|
||||||
|
getTraffic("clones")
|
||||||
|
]);
|
||||||
|
|
||||||
|
const stars = repoData.data.stargazers_count;
|
||||||
|
const forks = repoData.data.forks_count;
|
||||||
|
|
||||||
|
const tableHeader = [
|
||||||
|
"| Month (UTC) | ecc-universal (week) | ecc-agentshield (week) | ecc-universal (30d) | ecc-agentshield (30d) | Stars | Forks | Contributors | GitHub App installs (manual) | Views (14d) | Clones (14d) | Releases |",
|
||||||
|
"|---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|"
|
||||||
|
].join("\n");
|
||||||
|
|
||||||
|
const row = `| ${monthKey} | ${fmt(mainWeek)} | ${fmt(shieldWeek)} | ${fmt(mainMonth)} | ${fmt(shieldMonth)} | ${fmt(stars)} | ${fmt(forks)} | ${fmt(contributors)} | n/a | ${fmt(views14d)} | ${fmt(clones14d)} | ${fmt(releases)} |`;
|
||||||
|
|
||||||
|
const intro = [
|
||||||
|
"# Monthly Metrics Snapshot",
|
||||||
|
"",
|
||||||
|
"Automated monthly snapshot for sponsor/partner reporting.",
|
||||||
|
"",
|
||||||
|
"- `GitHub App installs (manual)` is intentionally manual until a stable public API path is available.",
|
||||||
|
"- Traffic metrics are 14-day rolling windows from the GitHub traffic API and can show `n/a` if unavailable.",
|
||||||
|
"",
|
||||||
|
tableHeader
|
||||||
|
].join("\n");
|
||||||
|
|
||||||
|
try {
|
||||||
|
await github.rest.issues.getLabel({ owner, repo, name: label });
|
||||||
|
} catch (error) {
|
||||||
|
if (error.status === 404) {
|
||||||
|
await github.rest.issues.createLabel({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
name: label,
|
||||||
|
color: "0e8a16",
|
||||||
|
description: "Automated monthly project metrics snapshots"
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const issuesResp = await github.rest.issues.listForRepo({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
state: "open",
|
||||||
|
labels: label,
|
||||||
|
per_page: 100
|
||||||
|
});
|
||||||
|
|
||||||
|
let issue = issuesResp.data.find((item) => item.title === title);
|
||||||
|
|
||||||
|
if (!issue) {
|
||||||
|
const created = await github.rest.issues.create({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
title,
|
||||||
|
labels: [label],
|
||||||
|
body: `${intro}\n${row}\n`
|
||||||
|
});
|
||||||
|
console.log(`Created issue #${created.data.number}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentBody = issue.body || "";
|
||||||
|
if (currentBody.includes(`| ${monthKey} |`)) {
|
||||||
|
console.log(`Issue #${issue.number} already has snapshot row for ${monthKey}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const body = currentBody.includes("| Month (UTC) |")
|
||||||
|
? `${currentBody.trimEnd()}\n${row}\n`
|
||||||
|
: `${intro}\n${row}\n`;
|
||||||
|
|
||||||
|
await github.rest.issues.update({
|
||||||
|
owner,
|
||||||
|
repo,
|
||||||
|
issue_number: issue.number,
|
||||||
|
body
|
||||||
|
});
|
||||||
|
console.log(`Updated issue #${issue.number}`);
|
||||||
@@ -45,12 +45,15 @@ Use these live signals when presenting ECC to sponsors, platforms, or ecosystem
|
|||||||
- **Main package installs:** [`ecc-universal` on npm](https://www.npmjs.com/package/ecc-universal)
|
- **Main package installs:** [`ecc-universal` on npm](https://www.npmjs.com/package/ecc-universal)
|
||||||
- **Security companion installs:** [`ecc-agentshield` on npm](https://www.npmjs.com/package/ecc-agentshield)
|
- **Security companion installs:** [`ecc-agentshield` on npm](https://www.npmjs.com/package/ecc-agentshield)
|
||||||
- **GitHub App distribution:** [ECC Tools marketplace listing](https://github.com/marketplace/ecc-tools)
|
- **GitHub App distribution:** [ECC Tools marketplace listing](https://github.com/marketplace/ecc-tools)
|
||||||
|
- **Automated monthly metrics issue:** powered by `.github/workflows/monthly-metrics.yml`
|
||||||
- **Repo adoption signal:** stars/forks/contributors badges at the top of this README
|
- **Repo adoption signal:** stars/forks/contributors badges at the top of this README
|
||||||
|
|
||||||
Download counts for Claude Code plugin installs are not currently exposed as a public API. For partner reporting, combine npm metrics with GitHub App installs and repository traffic/fork growth.
|
Download counts for Claude Code plugin installs are not currently exposed as a public API. For partner reporting, combine npm metrics with GitHub App installs and repository traffic/fork growth.
|
||||||
|
|
||||||
For a sponsor-call metrics checklist and command snippets, see [`docs/business/metrics-and-sponsorship.md`](docs/business/metrics-and-sponsorship.md).
|
For a sponsor-call metrics checklist and command snippets, see [`docs/business/metrics-and-sponsorship.md`](docs/business/metrics-and-sponsorship.md).
|
||||||
|
|
||||||
|
[**Sponsor ECC**](https://github.com/sponsors/affaan-m) | [Sponsor Tiers](SPONSORS.md) | [Sponsorship Program](SPONSORING.md)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## The Guides
|
## The Guides
|
||||||
@@ -1217,7 +1220,7 @@ These configs work for my workflow. You should:
|
|||||||
|
|
||||||
This project is free and open source. Sponsors help keep it maintained and growing.
|
This project is free and open source. Sponsors help keep it maintained and growing.
|
||||||
|
|
||||||
[**Become a Sponsor**](https://github.com/sponsors/affaan-m) | [Sponsor Tiers](SPONSORS.md)
|
[**Become a Sponsor**](https://github.com/sponsors/affaan-m) | [Sponsor Tiers](SPONSORS.md) | [Sponsorship Program](SPONSORING.md)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
43
SPONSORING.md
Normal file
43
SPONSORING.md
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# Sponsoring ECC
|
||||||
|
|
||||||
|
ECC is maintained as an open-source agent harness performance system across Claude Code, Cursor, OpenCode, and Codex app/CLI.
|
||||||
|
|
||||||
|
## Why Sponsor
|
||||||
|
|
||||||
|
Sponsorship directly funds:
|
||||||
|
|
||||||
|
- Faster bug-fix and release cycles
|
||||||
|
- Cross-platform parity work across harnesses
|
||||||
|
- Public docs, skills, and reliability tooling that remain free for the community
|
||||||
|
|
||||||
|
## Sponsorship Tiers
|
||||||
|
|
||||||
|
These are practical starting points and can be adjusted for partnership scope.
|
||||||
|
|
||||||
|
| Tier | Price | Best For | Includes |
|
||||||
|
|------|-------|----------|----------|
|
||||||
|
| Pilot Partner | $200/mo | First sponsor engagement | Monthly metrics update, roadmap preview, prioritized maintainer feedback |
|
||||||
|
| Growth Partner | $500/mo | Teams actively adopting ECC | Pilot benefits + monthly office-hours sync + workflow integration guidance |
|
||||||
|
| Strategic Partner | $1,000+/mo | Platform/ecosystem partnerships | Growth benefits + coordinated launch support + deeper maintainer collaboration |
|
||||||
|
|
||||||
|
## Sponsor Reporting
|
||||||
|
|
||||||
|
Metrics shared monthly can include:
|
||||||
|
|
||||||
|
- npm downloads (`ecc-universal`, `ecc-agentshield`)
|
||||||
|
- Repository adoption (stars, forks, contributors)
|
||||||
|
- GitHub App install trend
|
||||||
|
- Release cadence and reliability milestones
|
||||||
|
|
||||||
|
For exact command snippets and a repeatable pull process, see [`docs/business/metrics-and-sponsorship.md`](docs/business/metrics-and-sponsorship.md).
|
||||||
|
|
||||||
|
## Expectations and Scope
|
||||||
|
|
||||||
|
- Sponsorship supports maintenance and acceleration; it does not transfer project ownership.
|
||||||
|
- Feature requests are prioritized based on sponsor tier, ecosystem impact, and maintenance risk.
|
||||||
|
- Security and reliability fixes take precedence over net-new features.
|
||||||
|
|
||||||
|
## Sponsor Here
|
||||||
|
|
||||||
|
- GitHub Sponsors: [https://github.com/sponsors/affaan-m](https://github.com/sponsors/affaan-m)
|
||||||
|
- Project site: [https://ecc.tools](https://ecc.tools)
|
||||||
@@ -70,3 +70,5 @@ Use this on calls:
|
|||||||
> We track adoption through npm distribution, GitHub App installs, and repository growth.
|
> We track adoption through npm distribution, GitHub App installs, and repository growth.
|
||||||
> Claude plugin installs are structurally undercounted publicly, so we use a blended metrics model.
|
> Claude plugin installs are structurally undercounted publicly, so we use a blended metrics model.
|
||||||
> The project supports Claude Code, Cursor, OpenCode, and Codex app/CLI with production-grade hook reliability and a large passing test suite.
|
> The project supports Claude Code, Cursor, OpenCode, and Codex app/CLI with production-grade hook reliability and a large passing test suite.
|
||||||
|
|
||||||
|
For launch-ready social copy snippets, see [`social-launch-copy.md`](./social-launch-copy.md).
|
||||||
|
|||||||
62
docs/business/social-launch-copy.md
Normal file
62
docs/business/social-launch-copy.md
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# Social Launch Copy (X + LinkedIn)
|
||||||
|
|
||||||
|
Use these templates as launch-ready starting points. Replace placeholders before posting.
|
||||||
|
|
||||||
|
## X Post: Release Announcement
|
||||||
|
|
||||||
|
```text
|
||||||
|
ECC v1.8.0 is live.
|
||||||
|
|
||||||
|
We moved from “config pack” to an agent harness performance system:
|
||||||
|
- hook reliability fixes
|
||||||
|
- new harness commands
|
||||||
|
- cross-tool parity (Claude Code, Cursor, OpenCode, Codex)
|
||||||
|
|
||||||
|
Start here: <repo-link>
|
||||||
|
```
|
||||||
|
|
||||||
|
## X Post: Proof + Metrics
|
||||||
|
|
||||||
|
```text
|
||||||
|
If you evaluate agent tooling, use blended distribution metrics:
|
||||||
|
- npm installs (`ecc-universal`, `ecc-agentshield`)
|
||||||
|
- GitHub App installs
|
||||||
|
- repo adoption (stars/forks/contributors)
|
||||||
|
|
||||||
|
We now track this monthly in-repo for sponsor transparency.
|
||||||
|
```
|
||||||
|
|
||||||
|
## X Quote Tweet: Eval Skills Article
|
||||||
|
|
||||||
|
```text
|
||||||
|
Strong point on eval discipline.
|
||||||
|
|
||||||
|
In ECC we turned this into production checks via:
|
||||||
|
- /harness-audit
|
||||||
|
- /quality-gate
|
||||||
|
- Stop-phase session summaries
|
||||||
|
|
||||||
|
This is where harness performance compounds over time.
|
||||||
|
```
|
||||||
|
|
||||||
|
## X Quote Tweet: Plankton / deslop workflow
|
||||||
|
|
||||||
|
```text
|
||||||
|
This workflow direction is right: optimize the harness, not just prompts.
|
||||||
|
|
||||||
|
Our v1.8.0 focus was reliability + parity + measurable quality gates across toolchains.
|
||||||
|
```
|
||||||
|
|
||||||
|
## LinkedIn Post: Partner-Friendly Summary
|
||||||
|
|
||||||
|
```text
|
||||||
|
We shipped ECC v1.8.0 with one objective: improve agent harness performance in production.
|
||||||
|
|
||||||
|
Highlights:
|
||||||
|
- more reliable hook lifecycle behavior
|
||||||
|
- new harness-level quality commands
|
||||||
|
- parity across Claude Code, Cursor, OpenCode, and Codex
|
||||||
|
- stronger sponsor-facing metrics tracking
|
||||||
|
|
||||||
|
If your team runs AI coding agents daily, this is designed for operational use.
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user