refactor: restructure project layout and add install.mjs
- Move src/ → plugin/ with subdirectories: - plugin/core/ (business logic, models, store, permissions, utils, memory) - plugin/tools/ (query, resources) - plugin/commands/ (placeholder for slash commands) - plugin/hooks/ (placeholder for lifecycle hooks) - plugin/index.ts (wiring layer only, no business logic) - Add install.mjs with --install, --uninstall, --openclaw-profile-path - Add skills/ and docs/ root directories - Move planning docs (PLAN.md, FEAT.md, AGENT_TASKS.md) to docs/ - Remove old scripts/install.sh - Update tsconfig rootDir: src → plugin - Update README.md and README.zh.md with new layout - Bump version to 0.2.0 - All tests pass
This commit is contained in:
145
install.mjs
Normal file
145
install.mjs
Normal file
@@ -0,0 +1,145 @@
|
||||
#!/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 <path> Install to custom path', 'reset');
|
||||
log(' node install.mjs --uninstall Uninstall plugin', 'reset');
|
||||
log(' node install.mjs --uninstall --openclaw-profile-path <path> Uninstall from custom path', 'reset');
|
||||
console.log('');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (isInstall) install();
|
||||
if (isUninstall) uninstall();
|
||||
Reference in New Issue
Block a user