seomd-cli 1.0.2 ā 1.0.3
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/package.json +2 -2
- package/src/commands/analyze.js +9 -4
- package/src/utils/api-client.js +18 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "seomd-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "The official CLI for the SEO.md open standard ā AEO infrastructure for technical founders",
|
|
5
5
|
"homepage": "https://seomd.dev",
|
|
6
6
|
"repository": {
|
|
@@ -47,4 +47,4 @@
|
|
|
47
47
|
"citation-tracking",
|
|
48
48
|
"llm-seo"
|
|
49
49
|
]
|
|
50
|
-
}
|
|
50
|
+
}
|
package/src/commands/analyze.js
CHANGED
|
@@ -66,20 +66,25 @@ export async function analyzeCommand(options) {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
// Filter by options.page if specified
|
|
70
|
+
if (options.page) {
|
|
71
|
+
pagesList = pagesList.filter(p => p.url === options.page);
|
|
72
|
+
}
|
|
73
|
+
|
|
69
74
|
// Default to homepage if no pages defined
|
|
70
75
|
if (pagesList.length === 0) {
|
|
71
76
|
pagesList.push({
|
|
72
77
|
id: 'homepage',
|
|
73
|
-
url: '/',
|
|
78
|
+
url: options.page || '/',
|
|
74
79
|
primary_keyword: `best ${niche}`,
|
|
75
80
|
status: 'planned'
|
|
76
81
|
});
|
|
77
82
|
}
|
|
78
83
|
|
|
79
84
|
// Extract engines
|
|
80
|
-
const engines = data.aeo?._analysis?.engines_tracked || ['
|
|
85
|
+
const engines = data.aeo?._analysis?.engines_tracked || ['ChatGPT'];
|
|
81
86
|
|
|
82
|
-
console.log(chalk.bold.cyan(`\nš
|
|
87
|
+
console.log(chalk.bold.cyan(`\nš Foxcite: Running AI Search Audit for ${chalk.white(domain)}`));
|
|
83
88
|
console.log(chalk.dim(`Engines: ${engines.join(', ')}`));
|
|
84
89
|
console.log(chalk.dim(`Pages to scan: ${pagesList.length}`));
|
|
85
90
|
console.log('');
|
|
@@ -95,7 +100,7 @@ export async function analyzeCommand(options) {
|
|
|
95
100
|
pages: pagesList.map(p => ({
|
|
96
101
|
id: p.id,
|
|
97
102
|
url: p.url,
|
|
98
|
-
primary_keyword: p.primary_keyword
|
|
103
|
+
primary_keyword: p.primary_keyword || data.keywords?.primary || `best ${niche}`,
|
|
99
104
|
status: p.status
|
|
100
105
|
}))
|
|
101
106
|
};
|
package/src/utils/api-client.js
CHANGED
|
@@ -9,6 +9,16 @@ const API_KEY = process.env.SEOMD_API_KEY;
|
|
|
9
9
|
const PAYMENT_TOKEN = process.env.SEOMD_PAYMENT_TOKEN;
|
|
10
10
|
const SEOMD_DOMAIN = process.env.SEOMD_DOMAIN;
|
|
11
11
|
|
|
12
|
+
const getDashboardUrlFromApi = (apiUrl) => {
|
|
13
|
+
if (apiUrl.includes('127.0.0.1') || apiUrl.includes('localhost')) {
|
|
14
|
+
return 'http://localhost:3000';
|
|
15
|
+
}
|
|
16
|
+
if (apiUrl.includes('api.foxcite.com')) {
|
|
17
|
+
return 'https://app.foxcite.com';
|
|
18
|
+
}
|
|
19
|
+
return 'https://seomd.dev';
|
|
20
|
+
};
|
|
21
|
+
|
|
12
22
|
export const client = axios.create({
|
|
13
23
|
baseURL: API_URL,
|
|
14
24
|
timeout: 300000, // 5 minutes timeout for LLM audits
|
|
@@ -32,7 +42,14 @@ client.interceptors.response.use(
|
|
|
32
42
|
return Promise.reject(new Error('Authentication failed: Invalid or missing API key (SEOMD_API_KEY).'));
|
|
33
43
|
}
|
|
34
44
|
if (status === 402) {
|
|
35
|
-
|
|
45
|
+
const dashUrl = getDashboardUrlFromApi(API_URL);
|
|
46
|
+
return Promise.reject(new Error(
|
|
47
|
+
`Insufficient scan credits.\n\n` +
|
|
48
|
+
`š For Humans: Recharge credits or upgrade your plan in the dashboard:\n` +
|
|
49
|
+
` ${dashUrl}/billing\n\n` +
|
|
50
|
+
`š¤ For Programmatic Agents:\n` +
|
|
51
|
+
` Set SEOMD_PAYMENT_TOKEN in your environment or headers to pay-per-scan inline using USDC via the agent-native x402 protocol.`
|
|
52
|
+
));
|
|
36
53
|
}
|
|
37
54
|
return Promise.reject(new Error(`API Error (${status}): ${detail}`));
|
|
38
55
|
}
|