#!/usr/bin/env node /** * QwenClaw - Set as Default Always-ON Agent for Qwen Code CLI * * This script configures Qwen Code to ALWAYS use QwenClaw as the default agent. * * Usage: bun run set-default-agent.js */ import { join } from "path"; import { existsSync, readFileSync, writeFile, mkdirSync } from "fs"; const QWEN_DIR = join(process.env.HOME || process.env.USERPROFILE || "", ".qwen"); const QWEN_SETTINGS_FILE = join(QWEN_DIR, "settings.json"); const QWEN_AGENT_FILE = join(QWEN_DIR, "agent.json"); const QWENCLAW_DIR = process.env.QWENCLAW_DIR || join(process.env.HOME || process.env.USERPROFILE || "", "qwenclaw"); const COLORS = { cyan: "\x1b[36m", green: "\x1b[32m", yellow: "\x1b[33m", red: "\x1b[31m", magenta: "\x1b[35m", bold: "\x1b[1m", reset: "\x1b[0m", }; function log(message, color = "reset") { console.log(`${COLORS[color]}${message}${COLORS.reset}`); } function showBanner() { log("\n" + "═".repeat(70), "cyan"); log(" 🐾 QWENCLAW - SET AS DEFAULT ALWAYS-ON AGENT", "cyan"); log("═".repeat(70), "cyan"); } /** * Ensure Qwen directory exists */ function ensureQwenDir() { log("\nšŸ“ Checking Qwen directory...", "cyan"); if (!existsSync(QWEN_DIR)) { mkdirSync(QWEN_DIR, { recursive: true }); log("āœ… Created Qwen directory: " + QWEN_DIR, "green"); } else { log("āœ… Qwen directory exists", "green"); } } /** * Create agent.json with QwenClaw as enforced default */ function createAgentConfig() { log("\nāš™ļø Creating agent configuration...", "cyan"); const agentConfig = { version: "1.0.0", agent: { default: "qwenclaw", enforce: true, agents: { qwenclaw: { name: "QwenClaw", description: "Persistent AI assistant daemon - ALWAYS ON", autoStart: true, alwaysOn: true, priority: 1, skills: [ "qwenclaw-integration", "gui-automation", "qwenbot-integration", ], config: { daemon: { autoStart: true, webDashboard: true, port: 4632, checkInterval: 30000, }, }, }, }, }, skills: { enforce: true, default: "qwenclaw-integration", enabled: [ "qwenclaw-integration", "gui-automation", "qwenbot-integration", ], disabled: [], }, mcpServers: { qwenclaw: { enabled: true, autoStart: true, command: "bun", args: ["run", "start", "--web"], cwd: QWENCLAW_DIR, env: { QWENCLAW_AUTO_START: "true", QWENCLAW_ALWAYS_ON: "true", }, }, }, context: { loadMemoryFromIncludeDirectories: true, persistentSessions: true, shareContextWithDaemon: true, }, tools: { approvalMode: "yolo", enableAll: true, }, ui: { showAgentStatus: true, showDaemonStatus: true, }, }; try { writeFile(QWEN_AGENT_FILE, JSON.stringify(agentConfig, null, 2) + "\n", "utf-8"); log("āœ… Agent configuration created: " + QWEN_AGENT_FILE, "green"); log(" • Default agent: qwenclaw (ENFORCED)", "magenta"); log(" • Always ON: true", "magenta"); log(" • Auto-start: enabled", "magenta"); } catch (err) { log(`āŒ Error creating agent config: ${err.message}`, "red"); } } /** * Update main settings.json */ function updateSettings() { log("\nāš™ļø 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); log("āœ… Loaded existing settings", "green"); } catch (err) { log(`āš ļø Warning: Could not parse settings.json`, "yellow"); } } // Enforce QwenClaw as default agent if (!settings.agents) { settings.agents = {}; } settings.agents.default = "qwenclaw"; settings.agents.enforce = true; settings.agents.qwenclaw = { name: "QwenClaw", description: "Persistent AI assistant daemon - ALWAYS ON", autoStart: true, alwaysOn: true, priority: 1, skills: ["qwenclaw-integration", "gui-automation", "qwenbot-integration"], }; log(" āœ“ Set default agent: qwenclaw (ENFORCED)", "green"); // Enforce skills if (!settings.skills) { settings.skills = {}; } settings.skills.enforce = true; settings.skills.default = "qwenclaw-integration"; 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"); } } // Configure MCP servers if (!settings.mcpServers) { settings.mcpServers = {}; } settings.mcpServers.qwenclaw = { enabled: true, autoStart: true, command: "bun", args: ["run", "start", "--web"], cwd: QWENCLAW_DIR, env: { QWENCLAW_AUTO_START: "true", QWENCLAW_ALWAYS_ON: "true", }, }; log(" āœ“ MCP server: qwenclaw (auto-start)", "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"); } } /** * Create startup script */ function createStartupScript() { log("\nšŸ“ Creating startup script...", "cyan"); const startupScript = join(QWEN_DIR, "startup.js"); const scriptContent = `#!/usr/bin/env node /** * QwenClaw Auto-Start Script * Ensures QwenClaw daemon is running when Qwen Code starts */ import { spawn } from "child_process"; import { join } from "path"; import { existsSync, readFileSync } from "fs"; const QWENCLAW_DIR = process.env.QWENCLAW_DIR || join(process.env.HOME || process.env.USERPROFILE || "", "qwenclaw"); const PID_FILE = join(process.env.HOME || process.env.USERPROFILE || "", ".qwen", "qwenclaw", "daemon.pid"); function isRunning() { if (!existsSync(PID_FILE)) return false; try { const pid = parseInt(readFileSync(PID_FILE, "utf-8").trim(), 10); if (isNaN(pid)) return false; process.kill(pid, 0); return true; } catch { return false; } } if (!isRunning()) { console.log("[QwenClaw] Starting daemon..."); const proc = spawn("bun", ["run", "start", "--web"], { cwd: QWENCLAW_DIR, detached: true, stdio: "ignore", windowsHide: true, }); proc.unref(); } else { console.log("[QwenClaw] Daemon already running"); } `; try { writeFile(startupScript, scriptContent, "utf-8"); log("āœ… Startup script created", "green"); } catch (err) { log(`āš ļø Could not create startup script: ${err.message}`, "yellow"); } } /** * Show completion summary */ function showSummary() { log("\n" + "═".repeat(70), "cyan"); log(" āœ… QWENCLAW IS NOW YOUR DEFAULT ALWAYS-ON AGENT!", "green"); log("═".repeat(70), "cyan"); log("\nšŸ“Œ Configuration Summary:", "yellow"); log(" • Default Agent: qwenclaw (ENFORCED)", "magenta"); log(" • Always ON: true", "magenta"); log(" • Auto-Start: enabled", "magenta"); log(" • Skills Enabled: 3", "magenta"); log(" • MCP Server: configured", "magenta"); log("\nšŸŽÆ What This Means:", "yellow"); log(" āœ“ Qwen Code will ALWAYS use QwenClaw by default", "green"); log(" āœ“ QwenClaw daemon auto-starts with Qwen Code", "green"); log(" āœ“ All QwenClaw skills are automatically enabled", "green"); log(" āœ“ Persistent sessions across restarts", "green"); log(" āœ“ Web dashboard auto-enabled", "green"); log("\nšŸš€ Next Steps:", "yellow"); log(" 1. Restart Qwen Code", "cyan"); log(" 2. QwenClaw will automatically start", "cyan"); log(" 3. All interactions will use QwenClaw by default", "cyan"); log("\nšŸ“š Quick Commands:", "yellow"); log(" qwenclaw start - Start daemon manually", "cyan"); log(" qwenclaw status - Check daemon status", "cyan"); log(" qwenclaw send - Send message to daemon", "cyan"); log(" qwenclaw skills - List all skills", "cyan"); log(" qwenclaw help - Show help", "cyan"); log("\n🌐 Web Dashboard: http://127.0.0.1:4632", "cyan"); log("\nšŸ“– Config Files:", "yellow"); log(" • Agent: " + QWEN_AGENT_FILE, "cyan"); log(" • Settings: " + QWEN_SETTINGS_FILE, "cyan"); log("\n"); } /** * Main function */ async function main() { showBanner(); try { ensureQwenDir(); createAgentConfig(); updateSettings(); createStartupScript(); showSummary(); } catch (err) { log(`\nāŒ Configuration failed: ${err.message}`, "red"); log("\nPlease check the error and try again.", "yellow"); process.exit(1); } } // Run configuration main();