@edtools/cli 0.3.3 → 0.4.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.
- package/dist/cli/commands/analyze.d.ts +9 -0
- package/dist/cli/commands/analyze.d.ts.map +1 -0
- package/dist/cli/commands/analyze.js +146 -0
- package/dist/cli/commands/analyze.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +1 -0
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +70 -26
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +9 -9
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/index.js +458 -71
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +38 -1
- package/dist/integrations/gsc-csv-analyzer.d.ts +5 -0
- package/dist/integrations/gsc-csv-analyzer.d.ts.map +1 -0
- package/dist/integrations/gsc-csv-analyzer.js +110 -0
- package/dist/integrations/gsc-csv-analyzer.js.map +1 -0
- package/dist/types/analytics.d.ts +37 -0
- package/dist/types/analytics.d.ts.map +1 -0
- package/dist/types/analytics.js +2 -0
- package/dist/types/analytics.js.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +1 -1
- package/dist/ui/banner.d.ts +7 -0
- package/dist/ui/banner.d.ts.map +1 -0
- package/dist/ui/banner.js +76 -0
- package/dist/ui/banner.js.map +1 -0
- package/package.json +9 -2
package/dist/index.d.ts
CHANGED
|
@@ -141,6 +141,43 @@ declare class AdapterRegistry {
|
|
|
141
141
|
list(): string[];
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
+
interface GSCKeywordData {
|
|
145
|
+
query: string;
|
|
146
|
+
impressions: number;
|
|
147
|
+
clicks: number;
|
|
148
|
+
ctr: number;
|
|
149
|
+
position: number;
|
|
150
|
+
url?: string;
|
|
151
|
+
}
|
|
152
|
+
interface ContentOpportunity {
|
|
153
|
+
keyword: string;
|
|
154
|
+
impressions: number;
|
|
155
|
+
clicks: number;
|
|
156
|
+
ctr: number;
|
|
157
|
+
position: number;
|
|
158
|
+
potentialClicks: number;
|
|
159
|
+
priority: 'high' | 'medium' | 'low';
|
|
160
|
+
suggestedTitle: string;
|
|
161
|
+
reason: string;
|
|
162
|
+
}
|
|
163
|
+
interface GSCAnalysisResult {
|
|
164
|
+
totalQueries: number;
|
|
165
|
+
totalImpressions: number;
|
|
166
|
+
totalClicks: number;
|
|
167
|
+
avgCTR: number;
|
|
168
|
+
avgPosition: number;
|
|
169
|
+
opportunities: ContentOpportunity[];
|
|
170
|
+
topKeywords: GSCKeywordData[];
|
|
171
|
+
lowCTRPages: GSCKeywordData[];
|
|
172
|
+
}
|
|
173
|
+
interface OpportunityConfig {
|
|
174
|
+
minImpressions?: number;
|
|
175
|
+
minPosition?: number;
|
|
176
|
+
maxPosition?: number;
|
|
177
|
+
minPotentialClicks?: number;
|
|
178
|
+
limit?: number;
|
|
179
|
+
}
|
|
180
|
+
|
|
144
181
|
declare class ContentGenerator {
|
|
145
182
|
private anthropic;
|
|
146
183
|
private openai;
|
|
@@ -173,4 +210,4 @@ declare class HTMLAdapter implements Adapter {
|
|
|
173
210
|
private escapeHtml;
|
|
174
211
|
}
|
|
175
212
|
|
|
176
|
-
export { type AIProvider, type Adapter, type AdapterConfig, AdapterRegistry, type BlogPostContent, type BlogPostMetadata, type CTAData, type CodeData, type ComparisonData, ContentGenerator, type ContentSection, type GenerateConfig, type GenerateResult, HTMLAdapter, type ListData, type ProductInfo, type RelatedPost, type SEOData, type SchemaOrgData };
|
|
213
|
+
export { type AIProvider, type Adapter, type AdapterConfig, AdapterRegistry, type BlogPostContent, type BlogPostMetadata, type CTAData, type CodeData, type ComparisonData, ContentGenerator, type ContentOpportunity, type ContentSection, type GSCAnalysisResult, type GSCKeywordData, type GenerateConfig, type GenerateResult, HTMLAdapter, type ListData, type OpportunityConfig, type ProductInfo, type RelatedPost, type SEOData, type SchemaOrgData };
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { GSCKeywordData, ContentOpportunity, GSCAnalysisResult, OpportunityConfig } from '../types/analytics.js';
|
|
2
|
+
export declare function parseGSCCSV(filePath: string): Promise<GSCKeywordData[]>;
|
|
3
|
+
export declare function analyzeGSCData(data: GSCKeywordData[], config?: OpportunityConfig): GSCAnalysisResult;
|
|
4
|
+
export declare function saveOpportunities(opportunities: ContentOpportunity[], outputPath: string): Promise<void>;
|
|
5
|
+
//# sourceMappingURL=gsc-csv-analyzer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gsc-csv-analyzer.d.ts","sourceRoot":"","sources":["../../src/integrations/gsc-csv-analyzer.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,uBAAuB,CAAC;AAK/B,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAkC7E;AAKD,wBAAgB,cAAc,CAC5B,IAAI,EAAE,cAAc,EAAE,EACtB,MAAM,GAAE,iBAAsB,GAC7B,iBAAiB,CAkFnB;AAwBD,wBAAsB,iBAAiB,CACrC,aAAa,EAAE,kBAAkB,EAAE,EACnC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAQf"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import { parse } from 'csv-parse/sync';
|
|
3
|
+
export async function parseGSCCSV(filePath) {
|
|
4
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
5
|
+
const records = parse(content, {
|
|
6
|
+
columns: true,
|
|
7
|
+
skip_empty_lines: true,
|
|
8
|
+
cast: (value, context) => {
|
|
9
|
+
if (context.column === 'Clicks' || context.column === 'Impressions') {
|
|
10
|
+
return parseInt(value.replace(/,/g, ''), 10);
|
|
11
|
+
}
|
|
12
|
+
if (context.column === 'CTR') {
|
|
13
|
+
return parseFloat(value.replace('%', '')) / 100;
|
|
14
|
+
}
|
|
15
|
+
if (context.column === 'Position') {
|
|
16
|
+
return parseFloat(value);
|
|
17
|
+
}
|
|
18
|
+
return value;
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
const data = records.map((record) => ({
|
|
22
|
+
query: record['Top queries'] || record['Query'] || record['query'] || '',
|
|
23
|
+
impressions: record['Impressions'] || record['impressions'] || 0,
|
|
24
|
+
clicks: record['Clicks'] || record['clicks'] || 0,
|
|
25
|
+
ctr: record['CTR'] || record['ctr'] || 0,
|
|
26
|
+
position: record['Position'] || record['position'] || 0,
|
|
27
|
+
url: record['Top pages'] || record['Page'] || record['url'] || undefined,
|
|
28
|
+
}));
|
|
29
|
+
return data.filter((d) => d.query && d.impressions > 0);
|
|
30
|
+
}
|
|
31
|
+
export function analyzeGSCData(data, config = {}) {
|
|
32
|
+
const { minImpressions = 50, minPosition = 20, maxPosition = 100, minPotentialClicks = 10, limit = 10, } = config;
|
|
33
|
+
const totalQueries = data.length;
|
|
34
|
+
const totalImpressions = data.reduce((sum, d) => sum + d.impressions, 0);
|
|
35
|
+
const totalClicks = data.reduce((sum, d) => sum + d.clicks, 0);
|
|
36
|
+
const avgCTR = totalClicks / totalImpressions || 0;
|
|
37
|
+
const avgPosition = data.reduce((sum, d) => sum + d.position, 0) / totalQueries || 0;
|
|
38
|
+
const opportunities = data
|
|
39
|
+
.filter((d) => d.impressions >= minImpressions && d.position >= minPosition && d.position <= maxPosition)
|
|
40
|
+
.map((d) => {
|
|
41
|
+
const estimatedCTRTop10 = 0.15;
|
|
42
|
+
const potentialClicks = Math.round(d.impressions * estimatedCTRTop10 - d.clicks);
|
|
43
|
+
let priority = 'low';
|
|
44
|
+
if (d.impressions > 100 && potentialClicks > 20) {
|
|
45
|
+
priority = 'high';
|
|
46
|
+
}
|
|
47
|
+
else if (d.impressions > 50 && potentialClicks > 10) {
|
|
48
|
+
priority = 'medium';
|
|
49
|
+
}
|
|
50
|
+
const suggestedTitle = generateSuggestedTitle(d.query);
|
|
51
|
+
const reason = `${d.impressions} impressions at position ${d.position.toFixed(1)} → potential +${potentialClicks} clicks`;
|
|
52
|
+
return {
|
|
53
|
+
keyword: d.query,
|
|
54
|
+
impressions: d.impressions,
|
|
55
|
+
clicks: d.clicks,
|
|
56
|
+
ctr: d.ctr,
|
|
57
|
+
position: d.position,
|
|
58
|
+
potentialClicks,
|
|
59
|
+
priority,
|
|
60
|
+
suggestedTitle,
|
|
61
|
+
reason,
|
|
62
|
+
};
|
|
63
|
+
})
|
|
64
|
+
.filter((opp) => opp.potentialClicks >= minPotentialClicks)
|
|
65
|
+
.sort((a, b) => {
|
|
66
|
+
const priorityOrder = { high: 3, medium: 2, low: 1 };
|
|
67
|
+
const priorityDiff = priorityOrder[b.priority] - priorityOrder[a.priority];
|
|
68
|
+
if (priorityDiff !== 0)
|
|
69
|
+
return priorityDiff;
|
|
70
|
+
return b.potentialClicks - a.potentialClicks;
|
|
71
|
+
})
|
|
72
|
+
.slice(0, limit);
|
|
73
|
+
const topKeywords = [...data]
|
|
74
|
+
.sort((a, b) => b.clicks - a.clicks)
|
|
75
|
+
.slice(0, 10);
|
|
76
|
+
const lowCTRPages = data
|
|
77
|
+
.filter((d) => d.position <= 20 && d.ctr < 0.02)
|
|
78
|
+
.sort((a, b) => a.ctr - b.ctr)
|
|
79
|
+
.slice(0, 10);
|
|
80
|
+
return {
|
|
81
|
+
totalQueries,
|
|
82
|
+
totalImpressions,
|
|
83
|
+
totalClicks,
|
|
84
|
+
avgCTR,
|
|
85
|
+
avgPosition,
|
|
86
|
+
opportunities,
|
|
87
|
+
topKeywords,
|
|
88
|
+
lowCTRPages,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function generateSuggestedTitle(keyword) {
|
|
92
|
+
const words = keyword.split(' ');
|
|
93
|
+
const capitalized = words
|
|
94
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
|
|
95
|
+
.join(' ');
|
|
96
|
+
const currentYear = new Date().getFullYear();
|
|
97
|
+
if (!capitalized.includes(currentYear.toString())) {
|
|
98
|
+
return `${capitalized}: Complete Guide ${currentYear}`;
|
|
99
|
+
}
|
|
100
|
+
return `${capitalized}: Complete Guide`;
|
|
101
|
+
}
|
|
102
|
+
export async function saveOpportunities(opportunities, outputPath) {
|
|
103
|
+
const data = {
|
|
104
|
+
generatedAt: new Date().toISOString(),
|
|
105
|
+
count: opportunities.length,
|
|
106
|
+
opportunities,
|
|
107
|
+
};
|
|
108
|
+
await fs.writeJson(outputPath, data, { spaces: 2 });
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=gsc-csv-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gsc-csv-analyzer.js","sourceRoot":"","sources":["../../src/integrations/gsc-csv-analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface GSCKeywordData {
|
|
2
|
+
query: string;
|
|
3
|
+
impressions: number;
|
|
4
|
+
clicks: number;
|
|
5
|
+
ctr: number;
|
|
6
|
+
position: number;
|
|
7
|
+
url?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ContentOpportunity {
|
|
10
|
+
keyword: string;
|
|
11
|
+
impressions: number;
|
|
12
|
+
clicks: number;
|
|
13
|
+
ctr: number;
|
|
14
|
+
position: number;
|
|
15
|
+
potentialClicks: number;
|
|
16
|
+
priority: 'high' | 'medium' | 'low';
|
|
17
|
+
suggestedTitle: string;
|
|
18
|
+
reason: string;
|
|
19
|
+
}
|
|
20
|
+
export interface GSCAnalysisResult {
|
|
21
|
+
totalQueries: number;
|
|
22
|
+
totalImpressions: number;
|
|
23
|
+
totalClicks: number;
|
|
24
|
+
avgCTR: number;
|
|
25
|
+
avgPosition: number;
|
|
26
|
+
opportunities: ContentOpportunity[];
|
|
27
|
+
topKeywords: GSCKeywordData[];
|
|
28
|
+
lowCTRPages: GSCKeywordData[];
|
|
29
|
+
}
|
|
30
|
+
export interface OpportunityConfig {
|
|
31
|
+
minImpressions?: number;
|
|
32
|
+
minPosition?: number;
|
|
33
|
+
maxPosition?: number;
|
|
34
|
+
minPotentialClicks?: number;
|
|
35
|
+
limit?: number;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=analytics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.d.ts","sourceRoot":"","sources":["../../src/types/analytics.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAKD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AAKD,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,kBAAkB,EAAE,CAAC;IACpC,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,WAAW,EAAE,cAAc,EAAE,CAAC;CAC/B;AAKD,MAAM,WAAW,iBAAiB;IAChC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analytics.js","sourceRoot":"","sources":["../../src/types/analytics.ts"],"names":[],"mappings":""}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAIA,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAIA,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
|
package/dist/types/index.js
CHANGED
package/dist/types/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAIA,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAIA,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function generateBanner(): string;
|
|
2
|
+
export declare function showWelcome(): void;
|
|
3
|
+
export declare function successBox(message: string): string;
|
|
4
|
+
export declare function errorBox(message: string): string;
|
|
5
|
+
export declare function infoBox(title: string, content: string): string;
|
|
6
|
+
export declare function warningBox(message: string): string;
|
|
7
|
+
//# sourceMappingURL=banner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"banner.d.ts","sourceRoot":"","sources":["../../src/ui/banner.ts"],"names":[],"mappings":"AAQA,wBAAgB,cAAc,IAAI,MAAM,CAsBvC;AAKD,wBAAgB,WAAW,IAAI,IAAI,CAYlC;AAiBD,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOlD;AAKD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOhD;AAKD,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAO9D;AAKD,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOlD"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import figlet from 'figlet';
|
|
2
|
+
import gradient from 'gradient-string';
|
|
3
|
+
import boxen from 'boxen';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
export function generateBanner() {
|
|
6
|
+
const asciiArt = figlet.textSync('edtools', {
|
|
7
|
+
font: 'ANSI Shadow',
|
|
8
|
+
horizontalLayout: 'default',
|
|
9
|
+
verticalLayout: 'default',
|
|
10
|
+
});
|
|
11
|
+
const coloredAscii = gradient(['#00D9FF', '#00FF9F'])(asciiArt);
|
|
12
|
+
const tagline = chalk.gray('AI-Powered Content Marketing CLI');
|
|
13
|
+
const version = chalk.dim(`v${getVersion()}`);
|
|
14
|
+
const content = `${coloredAscii}\n\n${tagline} ${version}`;
|
|
15
|
+
return boxen(content, {
|
|
16
|
+
padding: 1,
|
|
17
|
+
margin: 1,
|
|
18
|
+
borderStyle: 'round',
|
|
19
|
+
borderColor: 'cyan',
|
|
20
|
+
dimBorder: false,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
export function showWelcome() {
|
|
24
|
+
console.log(generateBanner());
|
|
25
|
+
console.log('');
|
|
26
|
+
console.log(chalk.bold.cyan(' Quick Start:'));
|
|
27
|
+
console.log(chalk.gray(' ────────────'));
|
|
28
|
+
console.log('');
|
|
29
|
+
console.log(` ${chalk.cyan('edtools init')} ${chalk.gray('Initialize your project')}`);
|
|
30
|
+
console.log(` ${chalk.cyan('edtools generate')} ${chalk.gray('Generate SEO-optimized posts')}`);
|
|
31
|
+
console.log(` ${chalk.cyan('edtools analyze')} ${chalk.gray('Analyze Google Search Console CSV')}`);
|
|
32
|
+
console.log('');
|
|
33
|
+
console.log(chalk.gray(' Run ') + chalk.cyan('edtools --help') + chalk.gray(' for all commands'));
|
|
34
|
+
console.log('');
|
|
35
|
+
}
|
|
36
|
+
function getVersion() {
|
|
37
|
+
try {
|
|
38
|
+
return '0.4.0';
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return 'dev';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
export function successBox(message) {
|
|
45
|
+
return boxen(chalk.green('✓ ') + message, {
|
|
46
|
+
padding: 1,
|
|
47
|
+
margin: 1,
|
|
48
|
+
borderStyle: 'round',
|
|
49
|
+
borderColor: 'green',
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
export function errorBox(message) {
|
|
53
|
+
return boxen(chalk.red('✗ ') + message, {
|
|
54
|
+
padding: 1,
|
|
55
|
+
margin: 1,
|
|
56
|
+
borderStyle: 'round',
|
|
57
|
+
borderColor: 'red',
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
export function infoBox(title, content) {
|
|
61
|
+
return boxen(`${chalk.cyan.bold(title)}\n\n${content}`, {
|
|
62
|
+
padding: 1,
|
|
63
|
+
margin: 1,
|
|
64
|
+
borderStyle: 'round',
|
|
65
|
+
borderColor: 'cyan',
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
export function warningBox(message) {
|
|
69
|
+
return boxen(chalk.yellow('⚠ ') + message, {
|
|
70
|
+
padding: 1,
|
|
71
|
+
margin: 1,
|
|
72
|
+
borderStyle: 'round',
|
|
73
|
+
borderColor: 'yellow',
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=banner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"banner.js","sourceRoot":"","sources":["../../src/ui/banner.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
|
-
"description": "Generate SEO-optimized content
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"description": "AI-Powered Content Marketing CLI - Generate SEO-optimized content with Google Search Console analysis",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -33,11 +33,16 @@
|
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@anthropic-ai/sdk": "^0.20.0",
|
|
36
|
+
"boxen": "^7.1.1",
|
|
36
37
|
"chalk": "^5.3.0",
|
|
37
38
|
"cheerio": "^1.0.0-rc.12",
|
|
39
|
+
"cli-table3": "^0.6.3",
|
|
38
40
|
"commander": "^11.1.0",
|
|
41
|
+
"csv-parse": "^5.5.3",
|
|
39
42
|
"ejs": "^3.1.9",
|
|
43
|
+
"figlet": "^1.7.0",
|
|
40
44
|
"fs-extra": "^11.2.0",
|
|
45
|
+
"gradient-string": "^2.0.2",
|
|
41
46
|
"inquirer": "^9.2.12",
|
|
42
47
|
"marked": "^11.1.1",
|
|
43
48
|
"openai": "^6.15.0",
|
|
@@ -46,7 +51,9 @@
|
|
|
46
51
|
},
|
|
47
52
|
"devDependencies": {
|
|
48
53
|
"@types/ejs": "^3.1.5",
|
|
54
|
+
"@types/figlet": "^1.5.8",
|
|
49
55
|
"@types/fs-extra": "^11.0.4",
|
|
56
|
+
"@types/gradient-string": "^1.1.5",
|
|
50
57
|
"@types/inquirer": "^9.0.7",
|
|
51
58
|
"@types/node": "^20.10.6",
|
|
52
59
|
"tsup": "^8.0.1",
|