341 lines
8.9 KiB
JavaScript
341 lines
8.9 KiB
JavaScript
#!/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();
|