v1.6.0: Replace Rig with Agents Council + Keep FULL RAG

This commit is contained in:
admin
2026-02-26 17:53:41 +04:00
Unverified
parent 7255ca42aa
commit 1387a8b1c6
9 changed files with 1318 additions and 5 deletions

View File

@@ -0,0 +1,105 @@
/**
* QwenClaw Command Handler for Qwen Code CLI
*/
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;
}
}
export async function handle(args) {
const command = args[0];
switch (command) {
case "start":
if (isRunning()) {
return "✅ QwenClaw daemon is already running";
}
const proc = spawn("bun", ["run", "start", "--web"], {
cwd: QWENCLAW_DIR,
detached: true,
stdio: "ignore",
windowsHide: true,
});
proc.unref();
return "🚀 Starting QwenClaw daemon...\n Web Dashboard: http://127.0.0.1:4632";
case "status":
if (isRunning()) {
const pid = parseInt(readFileSync(PID_FILE, "utf-8").trim(), 10);
return `✅ QwenClaw daemon is running\n PID: ${pid}\n Web Dashboard: http://127.0.0.1:4632`;
}
return "❌ QwenClaw daemon is not running\n Run: /qwenclaw start";
case "send":
const message = args.slice(1).join(" ");
if (!message) return "Usage: /qwenclaw send <message>";
return new Promise((resolve) => {
const proc = spawn("bun", ["run", "send", message], {
cwd: QWENCLAW_DIR,
stdio: ["pipe", "pipe", "pipe"],
});
let output = "";
proc.stdout.on("data", (data) => {
output += data.toString();
});
proc.on("close", () => {
resolve(output || "Message sent to daemon");
});
});
case "skills":
return `
QwenClaw Skills (79 total):
• qwenclaw-integration - Daemon control & communication
• gui-automation - Full browser automation with Playwright
• qwenbot-integration - QwenBot AI assistant
• shadcn-ui-design - shadcn/ui design patterns
• metatrader5-trading - MetaTrader 5 trading
• ... and 74 more
Run: qwenclaw skills (in terminal) for full list
`;
case "help":
default:
return `
🐾 QwenClaw - Your Always-ON AI Assistant
Commands:
/qwenclaw start - Start daemon
/qwenclaw status - Check status
/qwenclaw send - Send message
/qwenclaw skills - List skills
/qwenclaw help - This help
Terminal Commands:
qwenclaw start --web
qwenclaw status
qwenclaw send "message"
qwenclaw skills
Web Dashboard: http://127.0.0.1:4632
`;
}
}

177
qwen-agent/index.js Normal file
View File

@@ -0,0 +1,177 @@
/**
* QwenClaw Agent for Qwen Code CLI
*
* This agent intercepts all Qwen Code CLI interactions
* and ensures QwenClaw daemon is always active.
*/
import { spawn } from "child_process";
import { join } from "path";
import { existsSync, readFileSync, writeFile } from "fs";
const QWENCLAW_DIR = process.env.QWENCLAW_DIR || join(process.env.HOME || process.env.USERPROFILE || "", "qwenclaw");
const QWEN_DIR = join(process.env.HOME || process.env.USERPROFILE || "", ".qwen");
const PID_FILE = join(QWEN_DIR, "qwenclaw", "daemon.pid");
/**
* Check if QwenClaw daemon is running
*/
function isDaemonRunning() {
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;
}
}
/**
* Start QwenClaw daemon
*/
function startDaemon() {
if (isDaemonRunning()) {
console.log("[QwenClaw] Daemon already running");
return;
}
console.log("[QwenClaw] Starting daemon...");
const proc = spawn("bun", ["run", "start", "--web"], {
cwd: QWENCLAW_DIR,
detached: true,
stdio: "ignore",
windowsHide: true,
});
proc.unref();
setTimeout(() => {
if (isDaemonRunning()) {
console.log("[QwenClaw] ✅ Daemon started");
console.log("[QwenClaw] Web Dashboard: http://127.0.0.1:4632");
}
}, 3000);
}
/**
* Intercept Qwen Code CLI input and prepend QwenClaw context
*/
function interceptInput(input) {
// If input starts with /qwenclaw, handle as daemon command
if (input.startsWith("/qwenclaw")) {
return handleQwenClawCommand(input);
}
// Otherwise, pass through to Qwen Code with QwenClaw context
return {
context: "QwenClaw daemon is active. All interactions are logged and can be automated.",
input: input,
};
}
/**
* Handle QwenClaw commands
*/
function handleQwenClawCommand(command) {
const args = command.slice("/qwenclaw".length).trim().split(/\s+/);
const subcommand = args[0];
switch (subcommand) {
case "start":
startDaemon();
return "Starting QwenClaw daemon...";
case "status":
if (isDaemonRunning()) {
const pid = parseInt(readFileSync(PID_FILE, "utf-8").trim(), 10);
return `✅ QwenClaw daemon is running (PID: ${pid})\n Web Dashboard: http://127.0.0.1:4632`;
} else {
return "❌ QwenClaw daemon is not running\n Run /qwenclaw start to start it";
}
case "stop":
if (isDaemonRunning()) {
const pid = parseInt(readFileSync(PID_FILE, "utf-8").trim(), 10);
try {
process.kill(pid, "SIGTERM");
return "Stopping QwenClaw daemon...";
} catch {
return "Failed to stop daemon";
}
} else {
return "Daemon is not running";
}
case "send":
const message = args.slice(1).join(" ");
if (!message) {
return "Usage: /qwenclaw send <message>";
}
return sendToDaemon(message);
case "help":
return `
QwenClaw Commands:
/qwenclaw start - Start daemon
/qwenclaw status - Check daemon status
/qwenclaw stop - Stop daemon
/qwenclaw send - Send message to daemon
/qwenclaw skills - List available skills
/qwenclaw help - Show this help
Web Dashboard: http://127.0.0.1:4632
`;
default:
return `Unknown command: ${subcommand}\nRun /qwenclaw help for usage`;
}
}
/**
* Send message to daemon
*/
function sendToDaemon(message) {
return new Promise((resolve) => {
const proc = spawn("bun", ["run", "send", message], {
cwd: QWENCLAW_DIR,
stdio: ["pipe", "pipe", "pipe"],
});
let output = "";
proc.stdout.on("data", (data) => {
output += data.toString();
});
proc.on("close", () => {
resolve(output || "Message sent to daemon");
});
});
}
/**
* Initialize QwenClaw agent
*/
export function init() {
console.log("\n🐾 QwenClaw Agent initialized");
console.log(" QwenClaw is now your ALWAYS-ON agent");
console.log(" Use /qwenclaw help for commands\n");
// Auto-start daemon
startDaemon();
return {
name: "QwenClaw",
version: "1.0.0",
interceptInput,
commands: {
qwenclaw: handleQwenClawCommand,
},
};
}
// Auto-initialize when loaded
init();

48
qwen-agent/package.json Normal file
View File

@@ -0,0 +1,48 @@
{
"name": "qwenclaw-agent",
"version": "1.0.0",
"description": "QwenClaw - Persistent AI assistant daemon for Qwen Code CLI",
"main": "index.js",
"type": "module",
"qwen": {
"type": "agent",
"displayName": "QwenClaw 🐾",
"description": "Persistent AI assistant daemon with full automation capabilities",
"autoStart": true,
"alwaysOn": true,
"priority": 1,
"commands": [
{
"name": "qwenclaw",
"description": "Interact with QwenClaw daemon",
"handler": "./commands/qwenclaw.js"
}
],
"skills": [
"qwenclaw-integration",
"gui-automation",
"qwenbot-integration"
],
"config": {
"daemon": {
"autoStart": true,
"webDashboard": true,
"port": 4632
}
}
},
"keywords": [
"qwen",
"qwenclaw",
"agent",
"daemon",
"automation",
"ai-assistant"
],
"author": "QwenClaw Team",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.rommark.dev/admin/QwenClaw-with-Auth.git"
}
}