@edtools/cli 0.4.1 → 0.6.0

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.
Files changed (42) hide show
  1. package/dist/adapters/html/index.d.ts.map +1 -1
  2. package/dist/adapters/html/index.js +14 -3
  3. package/dist/adapters/html/index.js.map +1 -1
  4. package/dist/adapters/html/templates/blog-index.html.ejs +342 -0
  5. package/dist/adapters/html/templates/blog-post.html.ejs +48 -0
  6. package/dist/chunk-AJSCN4WK.js +663 -0
  7. package/dist/chunk-INVECVSW.js +45 -0
  8. package/dist/chunk-JCUQ7D56.js +688 -0
  9. package/dist/chunk-UMREI3K7.js +652 -0
  10. package/dist/chunk-ZDV7BJZ4.js +652 -0
  11. package/dist/chunk-ZG6JJCRI.js +539 -0
  12. package/dist/cli/commands/generate.d.ts +2 -0
  13. package/dist/cli/commands/generate.d.ts.map +1 -1
  14. package/dist/cli/commands/generate.js +114 -38
  15. package/dist/cli/commands/generate.js.map +1 -1
  16. package/dist/cli/commands/validate.d.ts +9 -0
  17. package/dist/cli/commands/validate.d.ts.map +1 -0
  18. package/dist/cli/commands/validate.js +196 -0
  19. package/dist/cli/commands/validate.js.map +1 -0
  20. package/dist/cli/index.js +535 -46
  21. package/dist/cli/index.js.map +1 -1
  22. package/dist/content-helpers-TXVEJMQK.js +16 -0
  23. package/dist/core/generator.d.ts +2 -0
  24. package/dist/core/generator.d.ts.map +1 -1
  25. package/dist/core/generator.js +148 -10
  26. package/dist/core/generator.js.map +1 -1
  27. package/dist/index.d.ts +92 -1
  28. package/dist/index.js +2 -1
  29. package/dist/types/content.d.ts +89 -0
  30. package/dist/types/content.d.ts.map +1 -1
  31. package/dist/ui/banner.d.ts.map +1 -1
  32. package/dist/ui/banner.js +9 -1
  33. package/dist/ui/banner.js.map +1 -1
  34. package/dist/utils/content-helpers.d.ts +7 -0
  35. package/dist/utils/content-helpers.d.ts.map +1 -0
  36. package/dist/utils/content-helpers.js +48 -0
  37. package/dist/utils/content-helpers.js.map +1 -0
  38. package/dist/utils/seo-validator.d.ts +35 -0
  39. package/dist/utils/seo-validator.d.ts.map +1 -0
  40. package/dist/utils/seo-validator.js +244 -0
  41. package/dist/utils/seo-validator.js.map +1 -0
  42. package/package.json +3 -3
@@ -0,0 +1,48 @@
1
+ import { randomUUID } from 'crypto';
2
+ export function generateUUID() {
3
+ return randomUUID();
4
+ }
5
+ export function calculateWordCount(text) {
6
+ const cleanText = text
7
+ .replace(/```[\s\S]*?```/g, '')
8
+ .replace(/`[^`]+`/g, '')
9
+ .replace(/\[([^\]]+)\]\([^)]+\)/g, '$1')
10
+ .replace(/[#*_~`]/g, '')
11
+ .replace(/\s+/g, ' ')
12
+ .trim();
13
+ if (!cleanText)
14
+ return 0;
15
+ return cleanText.split(/\s+/).length;
16
+ }
17
+ export function calculateReadTime(wordCount) {
18
+ const minutes = Math.ceil(wordCount / 200);
19
+ return `${minutes} min`;
20
+ }
21
+ export function extractShortDescription(text) {
22
+ const cleaned = text
23
+ .replace(/[#*_~`]/g, '')
24
+ .replace(/\s+/g, ' ')
25
+ .trim();
26
+ if (cleaned.length <= 160)
27
+ return cleaned;
28
+ const truncated = cleaned.substring(0, 160);
29
+ const lastPeriod = truncated.lastIndexOf('.');
30
+ const lastQuestion = truncated.lastIndexOf('?');
31
+ const lastExclamation = truncated.lastIndexOf('!');
32
+ const lastSentenceEnd = Math.max(lastPeriod, lastQuestion, lastExclamation);
33
+ if (lastSentenceEnd > 0) {
34
+ return cleaned.substring(0, lastSentenceEnd + 1);
35
+ }
36
+ const lastSpace = truncated.lastIndexOf(' ');
37
+ return cleaned.substring(0, lastSpace) + '...';
38
+ }
39
+ export function generateTimestamp() {
40
+ return new Date().toISOString();
41
+ }
42
+ export function calculateAvgReadTime(wordCounts) {
43
+ if (wordCounts.length === 0)
44
+ return '0 min';
45
+ const avgWords = wordCounts.reduce((sum, count) => sum + count, 0) / wordCounts.length;
46
+ return calculateReadTime(Math.round(avgWords));
47
+ }
48
+ //# sourceMappingURL=content-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-helpers.js","sourceRoot":"","sources":["../../src/utils/content-helpers.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAKpC,MAAM,UAAU,YAAY;IAC1B,OAAO,UAAU,EAAE,CAAC;AACtB,CAAC;AAKD,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAE7C,MAAM,SAAS,GAAG,IAAI;SACnB,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC;SAC9B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,OAAO,CAAC,wBAAwB,EAAE,IAAI,CAAC;SACvC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;IAEV,IAAI,CAAC,SAAS;QAAE,OAAO,CAAC,CAAC;IAEzB,OAAO,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;AACvC,CAAC;AAMD,MAAM,UAAU,iBAAiB,CAAC,SAAiB;IACjD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC;IAC3C,OAAO,GAAG,OAAO,MAAM,CAAC;AAC1B,CAAC;AAKD,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,MAAM,OAAO,GAAG,IAAI;SACjB,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;IAEV,IAAI,OAAO,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,OAAO,CAAC;IAG1C,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAG,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC9C,MAAM,YAAY,GAAG,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAChD,MAAM,eAAe,GAAG,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAEnD,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC;IAE5E,IAAI,eAAe,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,eAAe,GAAG,CAAC,CAAC,CAAC;IACnD,CAAC;IAGD,MAAM,SAAS,GAAG,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7C,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC;AACjD,CAAC;AAKD,MAAM,UAAU,iBAAiB;IAC/B,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAClC,CAAC;AAKD,MAAM,UAAU,oBAAoB,CAAC,UAAoB;IACvD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,OAAO,CAAC;IAE5C,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,CAAC;IACvF,OAAO,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,35 @@
1
+ export interface ValidationIssue {
2
+ severity: 'error' | 'warning' | 'info';
3
+ category: 'metadata' | 'headings' | 'content' | 'images' | 'links' | 'structure';
4
+ message: string;
5
+ suggestion?: string;
6
+ }
7
+ export interface ValidationResult {
8
+ path: string;
9
+ title: string;
10
+ seoScore: number;
11
+ issues: ValidationIssue[];
12
+ passed: string[];
13
+ metadata?: {
14
+ titleLength?: number;
15
+ descriptionLength?: number;
16
+ h1Count?: number;
17
+ h2Count?: number;
18
+ imageCount?: number;
19
+ wordCount?: number;
20
+ };
21
+ }
22
+ export declare function validatePost(htmlPath: string): Promise<ValidationResult>;
23
+ export declare function calculateValidationStats(results: ValidationResult[]): {
24
+ totalPosts: number;
25
+ avgSeoScore: number;
26
+ totalIssues: number;
27
+ postsWithIssues: number;
28
+ issuesBySeverity: {
29
+ error: number;
30
+ warning: number;
31
+ info: number;
32
+ };
33
+ issuesByCategory: Record<string, number>;
34
+ };
35
+ //# sourceMappingURL=seo-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-validator.d.ts","sourceRoot":"","sources":["../../src/utils/seo-validator.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;IACvC,QAAQ,EAAE,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,OAAO,GAAG,WAAW,CAAC;IACjF,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE;QACT,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAKD,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA2O9E;AAKD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,gBAAgB,EAAE;;;;;;;;;;;EA2BnE"}
@@ -0,0 +1,244 @@
1
+ import * as cheerio from 'cheerio';
2
+ import fs from 'fs-extra';
3
+ export async function validatePost(htmlPath) {
4
+ const html = await fs.readFile(htmlPath, 'utf-8');
5
+ const $ = cheerio.load(html);
6
+ const issues = [];
7
+ const passed = [];
8
+ const metadata = {};
9
+ const title = $('title').text().trim();
10
+ metadata.titleLength = title.length;
11
+ if (!title) {
12
+ issues.push({
13
+ severity: 'error',
14
+ category: 'metadata',
15
+ message: 'Missing <title> tag',
16
+ suggestion: 'Add a descriptive title (50-60 characters)'
17
+ });
18
+ }
19
+ else if (title.length < 30) {
20
+ issues.push({
21
+ severity: 'warning',
22
+ category: 'metadata',
23
+ message: `Title too short (${title.length} chars)`,
24
+ suggestion: 'Optimal length is 50-60 characters for better CTR'
25
+ });
26
+ }
27
+ else if (title.length > 60) {
28
+ issues.push({
29
+ severity: 'warning',
30
+ category: 'metadata',
31
+ message: `Title too long (${title.length} chars)`,
32
+ suggestion: 'Shorten to 50-60 characters to avoid truncation in SERPs'
33
+ });
34
+ }
35
+ else {
36
+ passed.push(`Title length optimal (${title.length} chars)`);
37
+ }
38
+ const metaDesc = $('meta[name="description"]').attr('content')?.trim() || '';
39
+ metadata.descriptionLength = metaDesc.length;
40
+ if (!metaDesc) {
41
+ issues.push({
42
+ severity: 'error',
43
+ category: 'metadata',
44
+ message: 'Missing meta description',
45
+ suggestion: 'Add a compelling description (150-160 characters)'
46
+ });
47
+ }
48
+ else if (metaDesc.length < 120) {
49
+ issues.push({
50
+ severity: 'warning',
51
+ category: 'metadata',
52
+ message: `Meta description too short (${metaDesc.length}/160 chars)`,
53
+ suggestion: `Add ${160 - metaDesc.length} more characters to optimize CTR`
54
+ });
55
+ }
56
+ else if (metaDesc.length > 160) {
57
+ issues.push({
58
+ severity: 'warning',
59
+ category: 'metadata',
60
+ message: `Meta description too long (${metaDesc.length}/160 chars)`,
61
+ suggestion: `Remove ${metaDesc.length - 160} characters to avoid truncation`
62
+ });
63
+ }
64
+ else {
65
+ passed.push(`Meta description optimal (${metaDesc.length} chars)`);
66
+ }
67
+ const h1Elements = $('h1');
68
+ const h1Count = h1Elements.length;
69
+ metadata.h1Count = h1Count;
70
+ if (h1Count === 0) {
71
+ issues.push({
72
+ severity: 'error',
73
+ category: 'headings',
74
+ message: 'Missing H1 heading',
75
+ suggestion: 'Add a single H1 with primary keyword'
76
+ });
77
+ }
78
+ else if (h1Count > 1) {
79
+ issues.push({
80
+ severity: 'warning',
81
+ category: 'headings',
82
+ message: `Multiple H1 tags found (${h1Count})`,
83
+ suggestion: 'Use only one H1 per page for proper structure'
84
+ });
85
+ }
86
+ else {
87
+ passed.push('Single H1 heading');
88
+ }
89
+ const h2Count = $('h2').length;
90
+ metadata.h2Count = h2Count;
91
+ if (h2Count < 2) {
92
+ issues.push({
93
+ severity: 'warning',
94
+ category: 'headings',
95
+ message: `Few H2 headings for readability (${h2Count} found)`,
96
+ suggestion: 'Add 3-5 H2 headings for better structure and scannability'
97
+ });
98
+ }
99
+ else if (h2Count > 10) {
100
+ issues.push({
101
+ severity: 'info',
102
+ category: 'headings',
103
+ message: `Many H2 headings (${h2Count})`,
104
+ suggestion: 'Consider if all sections need H2 or some should be H3'
105
+ });
106
+ }
107
+ else {
108
+ passed.push(`Good heading structure (${h2Count} H2s)`);
109
+ }
110
+ const images = $('img');
111
+ metadata.imageCount = images.length;
112
+ const imagesWithoutAlt = images.filter((i, el) => !$(el).attr('alt')).length;
113
+ if (imagesWithoutAlt > 0) {
114
+ issues.push({
115
+ severity: 'warning',
116
+ category: 'images',
117
+ message: `${imagesWithoutAlt} image${imagesWithoutAlt > 1 ? 's' : ''} missing alt text`,
118
+ suggestion: 'Add descriptive alt text to all images for accessibility and SEO'
119
+ });
120
+ }
121
+ else if (images.length > 0) {
122
+ passed.push(`All images have alt text (${images.length} images)`);
123
+ }
124
+ const schemaScript = $('script[type="application/ld+json"]');
125
+ if (schemaScript.length === 0) {
126
+ issues.push({
127
+ severity: 'info',
128
+ category: 'structure',
129
+ message: 'Missing Schema.org markup',
130
+ suggestion: 'Add structured data for rich snippets in search results'
131
+ });
132
+ }
133
+ else {
134
+ passed.push('Has Schema.org markup');
135
+ }
136
+ const metaKeywords = $('meta[name="keywords"]');
137
+ if (metaKeywords.length > 0) {
138
+ issues.push({
139
+ severity: 'info',
140
+ category: 'metadata',
141
+ message: 'Using deprecated meta keywords tag',
142
+ suggestion: 'Remove meta keywords tag (not used by modern search engines)'
143
+ });
144
+ }
145
+ const ogTitle = $('meta[property="og:title"]').attr('content');
146
+ const ogDescription = $('meta[property="og:description"]').attr('content');
147
+ const ogImage = $('meta[property="og:image"]').attr('content');
148
+ if (!ogTitle || !ogDescription) {
149
+ issues.push({
150
+ severity: 'info',
151
+ category: 'metadata',
152
+ message: 'Missing Open Graph tags',
153
+ suggestion: 'Add og:title, og:description, og:image for better social sharing'
154
+ });
155
+ }
156
+ else {
157
+ passed.push('Has Open Graph tags');
158
+ }
159
+ const bodyText = $('article, main, body').text();
160
+ const wordCount = bodyText
161
+ .replace(/\s+/g, ' ')
162
+ .trim()
163
+ .split(/\s+/)
164
+ .filter(word => word.length > 0).length;
165
+ metadata.wordCount = wordCount;
166
+ if (wordCount < 300) {
167
+ issues.push({
168
+ severity: 'warning',
169
+ category: 'content',
170
+ message: `Content too short (${wordCount} words)`,
171
+ suggestion: 'Aim for at least 1000 words for better SEO performance'
172
+ });
173
+ }
174
+ else if (wordCount < 1000) {
175
+ issues.push({
176
+ severity: 'info',
177
+ category: 'content',
178
+ message: `Content could be longer (${wordCount} words)`,
179
+ suggestion: 'Consider expanding to 1500+ words for comprehensive coverage'
180
+ });
181
+ }
182
+ else {
183
+ passed.push(`Good content length (${wordCount} words)`);
184
+ }
185
+ const links = $('a[href]');
186
+ const internalLinks = links.filter((i, el) => {
187
+ const href = $(el).attr('href') || '';
188
+ return href.startsWith('/') || href.startsWith('#');
189
+ }).length;
190
+ const externalLinks = links.length - internalLinks;
191
+ if (internalLinks === 0 && links.length > 0) {
192
+ issues.push({
193
+ severity: 'info',
194
+ category: 'links',
195
+ message: 'No internal links found',
196
+ suggestion: 'Add 2-3 internal links to related content'
197
+ });
198
+ }
199
+ else if (internalLinks > 0) {
200
+ passed.push(`Has internal links (${internalLinks} links)`);
201
+ }
202
+ const errorCount = issues.filter(i => i.severity === 'error').length;
203
+ const warningCount = issues.filter(i => i.severity === 'warning').length;
204
+ const infoCount = issues.filter(i => i.severity === 'info').length;
205
+ let score = 100;
206
+ score -= errorCount * 20;
207
+ score -= warningCount * 7;
208
+ score -= infoCount * 2;
209
+ score = Math.max(0, Math.min(100, score));
210
+ return {
211
+ path: htmlPath,
212
+ title: title || 'Untitled',
213
+ seoScore: score,
214
+ issues,
215
+ passed,
216
+ metadata
217
+ };
218
+ }
219
+ export function calculateValidationStats(results) {
220
+ const totalPosts = results.length;
221
+ const avgSeoScore = results.reduce((sum, r) => sum + r.seoScore, 0) / totalPosts;
222
+ const totalIssues = results.reduce((sum, r) => sum + r.issues.length, 0);
223
+ const postsWithIssues = results.filter(r => r.issues.length > 0).length;
224
+ const issuesBySeverity = {
225
+ error: results.reduce((sum, r) => sum + r.issues.filter(i => i.severity === 'error').length, 0),
226
+ warning: results.reduce((sum, r) => sum + r.issues.filter(i => i.severity === 'warning').length, 0),
227
+ info: results.reduce((sum, r) => sum + r.issues.filter(i => i.severity === 'info').length, 0),
228
+ };
229
+ const issuesByCategory = results.reduce((acc, r) => {
230
+ r.issues.forEach(issue => {
231
+ acc[issue.category] = (acc[issue.category] || 0) + 1;
232
+ });
233
+ return acc;
234
+ }, {});
235
+ return {
236
+ totalPosts,
237
+ avgSeoScore: Math.round(avgSeoScore * 10) / 10,
238
+ totalIssues,
239
+ postsWithIssues,
240
+ issuesBySeverity,
241
+ issuesByCategory
242
+ };
243
+ }
244
+ //# sourceMappingURL=seo-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seo-validator.js","sourceRoot":"","sources":["../../src/utils/seo-validator.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@edtools/cli",
3
- "version": "0.4.1",
4
- "description": "AI-Powered Content Marketing CLI - Generate SEO-optimized content with Google Search Console analysis",
3
+ "version": "0.6.0",
4
+ "description": "AI-Powered Content Marketing CLI - Generate, validate, and optimize SEO content with data-driven insights",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -15,7 +15,7 @@
15
15
  ],
16
16
  "scripts": {
17
17
  "build": "tsc && tsup src/index.ts src/cli/index.ts --format esm --dts && npm run copy-templates",
18
- "copy-templates": "mkdir -p dist/adapters/html/templates dist/templates && cp src/adapters/html/templates/*.ejs dist/adapters/html/templates/ && cp src/adapters/html/templates/*.ejs dist/templates/",
18
+ "copy-templates": "mkdir -p dist/adapters/html/templates dist/templates && cp src/adapters/html/templates/*.ejs dist/adapters/html/templates/",
19
19
  "dev": "tsc --watch",
20
20
  "test": "echo \"Tests coming soon\"",
21
21
  "prepublishOnly": "npm run build"