content-grade 1.0.8 → 1.0.10

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 CHANGED
@@ -16,7 +16,7 @@ Thanks for wanting to contribute. ContentGrade is a CLI + web dashboard for AI-p
16
16
  ## Local development setup
17
17
 
18
18
  ```bash
19
- git clone https://github.com/StanislavBG/Content-Grade
19
+ git clone https://github.com/Content-Grade/Content-Grade
20
20
  cd Content-Grade
21
21
  pnpm install
22
22
  pnpm dev
@@ -15,7 +15,7 @@
15
15
 
16
16
  import { execFileSync, execFile, spawn } from 'child_process';
17
17
  import { existsSync, readFileSync, mkdirSync, writeFileSync, unlinkSync, statSync } from 'fs';
18
- import { resolve, dirname, basename, extname } from 'path';
18
+ import { resolve, dirname, basename, extname, join } from 'path';
19
19
  import { homedir } from 'os';
20
20
  import { fileURLToPath } from 'url';
21
21
  import { promisify } from 'util';
@@ -113,7 +113,7 @@ function blank() { console.log(''); }
113
113
  function banner() {
114
114
  blank();
115
115
  console.log(`${B}${CY} ╔═══════════════════════════════════════╗${R}`);
116
- console.log(`${B}${CY} ║ ContentGrade · Content Analysis ║${R}`);
116
+ console.log(`${B}${CY} ║ ContentGrade · AI content scoring ║${R}`);
117
117
  console.log(`${B}${CY} ╚═══════════════════════════════════════╝${R}`);
118
118
  blank();
119
119
  }
@@ -1150,16 +1150,79 @@ async function cmdCheckUpdates() {
1150
1150
  blank();
1151
1151
  }
1152
1152
 
1153
+ // ── Metrics ───────────────────────────────────────────────────────────────────
1154
+
1155
+ async function cmdMetrics() {
1156
+ blank();
1157
+ console.log(` ${B}ContentGrade Metrics${R}`);
1158
+ blank();
1159
+
1160
+ // 1. npm download stats (public API, no auth)
1161
+ console.log(` ${B}npm Downloads${R}`);
1162
+ const fetchNpm = (period) => new Promise((resolve) => {
1163
+ const url = `https://api.npmjs.org/downloads/point/${period}/content-grade`;
1164
+ const mod = url.startsWith('https') ? httpsGet : httpGet;
1165
+ const req = mod(url, { timeout: 5000 }, (res) => {
1166
+ let data = '';
1167
+ res.on('data', (c) => data += c);
1168
+ res.on('end', () => {
1169
+ try { resolve(JSON.parse(data)); } catch { resolve(null); }
1170
+ });
1171
+ });
1172
+ req.on('error', () => resolve(null));
1173
+ req.on('timeout', () => { req.destroy(); resolve(null); });
1174
+ });
1175
+
1176
+ const [week, month] = await Promise.all([
1177
+ fetchNpm('last-week'),
1178
+ fetchNpm('last-month'),
1179
+ ]);
1180
+ if (week?.downloads != null) {
1181
+ console.log(` ${D}Last 7 days: ${R}${B}${week.downloads.toLocaleString()}${R} installs`);
1182
+ } else {
1183
+ console.log(` ${D}Last 7 days: ${R}${D}unavailable (offline?)${R}`);
1184
+ }
1185
+ if (month?.downloads != null) {
1186
+ console.log(` ${D}Last 30 days: ${R}${B}${month.downloads.toLocaleString()}${R} installs`);
1187
+ }
1188
+ blank();
1189
+
1190
+ // 2. Local telemetry summary
1191
+ console.log(` ${B}Local Usage${R}`);
1192
+ const eventsFile = join(homedir(), '.content-grade', 'events.jsonl');
1193
+ try {
1194
+ const lines = readFileSync(eventsFile, 'utf8').trim().split('\n').filter(Boolean);
1195
+ const events = lines.map(l => { try { return JSON.parse(l); } catch { return null; } }).filter(Boolean);
1196
+ const commands = events.filter(e => e.event === 'command');
1197
+ const installs = events.filter(e => e.event === 'install');
1198
+ const byCmd = {};
1199
+ for (const e of commands) { byCmd[e.command] = (byCmd[e.command] || 0) + 1; }
1200
+ console.log(` ${D}Total runs: ${R}${B}${commands.length}${R}`);
1201
+ console.log(` ${D}Installs: ${R}${B}${installs.length}${R}`);
1202
+ if (Object.keys(byCmd).length) {
1203
+ const top = Object.entries(byCmd).sort((a, b) => b[1] - a[1]).slice(0, 5);
1204
+ console.log(` ${D}Top commands: ${R}${top.map(([k, v]) => `${CY}${k}${R}(${v})`).join(' ')}`);
1205
+ }
1206
+ } catch {
1207
+ console.log(` ${D}No local events yet${R}`);
1208
+ }
1209
+ blank();
1210
+
1211
+ console.log(` ${D}Full install history: ${CY}https://npmjs.com/package/content-grade${R}`);
1212
+ blank();
1213
+ }
1214
+
1153
1215
  // ── Help ──────────────────────────────────────────────────────────────────────
1154
1216
 
1155
1217
  function cmdHelp() {
1156
1218
  banner();
1219
+ console.log(` ${D}AI-powered content quality scoring — readability, SEO, structure analysis${R}`);
1157
1220
  console.log(` ${D}v${_version} · ${CY}content-grade.github.io/Content-Grade${R}`);
1158
1221
  blank();
1159
1222
  console.log(` ${B}QUICK START${R}`);
1160
1223
  blank();
1161
- console.log(` ${CY}npx content-grade headline "Your title here"${R} ${D}# grade a headline (fastest, ~5s)${R}`);
1162
- console.log(` ${CY}npx content-grade analyze ./post.md${R} ${D}# full AI content analysis (~20s)${R}`);
1224
+ console.log(` ${CY}npx content-grade headline "Your Headline Here"${R} ${D}# grade a headline (fastest, ~5s)${R}`);
1225
+ console.log(` ${CY}npx content-grade analyze ./my-post.md${R} ${D}# full AI content analysis (~20s)${R}`);
1163
1226
  console.log(` ${CY}npx content-grade demo${R} ${D}# live demo on sample content${R}`);
1164
1227
  console.log(` ${CY}npx content-grade start${R} ${D}# launch web dashboard (6 tools)${R}`);
1165
1228
  blank();
@@ -1191,6 +1254,8 @@ function cmdHelp() {
1191
1254
  blank();
1192
1255
  console.log(` ${CY}init${R} Run if Claude CLI isn't detected or tools aren't working`);
1193
1256
  blank();
1257
+ console.log(` ${CY}metrics${R} Show npm download counts and local usage stats`);
1258
+ blank();
1194
1259
  console.log(` ${CY}telemetry [on|off]${R} View or toggle anonymous usage tracking`);
1195
1260
  blank();
1196
1261
  console.log(` ${CY}check-updates${R} Check if a newer version is available on npm`);
@@ -1745,6 +1810,10 @@ switch (cmd) {
1745
1810
  console.log(`content-grade v${_version}`);
1746
1811
  break;
1747
1812
 
1813
+ case 'metrics':
1814
+ cmdMetrics().catch(() => {});
1815
+ break;
1816
+
1748
1817
  case 'telemetry': {
1749
1818
  const sub = args[1];
1750
1819
  if (sub === 'off') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "content-grade",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "description": "AI-powered content analysis CLI. Score any blog post, landing page, or ad copy in under 30 seconds — runs on Claude CLI, no API key needed.",
5
5
  "type": "module",
6
6
  "bin": {