#!/usr/bin/env node
/**
* Discord Documentation Sync Tool (Final Version)
* Posts clean summaries with links to GitHub (single source of truth)
*
* Usage: node scripts/discord-sync-final.js <webhook-url>
*/
const https = require('https');
// Clean messages that link to GitHub as source of truth
const MESSAGES = [
{
title: '๐ Welcome to FAF',
content: `**FAF (Foundational AI-context Format)** - IANA-registered AI context standard
๐งก **IANA Format:** \`application/vnd.faf+yaml\`
๐ฆ **MCP Server:** 6.1k downloads (1,231/week)
โก **CLI Tool:** 6.2k downloads (235/week)
**Two packages, one ecosystem:**
โข \`claude-faf-mcp\` - For Claude Desktop (MCP integration)
โข \`faf-cli\` - For terminal workflows
**โญ๏ธ Help us grow:** <https://github.com/Wolfe-Jam/claude-faf-mcp>
Every star helps more devs discover FAF!
โโโโโโโโโโโโโโโโโโโโโ`,
order: 1
},
{
title: '๐ Quick Start',
content: `**Get started in 2 minutes:**
\`\`\`bash
npm install -g claude-faf-mcp
\`\`\`
**Add to Claude Desktop config:**
\`\`\`json
{
"mcpServers": {
"faf": {
"command": "npx",
"args": ["claude-faf-mcp"]
}
}
}
\`\`\`
**Restart Claude Desktop** โ Test with \`faf_score()\`
๐ **Full guide:** <https://github.com/Wolfe-Jam/claude-faf-mcp/blob/main/docs/QUICK_START.md>`,
order: 2
},
{
title: '๐ PODIUM Scoring',
content: `**Gamifying Software Excellence**
\`\`\`
๐ฅ 85% = BRONZE PODIUM
๐ฅ 95% = SILVER PODIUM
๐ฅ 99% = GOLD PODIUM
๐ 105% = TROPHY
\`\`\`
When you see BRONZE (85%), you can't help it...
**YOU'RE GONNA WANNA WIN.**
**Score breakdown:**
โข 40 points: .faf file (project context)
โข 30 points: CLAUDE.md (AI instructions)
โข 15 points: README.md (documentation)
โข 14 points: Project file (package.json, etc)
๐ **Full system:** <https://github.com/Wolfe-Jam/claude-faf-mcp/blob/main/docs/PODIUM-SYSTEM.md>`,
order: 3
},
{
title: 'โ FAQ',
content: `**Common Questions:**
**Do I need the CLI installed?**
No. v3.0.5 is 100% standalone (50/50 tools operational).
**What's MCP vs CLI?**
MCP = Claude Desktop integration
CLI = Terminal standalone tool
**How are scores calculated?**
.faf (40) + CLAUDE.md (30) + README (15) + project file (14) = 99%
Final 1% = perfect collaboration (only Claude can grant)
**Is my code safe?**
Yes. Everything runs locally. No external data transmission.
๐ **Full FAQ:** <https://github.com/Wolfe-Jam/claude-faf-mcp/blob/main/docs/FAQ.md>`,
order: 4
},
{
title: '๐ Documentation',
content: `**All docs available on GitHub:**
โข **Quick Start:** <https://github.com/Wolfe-Jam/claude-faf-mcp/blob/main/docs/QUICK_START.md>
โข **User Guide:** <https://github.com/Wolfe-Jam/claude-faf-mcp/blob/main/docs/USER_GUIDE.md>
โข **FAQ:** <https://github.com/Wolfe-Jam/claude-faf-mcp/blob/main/docs/FAQ.md>
โข **PODIUM System:** <https://github.com/Wolfe-Jam/claude-faf-mcp/blob/main/docs/PODIUM-SYSTEM.md>
โข **Main README:** <https://github.com/Wolfe-Jam/claude-faf-mcp>
**npm packages:**
โข MCP: <https://www.npmjs.com/package/claude-faf-mcp>
โข CLI: <https://www.npmjs.com/package/faf-cli>
**Website:** <https://faf.one>`,
order: 5
},
{
title: 'โญ๏ธ Support FAF',
content: `**Help FAF grow:**
โญ๏ธ **Star on GitHub:** <https://github.com/Wolfe-Jam/claude-faf-mcp>
Every star helps developers discover this tool!
๐ฌ **Join the community:**
Already here? Introduce yourself in #introductions!
๐ฃ **Share FAF:**
Know someone building with Claude? Share the npm link:
<https://www.npmjs.com/package/claude-faf-mcp>
๐ **Report issues:** <https://github.com/Wolfe-Jam/claude-faf-mcp/issues>
โโโโโโโโโโโโโโโโโโโโโ
Thanks for being part of the FAF community! ๐งก`,
order: 6
}
];
function postToDiscord(webhookUrl, content) {
return new Promise((resolve, reject) => {
const url = new URL(webhookUrl);
const payload = JSON.stringify({
content: content.substring(0, 2000)
});
const options = {
hostname: url.hostname,
path: url.pathname + url.search,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(payload)
}
};
const req = https.request(options, (res) => {
let body = '';
res.on('data', chunk => body += chunk);
res.on('end', () => {
if (res.statusCode === 204 || res.statusCode === 200) {
resolve();
} else {
reject(new Error(`Discord returned status ${res.statusCode}: ${body}`));
}
});
});
req.on('error', reject);
req.write(payload);
req.end();
});
}
async function syncDocs(webhookUrl) {
console.log('๐ Starting Discord documentation sync (final)...\n');
const sortedMessages = MESSAGES.sort((a, b) => a.order - b.order);
for (const msg of sortedMessages) {
const message = `**${msg.title}**
${msg.content}`;
try {
await postToDiscord(webhookUrl, message);
console.log(`โ
Posted ${msg.title}`);
// Rate limit: Discord allows 5 requests per 2 seconds
await new Promise(resolve => setTimeout(resolve, 1000));
} catch (error) {
console.error(`โ Failed to post ${msg.title}:`, error.message);
}
}
console.log('\nโจ Sync complete!');
}
// Main execution
if (require.main === module) {
const webhookUrl = process.argv[2];
if (!webhookUrl) {
console.error('Usage: node scripts/discord-sync-final.js <webhook-url>');
console.error('\nGet your webhook URL from Discord:');
console.error('1. Server Settings > Integrations > Webhooks');
console.error('2. Create New Webhook or use existing');
console.error('3. Copy Webhook URL');
process.exit(1);
}
syncDocs(webhookUrl).catch((error) => {
console.error('Fatal error:', error);
process.exit(1);
});
}
module.exports = { syncDocs };