content-grade 1.0.45 → 1.0.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTING.md +7 -5
- package/README.md +80 -25
- package/bin/content-grade.js +16 -16
- package/dist-server/server/db.js +5 -0
- package/dist-server/server/routes/analytics.js +21 -0
- package/package.json +1 -1
package/CONTRIBUTING.md
CHANGED
|
@@ -31,8 +31,8 @@ cd Content-Grade
|
|
|
31
31
|
npm install
|
|
32
32
|
|
|
33
33
|
# Run in development
|
|
34
|
-
node bin/content-grade.js demo # smoke test — no
|
|
35
|
-
node bin/content-grade.js analyze README.md # requires
|
|
34
|
+
node bin/content-grade.js demo # smoke test — runs on built-in sample, no Claude needed
|
|
35
|
+
node bin/content-grade.js analyze README.md # requires Claude CLI logged in
|
|
36
36
|
|
|
37
37
|
# Run all checks (must pass before opening a PR)
|
|
38
38
|
npm test # vitest — all tests green
|
|
@@ -40,16 +40,18 @@ npm run typecheck # zero TypeScript errors
|
|
|
40
40
|
npm run build # vite + tsc — must compile clean
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
+
**Requirement:** Content-Grade uses [Claude CLI](https://claude.ai/code) for AI analysis — not an API key. Install it with `npm install -g @anthropic-ai/claude-code` and run `claude login`. The `demo` command and all tests run without Claude active.
|
|
44
|
+
|
|
43
45
|
### Environment variables
|
|
44
46
|
|
|
45
47
|
Copy `.env.example` to `.env` if one exists, or set these:
|
|
46
48
|
|
|
47
49
|
| Variable | Required | Description |
|
|
48
50
|
|----------|----------|-------------|
|
|
49
|
-
| `
|
|
50
|
-
| `
|
|
51
|
+
| `PORT` | No (default 4000) | Port for the web dashboard server |
|
|
52
|
+
| `STRIPE_SECRET_KEY` | No | Stripe secret key for payment features |
|
|
51
53
|
|
|
52
|
-
|
|
54
|
+
No API keys are needed for the analysis tools. All tests and the `demo` command run without any environment variables.
|
|
53
55
|
|
|
54
56
|
## Submitting a pull request
|
|
55
57
|
|
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
[](https://opensource.org/licenses/MIT)
|
|
10
10
|
[](https://nodejs.org)
|
|
11
11
|
[](https://claude.ai/code)
|
|
12
|
+
[](https://github.com/StanislavBG/Content-Grade/issues)
|
|
12
13
|
[](https://github.com/StanislavBG/Content-Grade/discussions)
|
|
13
14
|
[](EARLY_ADOPTERS.md)
|
|
14
15
|
|
|
@@ -47,6 +48,8 @@ content-grade analyze ./post.md --quiet # score number only (for scripts)
|
|
|
47
48
|
content-grade activate # unlock Pro: batch mode, 100/day
|
|
48
49
|
```
|
|
49
50
|
|
|
51
|
+
⭐ **If the quickstart saved you 10 minutes, [star the repo](https://github.com/StanislavBG/Content-Grade) — it helps other developers find it.**
|
|
52
|
+
|
|
50
53
|
---
|
|
51
54
|
|
|
52
55
|
## Upgrade to Pro
|
|
@@ -66,6 +69,8 @@ Most developers hit the limit when they start trusting it enough to use it on ev
|
|
|
66
69
|
|
|
67
70
|
**[Upgrade to Pro → $9/mo](https://buy.stripe.com/4gM14p87GeCh9vn9ks8k80a)**
|
|
68
71
|
|
|
72
|
+
> **Early Adopter?** The first 50 users who share their results in [Show & Tell](https://github.com/StanislavBG/Content-Grade/discussions/new?category=show-and-tell) get **12 months Pro free**. [Details →](#early-adopter-program--12-months-pro-free)
|
|
73
|
+
|
|
69
74
|
**What Pro unlocks in practice:**
|
|
70
75
|
|
|
71
76
|
```bash
|
|
@@ -233,19 +238,62 @@ Free tier: **5 analyses/day**. [Pro ($9/mo)](https://buy.stripe.com/4gM14p87GeCh
|
|
|
233
238
|
|
|
234
239
|
**[All discussions →](https://github.com/StanislavBG/Content-Grade/discussions)**
|
|
235
240
|
|
|
236
|
-
|
|
241
|
+
### Early Adopter Program — 12 months Pro free
|
|
242
|
+
|
|
243
|
+
Over 1,000 developers have installed ContentGrade. **Zero have claimed an Early Adopter seat yet.** That means you're actually first — and there are only 50.
|
|
244
|
+
|
|
245
|
+
The first 50 users who run ContentGrade on real content and share it get **12 months Pro free** ($108 value) plus direct input on what gets built next.
|
|
246
|
+
|
|
247
|
+
**How to claim your seat:**
|
|
248
|
+
1. Run ContentGrade on a real file: `npx content-grade analyze ./your-post.md`
|
|
249
|
+
2. Post in [Show & Tell](https://github.com/StanislavBG/Content-Grade/discussions/new?category=show-and-tell) with `[Early Adopter]` in the title — include your use case, one thing you'd change, and your score
|
|
250
|
+
3. Maintainer responds within 48 hours with Pro access
|
|
251
|
+
|
|
252
|
+
**Short on time?** Just [open an issue](https://github.com/StanislavBG/Content-Grade/issues/new?title=%5BEarly+Adopter%5D+Quick+claim&labels=early-adopter&body=Use+case%3A+%0AScore+I+got%3A+%0AOne+thing+I%27d+change%3A+) with `[Early Adopter]` in the title — same deal, lower friction.
|
|
253
|
+
|
|
254
|
+
Full benefits: [EARLY_ADOPTERS.md](EARLY_ADOPTERS.md)
|
|
237
255
|
|
|
238
256
|
---
|
|
239
257
|
|
|
240
|
-
##
|
|
258
|
+
## Contributing
|
|
259
|
+
|
|
260
|
+
Already using ContentGrade? That makes you the most valuable contributor. You know what's missing.
|
|
261
|
+
|
|
262
|
+
**Three ways to help (pick what fits your time):**
|
|
263
|
+
|
|
264
|
+
| Effort | Action |
|
|
265
|
+
|--------|--------|
|
|
266
|
+
| 2 min | [Open a discussion](https://github.com/StanislavBG/Content-Grade/discussions/new?category=ideas) — describe a workflow gap or missing feature |
|
|
267
|
+
| 20 min | [File a bug report](https://github.com/StanislavBG/Content-Grade/issues/new?template=bug_report.yml) with `--verbose` output |
|
|
268
|
+
| 2 hours | Pick a [`good first issue`](https://github.com/StanislavBG/Content-Grade/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) — scoped tasks with acceptance criteria and a pointer to the right file |
|
|
241
269
|
|
|
242
|
-
|
|
270
|
+
**Quick dev setup:**
|
|
271
|
+
```bash
|
|
272
|
+
git clone https://github.com/StanislavBG/Content-Grade.git
|
|
273
|
+
cd Content-Grade
|
|
274
|
+
npm install
|
|
275
|
+
node bin/content-grade.js demo # smoke test — no Claude needed
|
|
276
|
+
npm test # all tests green
|
|
277
|
+
```
|
|
243
278
|
|
|
244
|
-
|
|
245
|
-
- Are you running it in CI? What score threshold do you use?
|
|
246
|
-
- Any workflow, config, or integration worth sharing?
|
|
279
|
+
Requires [Claude CLI](https://claude.ai/code) for the analysis commands (`claude login` once). No API keys. See [CONTRIBUTING.md](CONTRIBUTING.md) for PR guidelines, code style, and what gets merged.
|
|
247
280
|
|
|
248
|
-
|
|
281
|
+
Contributors who file a useful bug report or land a PR automatically qualify for the [Early Adopter program](#early-adopter-program--12-months-pro-free).
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Show Us Your Results
|
|
286
|
+
|
|
287
|
+
Over 1,000 developers have run ContentGrade. We'd love to hear what you're scoring — blog posts, landing pages, ad copy, emails, documentation.
|
|
288
|
+
|
|
289
|
+
**[→ Post in Show & Tell](https://github.com/StanislavBG/Content-Grade/discussions/new?category=show-and-tell)** (also counts as an Early Adopter claim — 12 months Pro free)
|
|
290
|
+
|
|
291
|
+
Tell us:
|
|
292
|
+
- What content type? What score did you get?
|
|
293
|
+
- Running it in CI? What threshold are you using?
|
|
294
|
+
- Something that surprised you — good or bad?
|
|
295
|
+
|
|
296
|
+
Use cases shared here get featured in this README. We'll credit you by username. And yes — every Show & Tell post qualifies for the [Early Adopter program](EARLY_ADOPTERS.md).
|
|
249
297
|
|
|
250
298
|
---
|
|
251
299
|
|
|
@@ -1036,9 +1084,32 @@ Power users who go beyond early adoption get early access to `@beta` releases, a
|
|
|
1036
1084
|
|
|
1037
1085
|
### Contributing
|
|
1038
1086
|
|
|
1039
|
-
|
|
1087
|
+
All contributions get a review within 48 hours.
|
|
1088
|
+
|
|
1089
|
+
**First contribution in ~15 minutes:**
|
|
1090
|
+
|
|
1091
|
+
```bash
|
|
1092
|
+
git clone https://github.com/StanislavBG/Content-Grade.git
|
|
1093
|
+
cd Content-Grade
|
|
1094
|
+
pnpm install
|
|
1095
|
+
pnpm dev # type-check + test suite
|
|
1096
|
+
```
|
|
1097
|
+
|
|
1098
|
+
Open a PR against `main`. Branch name format: `fix/short-description` or `feat/short-description`.
|
|
1099
|
+
|
|
1100
|
+
**What's most needed right now:**
|
|
1101
|
+
|
|
1102
|
+
| Area | Examples |
|
|
1103
|
+
|------|---------|
|
|
1104
|
+
| Scoring rules | Catch passive voice, jargon density, weak CTAs — add a new rule to the prompt |
|
|
1105
|
+
| CLI output | Better rendering in narrow terminals, CI-friendly formatting |
|
|
1106
|
+
| Bug fixes | Start with a [`good first issue`](https://github.com/StanislavBG/Content-Grade/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) — each has acceptance criteria and the exact file to touch |
|
|
1107
|
+
| Documentation | Fix unclear copy, add real-world examples, document edge cases |
|
|
1108
|
+
| Integrations | GitHub Actions workflows, pre-commit hook improvements, VS Code tasks |
|
|
1109
|
+
|
|
1110
|
+
**Not sure where to start?** Browse **[`good first issue` →](https://github.com/StanislavBG/Content-Grade/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)** — scoped, completable in a few hours, no prior codebase knowledge required.
|
|
1040
1111
|
|
|
1041
|
-
|
|
1112
|
+
See **[CONTRIBUTING.md](CONTRIBUTING.md)** for full code style, test guidelines, and PR checklist.
|
|
1042
1113
|
|
|
1043
1114
|
### Roadmap
|
|
1044
1115
|
|
|
@@ -1070,22 +1141,6 @@ See [docs/social-proof/built-with-badge.md](docs/social-proof/built-with-badge.m
|
|
|
1070
1141
|
|
|
1071
1142
|
---
|
|
1072
1143
|
|
|
1073
|
-
## Community & Feedback
|
|
1074
|
-
|
|
1075
|
-
[](https://github.com/StanislavBG/Content-Grade)
|
|
1076
|
-
|
|
1077
|
-
**1,159 developers have installed Content-Grade — join the community.**
|
|
1078
|
-
|
|
1079
|
-
If Content-Grade saves you time, a ⭐ goes a long way. It helps more developers find the tool and keeps the project active.
|
|
1080
|
-
|
|
1081
|
-
**Early adopter program:** The first 50 seats are still open — early adopters get permanent free Pro tier. [Claim your seat →](https://content-grade.github.io/Content-Grade/#early-adopter)
|
|
1082
|
-
|
|
1083
|
-
**Found a bug?** [Open an issue →](https://github.com/StanislavBG/Content-Grade/issues/new/choose) — every report shapes what gets built next.
|
|
1084
|
-
|
|
1085
|
-
**[GitHub Discussions →](https://github.com/StanislavBG/Content-Grade/discussions)** — questions, ideas, and show & tell. Built something with content-grade? Open a Discussion — we want to see it.
|
|
1086
|
-
|
|
1087
|
-
---
|
|
1088
|
-
|
|
1089
1144
|
## Legal
|
|
1090
1145
|
|
|
1091
1146
|
- [Privacy Policy](https://content-grade.github.io/Content-Grade/privacy.html)
|
package/bin/content-grade.js
CHANGED
|
@@ -141,10 +141,10 @@ function showFreeTierCTA(count) {
|
|
|
141
141
|
// Limit reached — that run just worked; now close the sale
|
|
142
142
|
console.log(` ${RD}${B}That was your last free analysis (${limit}/${limit} used).${R}`);
|
|
143
143
|
blank();
|
|
144
|
-
console.log(` ${WH}${B}Pro
|
|
145
|
-
console.log(` ${WH} ·
|
|
146
|
-
console.log(` ${WH} ·
|
|
147
|
-
console.log(` ${WH} ·
|
|
144
|
+
console.log(` ${WH}${B}Pro unlocks:${R}`);
|
|
145
|
+
console.log(` ${WH} · Unlimited runs — no cap, no monthly resets${R}`);
|
|
146
|
+
console.log(` ${WH} · Priority support — get answers within 24h${R}`);
|
|
147
|
+
console.log(` ${WH} · Team sharing — share analyses across your team${R}`);
|
|
148
148
|
blank();
|
|
149
149
|
console.log(` ${MG}${B}→ Get Pro ($9/mo, cancel anytime): ${CY}${UPGRADE_LINKS.free}${R}`);
|
|
150
150
|
blank();
|
|
@@ -153,20 +153,20 @@ function showFreeTierCTA(count) {
|
|
|
153
153
|
console.log(` ${D} 2. Run: ${CY}content-grade activate <your-key>${R}`);
|
|
154
154
|
console.log(` ${D} Already have a key? Run step 2 now.${R}`);
|
|
155
155
|
} else if (remaining <= 2) {
|
|
156
|
-
// 1-2 runs left — loss aversion +
|
|
157
|
-
console.log(` ${YL}${B}${
|
|
156
|
+
// 1-2 runs left — loss aversion + concrete Pro value
|
|
157
|
+
console.log(` ${YL}${B}${remaining} free analysis${remaining === 1 ? '' : 'es'} remaining (${count}/${limit} used)${R}`);
|
|
158
158
|
blank();
|
|
159
|
-
console.log(` ${WH}${B}Pro:
|
|
160
|
-
console.log(` ${WH} ·
|
|
159
|
+
console.log(` ${WH}${B}Pro: unlimited runs · priority support · team sharing${R}`);
|
|
160
|
+
console.log(` ${WH} · No cap, no resets — grade every piece you publish${R}`);
|
|
161
161
|
console.log(` ${MG}${B}→ Get Pro before you run out ($9/mo): ${CY}${UPGRADE_LINKS.free}${R}`);
|
|
162
162
|
} else {
|
|
163
163
|
// Runs available — rotate benefit angle each run to avoid banner blindness
|
|
164
164
|
const nudgeBenefits = [
|
|
165
|
-
`Pro:
|
|
166
|
-
`Pro:
|
|
167
|
-
`Pro:
|
|
165
|
+
`Pro: unlimited runs · no cap, no resets`,
|
|
166
|
+
`Pro: priority support · 24h response time`,
|
|
167
|
+
`Pro: team sharing · analyze together, no limits`,
|
|
168
168
|
];
|
|
169
|
-
console.log(` ${WH}${
|
|
169
|
+
console.log(` ${WH}${remaining} free analysis${remaining === 1 ? '' : 'es'} remaining (${count}/${limit} used)${R}`);
|
|
170
170
|
console.log(` ${WH} ${nudgeBenefits[count % 3]}${R}`);
|
|
171
171
|
console.log(` ${MG}→ Get Pro ($9/mo): ${CY}${UPGRADE_LINKS.free}${R}`);
|
|
172
172
|
}
|
|
@@ -285,10 +285,10 @@ function checkFreeTierLimit() {
|
|
|
285
285
|
hr();
|
|
286
286
|
console.log(` ${RD}${B}You've used all ${limit} free analyses.${R}`);
|
|
287
287
|
blank();
|
|
288
|
-
console.log(` ${WH}${B}Pro
|
|
289
|
-
console.log(` ${WH} ·
|
|
290
|
-
console.log(` ${WH} ·
|
|
291
|
-
console.log(` ${WH} ·
|
|
288
|
+
console.log(` ${WH}${B}Pro unlocks:${R}`);
|
|
289
|
+
console.log(` ${WH} · Unlimited runs — no cap, no monthly resets${R}`);
|
|
290
|
+
console.log(` ${WH} · Priority support — get answers within 24h${R}`);
|
|
291
|
+
console.log(` ${WH} · Team sharing — share analyses across your team${R}`);
|
|
292
292
|
blank();
|
|
293
293
|
console.log(` ${MG}${B}→ Get Pro ($9/mo, cancel anytime): ${CY}${UPGRADE_LINKS.free}${R}`);
|
|
294
294
|
blank();
|
package/dist-server/server/db.js
CHANGED
|
@@ -142,4 +142,9 @@ function migrate(db) {
|
|
|
142
142
|
db.exec(`ALTER TABLE cli_telemetry ADD COLUMN run_count INTEGER`);
|
|
143
143
|
}
|
|
144
144
|
catch { }
|
|
145
|
+
// Preflight Suite: identify which tool sent the ping
|
|
146
|
+
try {
|
|
147
|
+
db.exec(`ALTER TABLE cli_telemetry ADD COLUMN package TEXT`);
|
|
148
|
+
}
|
|
149
|
+
catch { }
|
|
145
150
|
}
|
|
@@ -54,6 +54,27 @@ export function registerAnalyticsRoutes(app) {
|
|
|
54
54
|
}
|
|
55
55
|
return { ok: true };
|
|
56
56
|
});
|
|
57
|
+
// ── Preflight Suite telemetry — fire-and-forget ping per CLI run ─────────
|
|
58
|
+
// Accepts: { event, package, command, version, node_version, platform, anonymous_id }
|
|
59
|
+
// No PII. Never stores IP addresses. Always returns 200.
|
|
60
|
+
app.post('/telemetry', async (req) => {
|
|
61
|
+
try {
|
|
62
|
+
const body = req.body;
|
|
63
|
+
const anonymousId = body?.anonymous_id ? String(body.anonymous_id).slice(0, 64) : null;
|
|
64
|
+
if (!anonymousId)
|
|
65
|
+
return { ok: true };
|
|
66
|
+
const db = getDb();
|
|
67
|
+
db.prepare(`
|
|
68
|
+
INSERT INTO cli_telemetry
|
|
69
|
+
(install_id, package, event, command, version, platform, node_version, created_at)
|
|
70
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
|
|
71
|
+
`).run(anonymousId, body?.package ? String(body.package).slice(0, 64) : null, body?.event ? String(body.event).slice(0, 64) : 'command_run', body?.command ? String(body.command).slice(0, 64) : null, body?.version ? String(body.version).slice(0, 32) : null, body?.platform ? String(body.platform).slice(0, 32) : null, body?.node_version ? String(body.node_version).slice(0, 32) : null);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// never fail — telemetry is non-critical
|
|
75
|
+
}
|
|
76
|
+
return { ok: true };
|
|
77
|
+
});
|
|
57
78
|
// ── CLI telemetry receiver ────────────────────────────────────────────────
|
|
58
79
|
// Receives events from CLI users who have opted in to telemetry.
|
|
59
80
|
// Always returns 200 — never interrupt a CLI session for analytics.
|
package/package.json
CHANGED