content-grade 1.0.43 → 1.0.45

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.
@@ -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: unlimited analyses — no cap, no daily reset.${R}`);
145
- console.log(` ${WH} · Batch entire /posts/ directories at once${R}`);
146
- console.log(` ${WH} · CI integration exit codes + JSON/HTML output${R}`);
147
- console.log(` ${WH} · Priority support reply within 24h${R}`);
144
+ console.log(` ${WH}${B}Pro: grade every piece you publish — no cap, no resets, ever.${R}`);
145
+ console.log(` ${WH} · No limit run as many analyses as you need${R}`);
146
+ console.log(` ${WH} · Batch mode: grade your entire /posts/ directory in one shot${R}`);
147
+ console.log(` ${WH} · CI integration: exit codes + JSON/HTML output${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,16 +153,22 @@ 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 + clear Pro value
157
- console.log(` ${YL}${B}${count}/${limit} runs used · ${remaining} free analysis${remaining === 1 ? '' : 'es'} remaining${R}`);
156
+ // 1-2 runs left — loss aversion + specific Pro value
157
+ console.log(` ${YL}${B}${count}/${limit} runs used · ${remaining} free analysis${remaining === 1 ? '' : 'es'} left${R}`);
158
158
  blank();
159
- console.log(` ${WH}${B}Pro: unlimited runs · batch analysis · priority support${R}`);
160
- console.log(` ${MG}${B}→ Get Pro ($9/mo): ${CY}${UPGRADE_LINKS.free}${R}`);
159
+ console.log(` ${WH}${B}Pro: no cap, no resets grade every piece you publish${R}`);
160
+ console.log(` ${WH} · Batch /posts/ directories · CI exit codes · JSON output${R}`);
161
+ console.log(` ${MG}${B}→ Get Pro before you run out ($9/mo): ${CY}${UPGRADE_LINKS.free}${R}`);
161
162
  } else {
162
- // Runs available — always visible count + clear Pro benefits + Stripe link
163
+ // Runs available — rotate benefit angle each run to avoid banner blindness
164
+ const nudgeBenefits = [
165
+ `Pro: no cap — grade every piece you publish, no resets`,
166
+ `Pro: batch entire directories at once · no limits, ever`,
167
+ `Pro: CI integration · exit codes + JSON output · unlimited runs`,
168
+ ];
163
169
  console.log(` ${WH}${count}/${limit} runs used · ${remaining} remaining${R}`);
164
- console.log(` ${WH} Pro: unlimited runs · batch analysis · priority support${R}`);
165
- console.log(` ${MG}→ Upgrade ($9/mo): ${CY}${UPGRADE_LINKS.free}${R}`);
170
+ console.log(` ${WH} ${nudgeBenefits[count % 3]}${R}`);
171
+ console.log(` ${MG}→ Get Pro ($9/mo): ${CY}${UPGRADE_LINKS.free}${R}`);
166
172
  }
167
173
  hr();
168
174
  maybeShowFeedbackCTA(count);
@@ -279,10 +285,10 @@ function checkFreeTierLimit() {
279
285
  hr();
280
286
  console.log(` ${RD}${B}You've used all ${limit} free analyses.${R}`);
281
287
  blank();
282
- console.log(` ${WH}${B}Pro: unlimited analyses — no cap, no daily reset.${R}`);
283
- console.log(` ${WH} · Batch entire /posts/ directories at once${R}`);
284
- console.log(` ${WH} · CI integration exit codes + JSON/HTML output${R}`);
285
- console.log(` ${WH} · Priority support reply within 24h${R}`);
288
+ console.log(` ${WH}${B}Pro: grade every piece you publish — no cap, no resets, ever.${R}`);
289
+ console.log(` ${WH} · No limit run as many analyses as you need${R}`);
290
+ console.log(` ${WH} · Batch mode: grade your entire /posts/ directory in one shot${R}`);
291
+ console.log(` ${WH} · CI integration: exit codes + JSON/HTML output${R}`);
286
292
  blank();
287
293
  console.log(` ${MG}${B}→ Get Pro ($9/mo, cancel anytime): ${CY}${UPGRADE_LINKS.free}${R}`);
288
294
  blank();
@@ -984,7 +990,10 @@ async function cmdActivate() {
984
990
  blank();
985
991
 
986
992
  const existing = getLicenseKey();
987
- if (existing) {
993
+ // If a new key is passed explicitly, allow re-activation (tier upgrades, replacements).
994
+ // If called with no args and a key is already stored, show status and return.
995
+ const newKeyArg = args[1] && args[1].length >= 8 ? args[1] : null;
996
+ if (existing && !newKeyArg) {
988
997
  ok(`Pro license already activated`);
989
998
  blank();
990
999
  console.log(` ${D}Key: ${existing.slice(0, 8)}...${R}`);
@@ -994,6 +1003,8 @@ async function cmdActivate() {
994
1003
  console.log(` ${D} content-grade batch ./posts/ ${R}${D}# analyze all files in a directory${R}`);
995
1004
  console.log(` ${D} Unlimited analyses (vs 15 free total)${R}`);
996
1005
  blank();
1006
+ console.log(` ${D}To activate a different key: ${CY}content-grade activate <new-key>${R}`);
1007
+ blank();
997
1008
  return;
998
1009
  }
999
1010
 
@@ -1003,10 +1014,10 @@ async function cmdActivate() {
1003
1014
  blank();
1004
1015
 
1005
1016
  let key;
1006
- if (args[1] && args[1].length >= 8) {
1007
- key = args[1];
1017
+ if (newKeyArg) {
1018
+ key = newKeyArg;
1008
1019
  blank();
1009
- console.log(` ${D}Using provided key: ${args[1].slice(0, 8)}...${R}`);
1020
+ console.log(` ${D}Using provided key: ${newKeyArg.slice(0, 8)}...${R}`);
1010
1021
  blank();
1011
1022
  } else {
1012
1023
  process.stdout.write(` ${CY}License key:${R} `);
@@ -1106,7 +1117,7 @@ async function cmdActivate() {
1106
1117
  config.activatedAt = new Date().toISOString();
1107
1118
  saveConfig(config);
1108
1119
 
1109
- recordEvent({ event: 'license_activated', tier: activatedTier });
1120
+ recordEvent({ event: existing ? 'license_reactivated' : 'license_activated', tier: activatedTier });
1110
1121
 
1111
1122
  // Also write canonical license file to ~/.content-grade/license.json
1112
1123
  mkdirSync(LICENSE_DIR, { recursive: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "content-grade",
3
- "version": "1.0.43",
3
+ "version": "1.0.45",
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": {