@rankcli/agent-runtime 0.0.1
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/README.md +242 -0
- package/dist/analyzer-2CSWIQGD.mjs +6 -0
- package/dist/chunk-YNZYHEYM.mjs +774 -0
- package/dist/index.d.mts +4012 -0
- package/dist/index.d.ts +4012 -0
- package/dist/index.js +29672 -0
- package/dist/index.mjs +28602 -0
- package/package.json +53 -0
- package/scripts/build-deno.ts +134 -0
- package/src/audit/ai/analyzer.ts +347 -0
- package/src/audit/ai/index.ts +29 -0
- package/src/audit/ai/prompts/content-analysis.ts +271 -0
- package/src/audit/ai/types.ts +179 -0
- package/src/audit/checks/additional-checks.ts +439 -0
- package/src/audit/checks/ai-citation-worthiness.ts +399 -0
- package/src/audit/checks/ai-content-structure.ts +325 -0
- package/src/audit/checks/ai-readiness.ts +339 -0
- package/src/audit/checks/anchor-text.ts +179 -0
- package/src/audit/checks/answer-conciseness.ts +322 -0
- package/src/audit/checks/asset-minification.ts +270 -0
- package/src/audit/checks/bing-optimization.ts +206 -0
- package/src/audit/checks/brand-mention-optimization.ts +349 -0
- package/src/audit/checks/caching-headers.ts +305 -0
- package/src/audit/checks/canonical-advanced.ts +150 -0
- package/src/audit/checks/canonical-domain.ts +196 -0
- package/src/audit/checks/citation-quality.ts +358 -0
- package/src/audit/checks/client-rendering.ts +542 -0
- package/src/audit/checks/color-contrast.ts +342 -0
- package/src/audit/checks/content-freshness.ts +170 -0
- package/src/audit/checks/content-science.ts +589 -0
- package/src/audit/checks/conversion-elements.ts +526 -0
- package/src/audit/checks/crawlability.ts +220 -0
- package/src/audit/checks/directory-listing.ts +172 -0
- package/src/audit/checks/dom-analysis.ts +191 -0
- package/src/audit/checks/dom-size.ts +246 -0
- package/src/audit/checks/duplicate-content.ts +194 -0
- package/src/audit/checks/eeat-signals.ts +990 -0
- package/src/audit/checks/entity-seo.ts +396 -0
- package/src/audit/checks/featured-snippet.ts +473 -0
- package/src/audit/checks/freshness-signals.ts +443 -0
- package/src/audit/checks/funnel-intent.ts +463 -0
- package/src/audit/checks/hreflang.ts +174 -0
- package/src/audit/checks/html-compliance.ts +302 -0
- package/src/audit/checks/image-dimensions.ts +167 -0
- package/src/audit/checks/images.ts +160 -0
- package/src/audit/checks/indexnow.ts +275 -0
- package/src/audit/checks/interactive-tools.ts +475 -0
- package/src/audit/checks/internal-link-graph.ts +436 -0
- package/src/audit/checks/keyword-analysis.ts +239 -0
- package/src/audit/checks/keyword-cannibalization.ts +385 -0
- package/src/audit/checks/keyword-placement.ts +471 -0
- package/src/audit/checks/links.ts +203 -0
- package/src/audit/checks/llms-txt.ts +224 -0
- package/src/audit/checks/local-seo.ts +296 -0
- package/src/audit/checks/mobile.ts +167 -0
- package/src/audit/checks/modern-images.ts +226 -0
- package/src/audit/checks/navboost-signals.ts +395 -0
- package/src/audit/checks/on-page.ts +209 -0
- package/src/audit/checks/page-resources.ts +285 -0
- package/src/audit/checks/pagination.ts +180 -0
- package/src/audit/checks/performance.ts +153 -0
- package/src/audit/checks/platform-presence.ts +580 -0
- package/src/audit/checks/redirect-analysis.ts +153 -0
- package/src/audit/checks/redirect-chain.ts +389 -0
- package/src/audit/checks/resource-hints.ts +420 -0
- package/src/audit/checks/responsive-css.ts +247 -0
- package/src/audit/checks/responsive-images.ts +396 -0
- package/src/audit/checks/review-ecosystem.ts +415 -0
- package/src/audit/checks/robots-validation.ts +373 -0
- package/src/audit/checks/security-headers.ts +172 -0
- package/src/audit/checks/security.ts +144 -0
- package/src/audit/checks/serp-preview.ts +251 -0
- package/src/audit/checks/site-maturity.ts +444 -0
- package/src/audit/checks/social-meta.test.ts +275 -0
- package/src/audit/checks/social-meta.ts +134 -0
- package/src/audit/checks/soft-404.ts +151 -0
- package/src/audit/checks/structured-data.ts +238 -0
- package/src/audit/checks/tech-detection.ts +496 -0
- package/src/audit/checks/topical-clusters.ts +435 -0
- package/src/audit/checks/tracker-bloat.ts +462 -0
- package/src/audit/checks/tracking-verification.test.ts +371 -0
- package/src/audit/checks/tracking-verification.ts +636 -0
- package/src/audit/checks/url-safety.ts +682 -0
- package/src/audit/deno-entry.ts +66 -0
- package/src/audit/discovery/index.ts +15 -0
- package/src/audit/discovery/link-crawler.ts +232 -0
- package/src/audit/discovery/repo-routes.ts +347 -0
- package/src/audit/engine.ts +620 -0
- package/src/audit/fixes/index.ts +209 -0
- package/src/audit/fixes/social-meta-fixes.test.ts +329 -0
- package/src/audit/fixes/social-meta-fixes.ts +463 -0
- package/src/audit/index.ts +74 -0
- package/src/audit/runner.test.ts +299 -0
- package/src/audit/runner.ts +130 -0
- package/src/audit/types.ts +1953 -0
- package/src/content/featured-snippet.ts +367 -0
- package/src/content/generator.test.ts +534 -0
- package/src/content/generator.ts +501 -0
- package/src/content/headline.ts +317 -0
- package/src/content/index.ts +62 -0
- package/src/content/intent.ts +258 -0
- package/src/content/keyword-density.ts +349 -0
- package/src/content/readability.ts +262 -0
- package/src/executor.ts +336 -0
- package/src/fixer.ts +416 -0
- package/src/frameworks/detector.test.ts +248 -0
- package/src/frameworks/detector.ts +371 -0
- package/src/frameworks/index.ts +68 -0
- package/src/frameworks/recipes/angular.yaml +171 -0
- package/src/frameworks/recipes/astro.yaml +206 -0
- package/src/frameworks/recipes/django.yaml +180 -0
- package/src/frameworks/recipes/laravel.yaml +137 -0
- package/src/frameworks/recipes/nextjs.yaml +268 -0
- package/src/frameworks/recipes/nuxt.yaml +175 -0
- package/src/frameworks/recipes/rails.yaml +188 -0
- package/src/frameworks/recipes/react.yaml +202 -0
- package/src/frameworks/recipes/sveltekit.yaml +154 -0
- package/src/frameworks/recipes/vue.yaml +137 -0
- package/src/frameworks/recipes/wordpress.yaml +209 -0
- package/src/frameworks/suggestion-engine.ts +320 -0
- package/src/geo/geo-content.test.ts +305 -0
- package/src/geo/geo-content.ts +266 -0
- package/src/geo/geo-history.test.ts +473 -0
- package/src/geo/geo-history.ts +433 -0
- package/src/geo/geo-tracker.test.ts +359 -0
- package/src/geo/geo-tracker.ts +411 -0
- package/src/geo/index.ts +10 -0
- package/src/git/commit-helper.test.ts +261 -0
- package/src/git/commit-helper.ts +329 -0
- package/src/git/index.ts +12 -0
- package/src/git/pr-helper.test.ts +284 -0
- package/src/git/pr-helper.ts +307 -0
- package/src/index.ts +66 -0
- package/src/keywords/ai-keyword-engine.ts +1062 -0
- package/src/keywords/ai-summarizer.ts +387 -0
- package/src/keywords/ci-mode.ts +555 -0
- package/src/keywords/engine.ts +359 -0
- package/src/keywords/index.ts +151 -0
- package/src/keywords/llm-judge.ts +357 -0
- package/src/keywords/nlp-analysis.ts +706 -0
- package/src/keywords/prioritizer.ts +295 -0
- package/src/keywords/site-crawler.ts +342 -0
- package/src/keywords/sources/autocomplete.ts +139 -0
- package/src/keywords/sources/competitive-search.ts +450 -0
- package/src/keywords/sources/competitor-analysis.ts +374 -0
- package/src/keywords/sources/dataforseo.ts +206 -0
- package/src/keywords/sources/free-sources.ts +294 -0
- package/src/keywords/sources/gsc.ts +123 -0
- package/src/keywords/topic-grouping.ts +327 -0
- package/src/keywords/types.ts +144 -0
- package/src/keywords/wizard.ts +457 -0
- package/src/loader.ts +40 -0
- package/src/reports/index.ts +7 -0
- package/src/reports/report-generator.test.ts +293 -0
- package/src/reports/report-generator.ts +713 -0
- package/src/scheduler/alerts.test.ts +458 -0
- package/src/scheduler/alerts.ts +328 -0
- package/src/scheduler/index.ts +8 -0
- package/src/scheduler/scheduled-audit.test.ts +377 -0
- package/src/scheduler/scheduled-audit.ts +149 -0
- package/src/test/integration-test.ts +325 -0
- package/src/tools/analyzer.ts +373 -0
- package/src/tools/crawl.ts +293 -0
- package/src/tools/files.ts +301 -0
- package/src/tools/h1-fixer.ts +249 -0
- package/src/tools/index.ts +67 -0
- package/src/tracking/github-action.ts +326 -0
- package/src/tracking/google-analytics.ts +265 -0
- package/src/tracking/index.ts +45 -0
- package/src/tracking/report-generator.ts +386 -0
- package/src/tracking/search-console.ts +335 -0
- package/src/types.ts +134 -0
- package/src/utils/http.ts +302 -0
- package/src/wasm-adapter.ts +297 -0
- package/src/wasm-entry.ts +14 -0
- package/tsconfig.json +17 -0
- package/tsup.wasm.config.ts +26 -0
- package/vitest.config.ts +15 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PR Helper
|
|
3
|
+
*
|
|
4
|
+
* Creates pull requests for SEO fixes using GitHub CLI.
|
|
5
|
+
* Generates formatted PR titles, bodies, and handles branch management.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { exec } from 'child_process';
|
|
9
|
+
import { promisify } from 'util';
|
|
10
|
+
|
|
11
|
+
const execAsync = promisify(exec);
|
|
12
|
+
|
|
13
|
+
export interface SEOFixSummary {
|
|
14
|
+
category: string;
|
|
15
|
+
issues: string[];
|
|
16
|
+
filesCount: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface PRConfig {
|
|
20
|
+
scoreBefore?: number;
|
|
21
|
+
scoreAfter?: number;
|
|
22
|
+
reviewers?: string[];
|
|
23
|
+
assignees?: string[];
|
|
24
|
+
draft?: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface PRDescription {
|
|
28
|
+
title: string;
|
|
29
|
+
body: string;
|
|
30
|
+
labels: string[];
|
|
31
|
+
reviewers?: string[];
|
|
32
|
+
assignees?: string[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface CreatePROptions {
|
|
36
|
+
title: string;
|
|
37
|
+
body: string;
|
|
38
|
+
baseBranch: string;
|
|
39
|
+
headBranch: string;
|
|
40
|
+
createBranch?: boolean;
|
|
41
|
+
labels?: string[];
|
|
42
|
+
reviewers?: string[];
|
|
43
|
+
assignees?: string[];
|
|
44
|
+
draft?: boolean;
|
|
45
|
+
dryRun?: boolean;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface PRResult {
|
|
49
|
+
success: boolean;
|
|
50
|
+
url?: string;
|
|
51
|
+
number?: number;
|
|
52
|
+
error?: string;
|
|
53
|
+
dryRun?: boolean;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface ExecOptions {
|
|
57
|
+
execAsync?: typeof execAsync;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Maps categories to commit types and scopes
|
|
62
|
+
*/
|
|
63
|
+
const CATEGORY_MAPPING: Record<string, { type: string; scope: string; displayName: string }> = {
|
|
64
|
+
'crawlability': { type: 'fix', scope: 'seo', displayName: 'Crawlability' },
|
|
65
|
+
'indexability': { type: 'fix', scope: 'seo', displayName: 'Indexability' },
|
|
66
|
+
'on-page': { type: 'fix', scope: 'meta', displayName: 'On-Page' },
|
|
67
|
+
'content': { type: 'fix', scope: 'content', displayName: 'Content' },
|
|
68
|
+
'links': { type: 'fix', scope: 'links', displayName: 'Links' },
|
|
69
|
+
'images': { type: 'fix', scope: 'images', displayName: 'Images' },
|
|
70
|
+
'structured-data': { type: 'feat', scope: 'schema', displayName: 'Structured Data' },
|
|
71
|
+
'performance': { type: 'perf', scope: 'web', displayName: 'Performance' },
|
|
72
|
+
'security': { type: 'fix', scope: 'security', displayName: 'Security' },
|
|
73
|
+
'mobile': { type: 'fix', scope: 'mobile', displayName: 'Mobile' },
|
|
74
|
+
'international': { type: 'fix', scope: 'i18n', displayName: 'International' },
|
|
75
|
+
'social-meta': { type: 'feat', scope: 'og', displayName: 'Social Meta' },
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Formats a PR title based on the fixes
|
|
80
|
+
*/
|
|
81
|
+
export function formatPRTitle(fixes: SEOFixSummary[]): string {
|
|
82
|
+
if (fixes.length === 0) {
|
|
83
|
+
return 'fix(seo): SEO audit fixes';
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const totalIssues = fixes.reduce((sum, f) => sum + f.issues.length, 0);
|
|
87
|
+
const categories = [...new Set(fixes.map(f => f.category))];
|
|
88
|
+
|
|
89
|
+
// Determine type and scope
|
|
90
|
+
let type = 'fix';
|
|
91
|
+
let scope = 'seo';
|
|
92
|
+
|
|
93
|
+
if (categories.length === 1) {
|
|
94
|
+
const mapping = CATEGORY_MAPPING[categories[0]];
|
|
95
|
+
if (mapping) {
|
|
96
|
+
type = mapping.type;
|
|
97
|
+
scope = mapping.scope;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const issueText = totalIssues === 1 ? '1 issue fixed' : `${totalIssues} issues fixed`;
|
|
102
|
+
return `${type}(${scope}): SEO improvements - ${issueText}`;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Formats the PR body with detailed information
|
|
107
|
+
*/
|
|
108
|
+
export function formatPRBody(
|
|
109
|
+
fixes: SEOFixSummary[],
|
|
110
|
+
options?: { scoreBefore?: number; scoreAfter?: number }
|
|
111
|
+
): string {
|
|
112
|
+
const totalIssues = fixes.reduce((sum, f) => sum + f.issues.length, 0);
|
|
113
|
+
const totalFiles = fixes.reduce((sum, f) => sum + f.filesCount, 0);
|
|
114
|
+
const uniqueFiles = new Set(fixes.flatMap(f => Array(f.filesCount).fill(0))).size || totalFiles;
|
|
115
|
+
|
|
116
|
+
let body = '## Summary\n';
|
|
117
|
+
body += `This PR fixes ${totalIssues} SEO issue${totalIssues === 1 ? '' : 's'} across ${totalFiles} file${totalFiles === 1 ? '' : 's'}.\n\n`;
|
|
118
|
+
|
|
119
|
+
// Score improvement if provided
|
|
120
|
+
if (options?.scoreBefore !== undefined && options?.scoreAfter !== undefined) {
|
|
121
|
+
const improvement = options.scoreAfter - options.scoreBefore;
|
|
122
|
+
const sign = improvement >= 0 ? '+' : '';
|
|
123
|
+
body += `### Score Improvement\n`;
|
|
124
|
+
body += `- Before: ${options.scoreBefore}/100\n`;
|
|
125
|
+
body += `- After: ${options.scoreAfter}/100\n`;
|
|
126
|
+
body += `- Change: **${sign}${improvement}** points\n\n`;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Category breakdown
|
|
130
|
+
if (fixes.length > 0) {
|
|
131
|
+
body += '### Issues Fixed\n\n';
|
|
132
|
+
|
|
133
|
+
for (const fix of fixes) {
|
|
134
|
+
const mapping = CATEGORY_MAPPING[fix.category] || { displayName: fix.category };
|
|
135
|
+
body += `**${mapping.displayName}**\n`;
|
|
136
|
+
for (const issue of fix.issues) {
|
|
137
|
+
body += `- \`${issue}\`\n`;
|
|
138
|
+
}
|
|
139
|
+
body += '\n';
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Test plan
|
|
144
|
+
body += '## Test plan\n';
|
|
145
|
+
body += '- [ ] Run SEO audit to verify fixes\n';
|
|
146
|
+
body += '- [ ] Check pages render correctly\n';
|
|
147
|
+
body += '- [ ] Validate structured data (if applicable)\n';
|
|
148
|
+
body += '- [ ] Test social share previews (if OG tags changed)\n';
|
|
149
|
+
body += '\n';
|
|
150
|
+
|
|
151
|
+
// Footer
|
|
152
|
+
body += '---\n';
|
|
153
|
+
body += '🤖 Generated with [SEO Autopilot](https://github.com/seo-autopilot/seo-autopilot)\n';
|
|
154
|
+
|
|
155
|
+
return body;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Generates complete PR description including title, body, and labels
|
|
160
|
+
*/
|
|
161
|
+
export function generatePRDescription(
|
|
162
|
+
fixes: SEOFixSummary[],
|
|
163
|
+
config?: PRConfig
|
|
164
|
+
): PRDescription {
|
|
165
|
+
const title = formatPRTitle(fixes);
|
|
166
|
+
const body = formatPRBody(fixes, {
|
|
167
|
+
scoreBefore: config?.scoreBefore,
|
|
168
|
+
scoreAfter: config?.scoreAfter,
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
const labels = ['seo', 'automated'];
|
|
172
|
+
|
|
173
|
+
// Add category-specific labels
|
|
174
|
+
const categories = [...new Set(fixes.map(f => f.category))];
|
|
175
|
+
for (const category of categories) {
|
|
176
|
+
const mapping = CATEGORY_MAPPING[category];
|
|
177
|
+
if (mapping && !labels.includes(mapping.scope)) {
|
|
178
|
+
labels.push(mapping.scope);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return {
|
|
183
|
+
title,
|
|
184
|
+
body,
|
|
185
|
+
labels,
|
|
186
|
+
reviewers: config?.reviewers,
|
|
187
|
+
assignees: config?.assignees,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Creates a pull request using GitHub CLI
|
|
193
|
+
*/
|
|
194
|
+
export async function createPullRequest(
|
|
195
|
+
options: CreatePROptions,
|
|
196
|
+
deps?: ExecOptions
|
|
197
|
+
): Promise<PRResult> {
|
|
198
|
+
const run = deps?.execAsync || execAsync;
|
|
199
|
+
|
|
200
|
+
// Dry run mode
|
|
201
|
+
if (options.dryRun) {
|
|
202
|
+
console.log('DRY RUN - Would create PR:');
|
|
203
|
+
console.log(`Title: ${options.title}`);
|
|
204
|
+
console.log(`Base: ${options.baseBranch}`);
|
|
205
|
+
console.log(`Head: ${options.headBranch}`);
|
|
206
|
+
console.log(`Labels: ${options.labels?.join(', ') || 'none'}`);
|
|
207
|
+
console.log('---');
|
|
208
|
+
console.log(options.body);
|
|
209
|
+
console.log('---');
|
|
210
|
+
return { success: true, dryRun: true };
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
try {
|
|
214
|
+
// Create branch if needed
|
|
215
|
+
if (options.createBranch) {
|
|
216
|
+
await run(`git checkout -b ${options.headBranch}`);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// Build gh pr create command
|
|
220
|
+
let cmd = `gh pr create --title "${options.title.replace(/"/g, '\\"')}"`;
|
|
221
|
+
cmd += ` --base "${options.baseBranch}"`;
|
|
222
|
+
cmd += ` --head "${options.headBranch}"`;
|
|
223
|
+
|
|
224
|
+
// Add labels
|
|
225
|
+
if (options.labels && options.labels.length > 0) {
|
|
226
|
+
cmd += ` --label "${options.labels.join(',')}"`;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Add reviewers
|
|
230
|
+
if (options.reviewers && options.reviewers.length > 0) {
|
|
231
|
+
cmd += ` --reviewer "${options.reviewers.join(',')}"`;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Add assignees
|
|
235
|
+
if (options.assignees && options.assignees.length > 0) {
|
|
236
|
+
cmd += ` --assignee "${options.assignees.join(',')}"`;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Draft PR
|
|
240
|
+
if (options.draft) {
|
|
241
|
+
cmd += ' --draft';
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Add body using heredoc
|
|
245
|
+
cmd += ` --body "$(cat <<'EOF'\n${options.body}\nEOF\n)"`;
|
|
246
|
+
|
|
247
|
+
const { stdout } = await run(cmd);
|
|
248
|
+
const url = stdout.trim();
|
|
249
|
+
|
|
250
|
+
// Extract PR number from URL
|
|
251
|
+
const numberMatch = url.match(/\/pull\/(\d+)/);
|
|
252
|
+
const number = numberMatch ? parseInt(numberMatch[1], 10) : undefined;
|
|
253
|
+
|
|
254
|
+
return {
|
|
255
|
+
success: true,
|
|
256
|
+
url,
|
|
257
|
+
number,
|
|
258
|
+
};
|
|
259
|
+
} catch (error) {
|
|
260
|
+
return {
|
|
261
|
+
success: false,
|
|
262
|
+
error: (error as Error).message,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Generates a branch name for SEO fixes
|
|
269
|
+
*/
|
|
270
|
+
export function generateBranchName(prefix = 'seo-fixes'): string {
|
|
271
|
+
const timestamp = new Date().toISOString().slice(0, 10).replace(/-/g, '');
|
|
272
|
+
const random = Math.random().toString(36).slice(2, 6);
|
|
273
|
+
return `${prefix}-${timestamp}-${random}`;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Checks if gh CLI is available and authenticated
|
|
278
|
+
*/
|
|
279
|
+
export async function checkGitHubCLI(deps?: ExecOptions): Promise<{
|
|
280
|
+
available: boolean;
|
|
281
|
+
authenticated: boolean;
|
|
282
|
+
error?: string;
|
|
283
|
+
}> {
|
|
284
|
+
const run = deps?.execAsync || execAsync;
|
|
285
|
+
|
|
286
|
+
try {
|
|
287
|
+
// Check if gh is installed
|
|
288
|
+
await run('gh --version');
|
|
289
|
+
|
|
290
|
+
// Check if authenticated
|
|
291
|
+
await run('gh auth status');
|
|
292
|
+
|
|
293
|
+
return { available: true, authenticated: true };
|
|
294
|
+
} catch (error) {
|
|
295
|
+
const message = (error as Error).message;
|
|
296
|
+
|
|
297
|
+
if (message.includes('command not found') || message.includes('not recognized')) {
|
|
298
|
+
return { available: false, authenticated: false, error: 'GitHub CLI (gh) is not installed' };
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (message.includes('not logged') || message.includes('auth')) {
|
|
302
|
+
return { available: true, authenticated: false, error: 'GitHub CLI is not authenticated' };
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return { available: false, authenticated: false, error: message };
|
|
306
|
+
}
|
|
307
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Agent runtime for SEO Autopilot
|
|
2
|
+
|
|
3
|
+
// Types
|
|
4
|
+
export * from './types.js';
|
|
5
|
+
|
|
6
|
+
// Comprehensive Audit Module (Ahrefs-level checks)
|
|
7
|
+
export * from './audit/index.js';
|
|
8
|
+
|
|
9
|
+
// Keyword Research Module
|
|
10
|
+
export * from './keywords/index.js';
|
|
11
|
+
|
|
12
|
+
// Content Analysis & Optimization Module
|
|
13
|
+
export * from './content/index.js';
|
|
14
|
+
|
|
15
|
+
// Tracking & Monitoring Module
|
|
16
|
+
export * from './tracking/index.js';
|
|
17
|
+
|
|
18
|
+
// Loader
|
|
19
|
+
export { loadAgent, loadAgentByName, interpolatePrompt } from './loader.js';
|
|
20
|
+
|
|
21
|
+
// Executor
|
|
22
|
+
export { executeAgent, runDirectAnalysis } from './executor.js';
|
|
23
|
+
export type { ExecuteOptions, ExecutionResult } from './executor.js';
|
|
24
|
+
|
|
25
|
+
// Fix generator
|
|
26
|
+
export { generateFixes, applyFixes } from './fixer.js';
|
|
27
|
+
export type { FixGeneratorOptions, GeneratedFix } from './fixer.js';
|
|
28
|
+
|
|
29
|
+
// Tools
|
|
30
|
+
export { tools } from './tools/index.js';
|
|
31
|
+
export {
|
|
32
|
+
crawlUrl,
|
|
33
|
+
extractMeta,
|
|
34
|
+
analyzeHeadings,
|
|
35
|
+
extractImages,
|
|
36
|
+
extractLinks,
|
|
37
|
+
extractSchema,
|
|
38
|
+
checkRobots,
|
|
39
|
+
checkSitemap,
|
|
40
|
+
readFile,
|
|
41
|
+
writeFile,
|
|
42
|
+
listFiles,
|
|
43
|
+
detectFramework,
|
|
44
|
+
findHtmlEntry,
|
|
45
|
+
findPageFiles,
|
|
46
|
+
analyzeUrl,
|
|
47
|
+
} from './tools/index.js';
|
|
48
|
+
|
|
49
|
+
// Git integration (conventional commits, co-authoring)
|
|
50
|
+
export * from './git/index.js';
|
|
51
|
+
|
|
52
|
+
// Scheduler (scheduled audits, alerts)
|
|
53
|
+
export * from './scheduler/index.js';
|
|
54
|
+
|
|
55
|
+
// Reports (HTML/PDF generation, white-label)
|
|
56
|
+
export * from './reports/index.js';
|
|
57
|
+
|
|
58
|
+
// GEO (Generative Engine Optimization) tracking
|
|
59
|
+
export * from './geo/index.js';
|
|
60
|
+
|
|
61
|
+
// Framework Detection & SEO Recipes
|
|
62
|
+
// Note: Export as namespace to avoid conflict with tools/detectFramework
|
|
63
|
+
export * as frameworks from './frameworks/index.js';
|
|
64
|
+
|
|
65
|
+
// WASM Adapter (sync audit for embedded execution)
|
|
66
|
+
export { runSyncAudit } from './wasm-adapter.js';
|