mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-03-30 05:33:27 +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)
|
||||
- **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)
|
||||
- **Automated monthly metrics issue:** powered by `.github/workflows/monthly-metrics.yml`
|
||||
- **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.
|
||||
|
||||
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
|
||||
@@ -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.
|
||||
|
||||
[**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.
|
||||
> 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.
|
||||
|
||||
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