wordlift-cli
Version:
WordLift CLI - A customized CLI for WordLift SEO workflows with agent memory system and smart project directory detection
151 lines (124 loc) ⢠4.86 kB
JavaScript
/**
* WordLift Content Linking Phase
* Implements Phase 9 from the content playbook
* Adds strategic internal links to generated content
*/
const fs = require('fs');
const path = require('path');
class ContentLinker {
constructor() {
this.serviceUrls = {
'Translation OS': 'https://translated.com/translation-os',
'Custom Localization Solutions': 'https://translated.com/custom-localization',
'Language AI': 'https://translated.com/language-ai',
'Professional Translation Agency': 'https://translated.com/professional-translation',
'TranslationOS': 'https://translated.com/translation-os',
'Lara': 'https://translated.com/lara'
};
}
/**
* Process content and add mandatory service links
*/
addServiceLinks(content) {
console.log('š Adding mandatory service links...');
let linkedContent = content;
let linksAdded = 0;
// Add links for each service mention
for (const [serviceName, url] of Object.entries(this.serviceUrls)) {
const regex = new RegExp(`\\*\\*${serviceName}\\*\\*(?!.*<a)`, 'g');
const replacement = `[**${serviceName}**](${url})`;
const matches = linkedContent.match(regex);
if (matches) {
linkedContent = linkedContent.replace(regex, replacement);
linksAdded += matches.length;
console.log(` ā
Linked ${matches.length} mention(s) of "${serviceName}"`);
}
}
if (linksAdded > 0) {
console.log(`šÆ Added ${linksAdded} service links total`);
} else {
console.log('ā¹ļø No service mentions found to link');
}
return linkedContent;
}
/**
* Suggest strategic linking opportunities
*/
suggestStrategicLinks(content) {
console.log('\nš” Strategic linking opportunities:');
const opportunities = [
'semantic SEO',
'knowledge graph',
'entity linking',
'structured data',
'AI translation',
'machine translation',
'localization',
'multilingual SEO'
];
const found = [];
opportunities.forEach(term => {
const regex = new RegExp(term, 'gi');
if (content.match(regex)) {
found.push(term);
}
});
if (found.length > 0) {
console.log(' š Found these linkable concepts:');
found.forEach(term => console.log(` - ${term}`));
console.log('\n š Use WordLift Agent to search for relevant blog posts on:');
console.log(' ⢠blog.laratranslate.com');
console.log(' ⢠imminent.translated.com');
console.log(' ⢠blog.modernmt.com');
} else {
console.log(' ā¹ļø No strategic linking opportunities identified');
}
return found;
}
/**
* Process a markdown file and add links
*/
processFile(filePath) {
console.log(`\nš Processing: ${path.basename(filePath)}`);
if (!fs.existsSync(filePath)) {
console.error(`ā File not found: ${filePath}`);
return false;
}
const content = fs.readFileSync(filePath, 'utf8');
const linkedContent = this.addServiceLinks(content);
this.suggestStrategicLinks(content);
// Create backup
const backupPath = filePath.replace('.md', '_backup.md');
fs.writeFileSync(backupPath, content);
console.log(`š¾ Backup saved: ${path.basename(backupPath)}`);
// Save linked version
fs.writeFileSync(filePath, linkedContent);
console.log(`ā
Updated: ${path.basename(filePath)}`);
return true;
}
}
// CLI usage
if (require.main === module) {
const args = process.argv.slice(2);
if (args.length === 0) {
console.log('Usage: node add-links-phase.js <markdown-file>');
console.log('Example: node add-links-phase.js output/article.md');
process.exit(1);
}
const filePath = path.resolve(args[0]);
const linker = new ContentLinker();
console.log('š WordLift Content Linking Phase');
console.log('==================================');
if (linker.processFile(filePath)) {
console.log('\nā
Linking phase complete!');
console.log('\nš Next steps:');
console.log('1. Review the added service links');
console.log('2. Use WordLift Agent to add strategic content links');
console.log('3. Verify all links work correctly');
} else {
console.log('\nā Linking phase failed');
process.exit(1);
}
}
module.exports = ContentLinker;