1const path = require('path');
2const fs = require('fs');
3const pool = require('./db');
4const PLUGIN_SRC = path.resolve(__dirname, '../../agent/plugins');
5const PLUGIN_DEST = path.resolve(__dirname, '../../agent/plugins');
6// pluginBuilder.js - Redis worker for plugin build/check jobs
8const { execSync } = require('child_process');
9const Redis = require('ioredis');
10const redisConfig = require('../config/redis');
11const redis = new Redis(redisConfig);
14const PLUGIN_HASHES_PATH = path.resolve(__dirname, 'pluginHashes.json');
18function getPluginHashes() {
20 return JSON.parse(fs.readFileSync(PLUGIN_HASHES_PATH, 'utf8'));
29function savePluginHashes(hashes) {
30 fs.writeFileSync(PLUGIN_HASHES_PATH, JSON.stringify(hashes, null, 2));
37function hashFile(filePath) {
38 if (!fs.existsSync(filePath)) return null;
39 const content = fs.readFileSync(filePath);
40 return require('crypto').createHash('sha256').update(content).digest('hex');
46function buildAllWindowsPlugins() {
48 const hashes = getPluginHashes();
49 const srcFiles = fs.readdirSync(PLUGIN_SRC).filter(f => f.endsWith('.js'));
52 for (const file of srcFiles) {
53 const pluginName = file.replace('.js', '');
54 const srcPath = path.join(PLUGIN_SRC, file);
55 const destPath = path.join(PLUGIN_DEST, 'windows', pluginName + '.exe');
56 const newHash = hashFile(srcPath);
57 if (hashes[file] !== newHash || !fs.existsSync(destPath)) {
59 execSync(`npx pkg ${srcPath} --output ${destPath} --targets node18-win-x64`);
60 console.log(`[PLUGIN BUILDER] Built ${pluginName}.exe for Windows.`);
61 hashes[file] = newHash;
64 console.error(`[PLUGIN BUILDER] Failed to build ${pluginName}.exe:`, err.message);
67 console.log(`[PLUGIN BUILDER] No change for ${pluginName}.js, skipping build.`);
69 // Seed plugin info in database
70 const version = '1.0.0';
71 const description = `Auto-seeded plugin for ${pluginName}`;
73 `INSERT INTO plugins (name, description, version, type) VALUES ($1, $2, $3, $4)
74 ON CONFLICT (name) DO UPDATE SET description = EXCLUDED.description, version = EXCLUDED.version, type = EXCLUDED.type`,
75 [`${pluginName}.exe`, description, version, 'windows']
77 console.log(`[PLUGIN BUILDER] Seeded DB: ${pluginName}.exe`);
79 console.error(`[PLUGIN BUILDER] DB seed error for ${pluginName}.exe:`, err.message);
82 // Build agent binary as plugin (use EverydayTechAgent-win-x64.exe)
83 const agentSrc = path.resolve(__dirname, '../../agent/agent.js');
84 const agentDest = path.resolve(__dirname, '../../agent/plugins/agent/EverydayTechAgent-win-x64.exe');
85 const agentHash = hashFile(agentSrc);
86 if (hashes['agent.js'] !== agentHash || !fs.existsSync(agentDest)) {
88 execSync(`npx pkg ${agentSrc} --output ${agentDest} --targets node18-win-x64`);
89 console.log(`[PLUGIN BUILDER] Built EverydayTechAgent-win-x64.exe for Windows.`);
90 hashes['EverydayTechAgent-win-x64.exe'] = agentHash;
93 console.error(`[PLUGIN BUILDER] Failed to build EverydayTechAgent-win-x64.exe:`, err.message);
96 console.log(`[PLUGIN BUILDER] No change for agent.js, skipping agent build.`);
98 // Seed agent plugin info in database
100 `INSERT INTO plugins (name, description, version, type) VALUES ($1, $2, $3, $4)
101 ON CONFLICT (name) DO UPDATE SET description = EXCLUDED.description, version = EXCLUDED.version, type = EXCLUDED.type`,
102 ['EverydayTechAgent-win-x64.exe', 'Auto-seeded agent plugin', '1.0.0', 'agent']
104 console.log('[PLUGIN BUILDER] Seeded DB: EverydayTechAgent-win-x64.exe');
106 console.error('[PLUGIN BUILDER] DB seed error for EverydayTechAgent-win-x64.exe:', err.message);
108 if (changed) savePluginHashes(hashes);
111redis.subscribe('plugin-build-jobs', (err, count) => {
112 if (err) console.error('[PLUGIN BUILDER] Redis subscribe error:', err);
113 else console.log(`[PLUGIN BUILDER] Subscribed to plugin-build-jobs (${count})`);
116redis.on('message', (channel, message) => {
117 if (channel !== 'plugin-build-jobs') return;
119 const job = JSON.parse(message);
121 console.log(`[PLUGIN BUILDER] Received job for OS: ${os}`);
122 if (os === 'windows') {
123 buildAllWindowsPlugins();
125 // Add similar logic for other OS if needed
127 console.error('[PLUGIN BUILDER] Job error:', err.message);
131// To run: node backend/services/pluginBuilder.js