#!/usr/bin/env node /** * Qwen Code Startup Hook for QwenClaw * * This script is automatically executed when Qwen Code starts. * It ensures QwenClaw daemon is running and sets it as the default agent. */ import { spawn } from "child_process"; import { join } from "path"; import { existsSync, readFileSync, writeFile } from "fs"; const QWENCLAW_DIR = join(process.env.HOME || process.env.USERPROFILE || "", "qwenclaw"); const QWEN_DIR = join(process.env.HOME || process.env.USERPROFILE || "", ".qwen"); const QWEN_SETTINGS_FILE = join(QWEN_DIR, "settings.json"); const QWENCLAW_PID_FILE = join(QWEN_DIR, "qwenclaw", "daemon.pid"); const COLORS = { cyan: "\x1b[36m", green: "\x1b[32m", yellow: "\x1b[33m", red: "\x1b[31m", reset: "\x1b[0m", }; function log(message, color = "reset") { console.log(`${COLORS[color]}${message}${COLORS.reset}`); } /** * Check if QwenClaw daemon is running */ function isQwenClawRunning() { if (!existsSync(QWENCLAW_PID_FILE)) { return false; } try { const pid = parseInt(readFileSync(QWENCLAW_PID_FILE, "utf-8").trim(), 10); if (isNaN(pid)) { return false; } // Check if process exists process.kill(pid, 0); return true; } catch { return false; } } /** * Start QwenClaw daemon in background */ function startQwenClaw() { log("\n🐾 QwenClaw: Starting daemon...", "cyan"); const qwenclawProcess = spawn("bun", ["run", "start", "--web"], { cwd: QWENCLAW_DIR, detached: true, stdio: "ignore", windowsHide: true, }); qwenclawProcess.unref(); log("āœ… QwenClaw daemon started in background", "green"); log(" Web Dashboard: http://127.0.0.1:4632", "cyan"); } /** * Update Qwen Code settings to enable QwenClaw as default */ function updateQwenSettings() { log("\nāš™ļø QwenClaw: Updating Qwen Code settings...", "cyan"); let settings = {}; if (existsSync(QWEN_SETTINGS_FILE)) { try { const content = readFileSync(QWEN_SETTINGS_FILE, "utf-8"); settings = JSON.parse(content); } catch (err) { log(`āš ļø Warning: Could not parse settings.json: ${err.message}`, "yellow"); } } // Enable QwenClaw skills if (!settings.skills) { settings.skills = {}; } if (!settings.skills.enabled) { settings.skills.enabled = []; } const requiredSkills = [ "qwenclaw-integration", "gui-automation", "qwenbot-integration", ]; for (const skill of requiredSkills) { if (!settings.skills.enabled.includes(skill)) { settings.skills.enabled.push(skill); log(` + Enabled skill: ${skill}`, "green"); } } // Set QwenClaw as default skill settings.skills.default = "qwenclaw-integration"; // Set QwenClaw as default agent if (!settings.agents) { settings.agents = {}; } settings.agents.default = "qwenclaw"; if (!settings.agents.qwenclaw) { settings.agents.qwenclaw = { name: "QwenClaw", description: "Persistent AI assistant daemon with automation capabilities", autoStart: true, skills: ["qwenclaw-integration", "gui-automation", "qwenbot-integration"], }; log(" + Created default agent: qwenclaw", "green"); } else { settings.agents.qwenclaw.autoStart = true; log(" āœ“ Updated agent: qwenclaw", "green"); } // Add QwenClaw MCP server if (!settings.mcpServers) { settings.mcpServers = {}; } if (!settings.mcpServers.qwenclaw) { settings.mcpServers.qwenclaw = { command: "bun", args: ["run", "start", "--web"], cwd: QWENCLAW_DIR, env: { QWENCLAW_AUTO_START: "true", }, }; log(" + Added MCP server: qwenclaw", "green"); } // Save settings try { writeFile(QWEN_SETTINGS_FILE, JSON.stringify(settings, null, 2) + "\n", "utf-8"); log("āœ… Qwen Code settings updated", "green"); } catch (err) { log(`āŒ Error saving settings: ${err.message}`, "red"); } } /** * Main startup hook */ async function main() { log("\n" + "═".repeat(50), "cyan"); log(" 🐾 QWENCLAW - Qwen Code Startup Hook", "cyan"); log("═".repeat(50), "cyan"); // Check if QwenClaw is installed if (!existsSync(QWENCLAW_DIR)) { log("\nāŒ QwenClaw not found at: " + QWENCLAW_DIR, "red"); log(" Please install QwenClaw first:", "yellow"); log(" git clone https://github.rommark.dev/admin/QwenClaw-with-Auth.git", "cyan"); return; } // Check if daemon is running if (isQwenClawRunning()) { log("\nāœ… QwenClaw daemon is already running", "green"); } else { startQwenClaw(); // Wait for daemon to start await new Promise((resolve) => setTimeout(resolve, 3000)); } // Update Qwen Code settings updateQwenSettings(); // Show status log("\n" + "═".repeat(50), "cyan"); log(" āœ… QwenClaw is ready!", "green"); log("═".repeat(50), "cyan"); log("\nšŸ“Œ Quick Commands:", "yellow"); log(" /qwenclaw start - Start daemon", "cyan"); log(" /qwenclaw status - Check status", "cyan"); log(" /qwenclaw send - Send message", "cyan"); log(" /qwenclaw skills - List skills", "cyan"); log("\n🌐 Web Dashboard: http://127.0.0.1:4632", "cyan"); log("\n"); } // Run startup hook main().catch((err) => { log(`\nāŒ Startup hook error: ${err.message}`, "red"); });