#!/usr/bin/env node /** * Yonexus Plugin Installer v0.2.0 * * Usage: * node install.mjs --install * node install.mjs --install --openclaw-profile-path /path/to/.openclaw * node install.mjs --uninstall * node install.mjs --uninstall --openclaw-profile-path /path/to/.openclaw */ import { execSync } from 'child_process'; import { existsSync, mkdirSync, copyFileSync, readdirSync, rmSync } from 'fs'; import { dirname, join, resolve } from 'path'; import { fileURLToPath } from 'url'; import { homedir } from 'os'; const __filename = fileURLToPath(import.meta.url); const __dirname = resolve(dirname(__filename)); const PLUGIN_NAME = 'yonexus'; const SRC_DIST_DIR = join(__dirname, 'dist', PLUGIN_NAME); // ── Parse arguments ───────────────────────────────────────────────────── const args = process.argv.slice(2); const isInstall = args.includes('--install'); const isUninstall = args.includes('--uninstall'); const profileIdx = args.indexOf('--openclaw-profile-path'); let openclawProfilePath = null; if (profileIdx !== -1 && args[profileIdx + 1]) { openclawProfilePath = resolve(args[profileIdx + 1]); } function resolveOpenclawPath() { if (openclawProfilePath) return openclawProfilePath; if (process.env.OPENCLAW_PATH) return resolve(process.env.OPENCLAW_PATH); return join(homedir(), '.openclaw'); } // ── Colors ────────────────────────────────────────────────────────────── const c = { reset: '\x1b[0m', red: '\x1b[31m', green: '\x1b[32m', yellow: '\x1b[33m', blue: '\x1b[34m', cyan: '\x1b[36m', }; function log(msg, color = 'reset') { console.log(`${c[color]}${msg}${c.reset}`); } function logOk(msg) { log(` ✓ ${msg}`, 'green'); } function logWarn(msg) { log(` ⚠ ${msg}`, 'yellow'); } function logErr(msg) { log(` ✗ ${msg}`, 'red'); } // ── Helpers ───────────────────────────────────────────────────────────── function copyDir(src, dest) { mkdirSync(dest, { recursive: true }); for (const entry of readdirSync(src, { withFileTypes: true })) { const s = join(src, entry.name); const d = join(dest, entry.name); if (entry.name === 'node_modules') continue; entry.isDirectory() ? copyDir(s, d) : copyFileSync(s, d); } } // ── Install ───────────────────────────────────────────────────────────── function install() { console.log(''); log('╔══════════════════════════════════════════════╗', 'cyan'); log('║ Yonexus Plugin Installer v0.2.0 ║', 'cyan'); log('╚══════════════════════════════════════════════╝', 'cyan'); console.log(''); // 1. Build log('[1/3] Building...', 'cyan'); execSync('npm install', { cwd: __dirname, stdio: 'inherit' }); execSync('npm run build', { cwd: __dirname, stdio: 'inherit' }); if (!existsSync(SRC_DIST_DIR)) { logErr(`Build output not found at ${SRC_DIST_DIR}`); process.exit(1); } logOk('Build complete'); // 2. Copy to plugins dir log('[2/3] Installing...', 'cyan'); const openclawPath = resolveOpenclawPath(); const destDir = join(openclawPath, 'plugins', PLUGIN_NAME); log(` OpenClaw path: ${openclawPath}`, 'blue'); if (existsSync(destDir)) rmSync(destDir, { recursive: true, force: true }); copyDir(SRC_DIST_DIR, destDir); logOk(`Plugin files → ${destDir}`); // 3. Summary log('[3/3] Done!', 'cyan'); console.log(''); log('✓ Yonexus installed successfully!', 'green'); console.log(''); log('Next steps:', 'blue'); log(' openclaw gateway restart', 'cyan'); console.log(''); } // ── Uninstall ─────────────────────────────────────────────────────────── function uninstall() { console.log(''); log('Uninstalling Yonexus...', 'cyan'); const openclawPath = resolveOpenclawPath(); const destDir = join(openclawPath, 'plugins', PLUGIN_NAME); if (existsSync(destDir)) { rmSync(destDir, { recursive: true, force: true }); logOk(`Removed ${destDir}`); } else { logWarn(`${destDir} not found, nothing to remove`); } console.log(''); log('✓ Yonexus uninstalled.', 'green'); log('\nNext: openclaw gateway restart', 'yellow'); console.log(''); } // ── Main ──────────────────────────────────────────────────────────────── if (!isInstall && !isUninstall) { console.log(''); log('Yonexus Plugin Installer', 'cyan'); console.log(''); log('Usage:', 'blue'); log(' node install.mjs --install Install plugin', 'reset'); log(' node install.mjs --install --openclaw-profile-path Install to custom path', 'reset'); log(' node install.mjs --uninstall Uninstall plugin', 'reset'); log(' node install.mjs --uninstall --openclaw-profile-path Uninstall from custom path', 'reset'); console.log(''); process.exit(1); } if (isInstall) install(); if (isUninstall) uninstall();