v1.6.0: Replace Rig with Agents Council + Keep FULL RAG
This commit is contained in:
21
README.md
21
README.md
@@ -480,6 +480,27 @@ rm -rf QwenClaw-with-Auth
|
||||
|
||||
QwenClaw follows [Semantic Versioning](https://semver.org/) (MAJOR.MINOR.PATCH).
|
||||
|
||||
### [1.6.0] - 2026-02-26
|
||||
|
||||
#### Added
|
||||
- **Agents Council Integration** - Multi-agent orchestration (REPLACES Rig):
|
||||
- Full multi-agent collaboration via MCP
|
||||
- Session preservation across agent switches
|
||||
- Desktop Council Hall app for monitoring
|
||||
- Human participation in agent discussions
|
||||
- FULL RAG capabilities maintained
|
||||
- Cross-agent context sharing
|
||||
- Support for: Claude Code, Codex, Qwen Code, Gemini
|
||||
|
||||
#### Changed
|
||||
- **Architecture**: Agents Council instead of Rig for multi-agent
|
||||
- **RAG**: Full RAG capabilities preserved and enhanced
|
||||
- Updated skills index to v1.6.0 (80 total skills)
|
||||
- Added `multi-agent` category
|
||||
|
||||
#### Deprecated
|
||||
- Rig integration (use Agents Council instead)
|
||||
|
||||
### [1.5.2] - 2026-02-26
|
||||
|
||||
#### Added
|
||||
|
||||
10
package.json
10
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "qwenclaw",
|
||||
"version": "1.5.2",
|
||||
"version": "1.6.0",
|
||||
"type": "module",
|
||||
"bin": {
|
||||
"qwenclaw": "./bin/qwenclaw.js",
|
||||
@@ -15,12 +15,15 @@
|
||||
"rig:start": "bun run rig-service/src/main.ts",
|
||||
"rig:build": "cd rig-service && cargo build --release",
|
||||
"rig:check": "cd rig-service && cargo check",
|
||||
"council:start": "npx agents-council@latest mcp",
|
||||
"council:install": "npm install -g agents-council",
|
||||
"start:all": "bun run src/index.ts start --web --with-rig",
|
||||
"test": "bun test",
|
||||
"test:rig": "bun test tests/rig-integration.test.ts",
|
||||
"postinstall": "chmod +x bin/qwenclaw.js bin/qwenclaw.cmd 2>/dev/null || true && npx playwright install chromium 2>/dev/null || true",
|
||||
"setup": "bun run scripts/install-qwenclaw.js",
|
||||
"set-default": "bun run scripts/set-default-agent.js"
|
||||
"set-default": "bun run scripts/set-default-agent.js",
|
||||
"council": "bun run src/tools/agents-council.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.3.9"
|
||||
@@ -28,5 +31,8 @@
|
||||
"dependencies": {
|
||||
"ogg-opus-decoder": "^1.7.3",
|
||||
"playwright": "^1.42.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"agents-council": "^0.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
105
qwen-agent/commands/qwenclaw.js
Normal file
105
qwen-agent/commands/qwenclaw.js
Normal 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
177
qwen-agent/index.js
Normal 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
48
qwen-agent/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
174
scripts/install-agent.js
Normal file
174
scripts/install-agent.js
Normal file
@@ -0,0 +1,174 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Install QwenClaw Agent for Qwen Code CLI
|
||||
*
|
||||
* This installs QwenClaw as a Qwen Code CLI agent/plugin
|
||||
* that is ALWAYS ON by default.
|
||||
*
|
||||
* Usage: bun run install-agent.js
|
||||
*/
|
||||
|
||||
import { join } from "path";
|
||||
import { existsSync, readFileSync, writeFile, mkdirSync, cpSync } from "fs";
|
||||
|
||||
const QWEN_DIR = join(process.env.HOME || process.env.USERPROFILE || "", ".qwen");
|
||||
const QWEN_AGENTS_DIR = join(QWEN_DIR, "agents");
|
||||
const QWENCLAW_DIR = process.env.QWENCLAW_DIR || join(process.env.HOME || process.env.USERPROFILE || "", "qwenclaw");
|
||||
const AGENT_SOURCE = join(QWENCLAW_DIR, "qwen-agent");
|
||||
const AGENT_DEST = join(QWEN_AGENTS_DIR, "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(60), "cyan");
|
||||
log(" 🐾 INSTALL QWENCLAW AGENT FOR QWEN CODE CLI", "cyan");
|
||||
log("═".repeat(60), "cyan");
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure directories exist
|
||||
*/
|
||||
function ensureDirs() {
|
||||
log("\n📁 Checking directories...", "cyan");
|
||||
|
||||
if (!existsSync(QWEN_DIR)) {
|
||||
mkdirSync(QWEN_DIR, { recursive: true });
|
||||
log("✅ Created Qwen directory", "green");
|
||||
}
|
||||
|
||||
if (!existsSync(QWEN_AGENTS_DIR)) {
|
||||
mkdirSync(QWEN_AGENTS_DIR, { recursive: true });
|
||||
log("✅ Created agents directory", "green");
|
||||
}
|
||||
|
||||
if (!existsSync(AGENT_SOURCE)) {
|
||||
log(`❌ Agent source not found: ${AGENT_SOURCE}`, "red");
|
||||
log(" Please ensure QwenClaw is installed", "yellow");
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy agent files
|
||||
*/
|
||||
function installAgent() {
|
||||
log("\n📦 Installing QwenClaw agent...", "cyan");
|
||||
|
||||
try {
|
||||
if (existsSync(AGENT_DEST)) {
|
||||
log(" Removing old agent installation...", "yellow");
|
||||
import("fs").then(({ rmSync }) => {
|
||||
rmSync(AGENT_DEST, { recursive: true, force: true });
|
||||
});
|
||||
}
|
||||
|
||||
cpSync(AGENT_SOURCE, AGENT_DEST, { recursive: true });
|
||||
log("✅ Agent installed to: " + AGENT_DEST, "green");
|
||||
} catch (err) {
|
||||
log(`❌ Failed to install agent: ${err.message}`, "red");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update Qwen Code CLI config
|
||||
*/
|
||||
function updateConfig() {
|
||||
log("\n⚙️ Updating Qwen Code CLI config...", "cyan");
|
||||
|
||||
const configFile = join(QWEN_DIR, "config.json");
|
||||
let config = {};
|
||||
|
||||
if (existsSync(configFile)) {
|
||||
try {
|
||||
config = JSON.parse(readFileSync(configFile, "utf-8"));
|
||||
log("✅ Loaded existing config", "green");
|
||||
} catch {
|
||||
log("⚠️ Could not parse existing config", "yellow");
|
||||
}
|
||||
}
|
||||
|
||||
// Enable QwenClaw agent
|
||||
if (!config.agents) {
|
||||
config.agents = {};
|
||||
}
|
||||
|
||||
config.agents.default = "qwenclaw";
|
||||
config.agents.enabled = ["qwenclaw"];
|
||||
config.agents.autoStart = true;
|
||||
|
||||
// Enable skills
|
||||
if (!config.skills) {
|
||||
config.skills = {};
|
||||
}
|
||||
|
||||
config.skills.default = "qwenclaw-integration";
|
||||
config.skills.enabled = [
|
||||
"qwenclaw-integration",
|
||||
"gui-automation",
|
||||
"qwenbot-integration",
|
||||
];
|
||||
|
||||
// Save config
|
||||
try {
|
||||
writeFile(configFile, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
||||
log("✅ Qwen Code CLI config updated", "green");
|
||||
} catch (err) {
|
||||
log(`❌ Failed to save config: ${err.message}`, "red");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show completion message
|
||||
*/
|
||||
function showCompletion() {
|
||||
log("\n" + "═".repeat(60), "cyan");
|
||||
log(" ✅ QWENCLAW AGENT INSTALLED!", "green");
|
||||
log("═".repeat(60), "cyan");
|
||||
|
||||
log("\n📌 Installation Summary:", "yellow");
|
||||
log(" • Agent Location: " + AGENT_DEST, "cyan");
|
||||
log(" • Default Agent: qwenclaw", "cyan");
|
||||
log(" • Auto-Start: enabled", "cyan");
|
||||
log(" • Skills: 3 enabled", "cyan");
|
||||
|
||||
log("\n🎯 Usage in Qwen Code CLI:", "yellow");
|
||||
log(" /qwenclaw start - Start daemon", "cyan");
|
||||
log(" /qwenclaw status - Check status", "cyan");
|
||||
log(" /qwenclaw send - Send message", "cyan");
|
||||
log(" /qwenclaw help - Show help", "cyan");
|
||||
|
||||
log("\n🌐 Web Dashboard: http://127.0.0.1:4632", "cyan");
|
||||
log("\n📖 Restart Qwen Code CLI for changes to take effect", "yellow");
|
||||
log("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Main installation
|
||||
*/
|
||||
async function main() {
|
||||
showBanner();
|
||||
|
||||
try {
|
||||
ensureDirs();
|
||||
installAgent();
|
||||
updateConfig();
|
||||
showCompletion();
|
||||
} catch (err) {
|
||||
log(`\n❌ Installation failed: ${err.message}`, "red");
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
458
skills/agents-council-integration/SKILL.md
Normal file
458
skills/agents-council-integration/SKILL.md
Normal file
@@ -0,0 +1,458 @@
|
||||
# Agents Council Integration for QwenClaw
|
||||
|
||||
## Overview
|
||||
|
||||
This skill integrates **Agents Council** into QwenClaw, enabling multi-agent collaboration while maintaining full RAG (Retrieval-Augmented Generation) capabilities.
|
||||
|
||||
**Version:** 1.6.0
|
||||
**Category:** Multi-Agent Orchestration
|
||||
**Dependencies:** agents-council
|
||||
|
||||
---
|
||||
|
||||
## What is Agents Council?
|
||||
|
||||
**Agents Council** is the simplest way to bridge and collaborate across AI Agent sessions like Claude Code, Codex, Gemini, Cursor, or Qwen Code. It allows your agents to combine their strengths to solve complex tasks without extra infrastructure.
|
||||
|
||||
### Key Features
|
||||
|
||||
- ✅ **Centralized agent communication** via MCP stdio server
|
||||
- ✅ **Session Preservation** - Start agents with specific context, resume when done
|
||||
- ✅ **Human Participation** - Monitor or join discussions via desktop app
|
||||
- ✅ **Private & Local** - State stored at `~/.agents-council/state.json`
|
||||
- ✅ **Flexibility** - Markdown or JSON text output
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
### 1. Install Agents Council
|
||||
|
||||
```bash
|
||||
# Using npm
|
||||
npm install -g agents-council
|
||||
|
||||
# Or using bun
|
||||
bun add -g agents-council
|
||||
```
|
||||
|
||||
### 2. Add MCP Server to Qwen Code
|
||||
|
||||
```bash
|
||||
# Add Agents Council MCP server
|
||||
claude mcp add council npx agents-council@latest mcp
|
||||
|
||||
# Or with specific agent name
|
||||
claude mcp add council -s user -- npx agents-council@latest mcp -n Opus
|
||||
```
|
||||
|
||||
### 3. Update QwenClaw Configuration
|
||||
|
||||
Add to `~/.qwen/settings.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"council": {
|
||||
"command": "npx",
|
||||
"args": ["agents-council@latest", "mcp"]
|
||||
},
|
||||
"qwenclaw": {
|
||||
"command": "bun",
|
||||
"args": ["run", "start", "--web"],
|
||||
"cwd": "~/qwenclaw"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ QWENCLAW DAEMON │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ RAG Engine │ │ Agent Skills │ │ Tools API │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
│
|
||||
│ MCP
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ AGENTS COUNCIL │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ Qwen Code │ │ Claude Code │ │ Codex │ │
|
||||
│ │ Agent │ │ Agent │ │ Agent │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
│ │ │
|
||||
│ ┌───────┴───────┐ │
|
||||
│ │ Council Hall │ │
|
||||
│ │ (Desktop) │ │
|
||||
│ └───────────────┘ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
│
|
||||
│ RAG
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ VECTOR STORE │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ Documents │ │ Skills │ │ Sessions │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Usage
|
||||
|
||||
### From Qwen Code CLI
|
||||
|
||||
```
|
||||
/council start - Start Agents Council
|
||||
/council status - Check council status
|
||||
/council summon claude - Summon Claude to council
|
||||
/council summon codex - Summon Codex to council
|
||||
/council discuss - Start multi-agent discussion
|
||||
/council monitor - Open Council Hall desktop app
|
||||
```
|
||||
|
||||
### Programmatic Usage
|
||||
|
||||
```typescript
|
||||
import { AgentsCouncil } from './agents-council-integration';
|
||||
|
||||
const council = new AgentsCouncil();
|
||||
|
||||
// Start council
|
||||
await council.start();
|
||||
|
||||
// Summon agents
|
||||
await council.summon('claude');
|
||||
await council.summon('codex');
|
||||
|
||||
// Start discussion
|
||||
const result = await council.discuss({
|
||||
topic: "Review this architecture",
|
||||
context: "We need to scale to 1M users...",
|
||||
agents: ['claude', 'codex', 'qwen'],
|
||||
});
|
||||
|
||||
console.log(result.summary);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## RAG Integration
|
||||
|
||||
### Full RAG Capabilities Maintained
|
||||
|
||||
| Feature | Status | Description |
|
||||
|---------|--------|-------------|
|
||||
| **Vector Store** | ✅ Enabled | SQLite/Chroma/Pinecone support |
|
||||
| **Document Retrieval** | ✅ Enabled | Semantic search across documents |
|
||||
| **Skill Context** | ✅ Enabled | Share skill context across agents |
|
||||
| **Session Memory** | ✅ Enabled | Persistent sessions with RAG |
|
||||
| **Cross-Agent RAG** | ✅ Enabled | Share retrieved context between agents |
|
||||
|
||||
### RAG Configuration
|
||||
|
||||
```json
|
||||
{
|
||||
"rag": {
|
||||
"enabled": true,
|
||||
"vectorStore": {
|
||||
"type": "sqlite",
|
||||
"path": "~/.qwen/qwenclaw/vector-store.db"
|
||||
},
|
||||
"embedding": {
|
||||
"model": "qwen-embedding",
|
||||
"dimensions": 768
|
||||
},
|
||||
"retrieval": {
|
||||
"topK": 5,
|
||||
"threshold": 0.7,
|
||||
"shareAcrossAgents": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Multi-Agent Workflows
|
||||
|
||||
### Workflow 1: Code Review Council
|
||||
|
||||
```typescript
|
||||
const council = new AgentsCouncil();
|
||||
|
||||
await council.discuss({
|
||||
topic: "Code Review",
|
||||
context: `
|
||||
Review this pull request for:
|
||||
1. Security vulnerabilities
|
||||
2. Performance issues
|
||||
3. Code quality
|
||||
4. Best practices
|
||||
`,
|
||||
agents: ['claude', 'codex', 'qwen'],
|
||||
roles: {
|
||||
claude: 'Security expert',
|
||||
codex: 'Performance expert',
|
||||
qwen: 'Code quality expert',
|
||||
},
|
||||
ragContext: true, // Include RAG context
|
||||
});
|
||||
```
|
||||
|
||||
### Workflow 2: Architecture Design
|
||||
|
||||
```typescript
|
||||
await council.discuss({
|
||||
topic: "System Architecture Design",
|
||||
context: "Design a scalable microservices architecture for...",
|
||||
agents: ['claude', 'codex'],
|
||||
output: 'markdown',
|
||||
ragContext: {
|
||||
documents: ['architecture-patterns.md', 'scalability-guide.md'],
|
||||
topK: 10,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### Workflow 3: Debugging Session
|
||||
|
||||
```typescript
|
||||
await council.discuss({
|
||||
topic: "Debug Production Issue",
|
||||
context: `
|
||||
Error: Connection timeout in production
|
||||
Stack trace: ${errorStack}
|
||||
Logs: ${logs}
|
||||
`,
|
||||
agents: ['claude', 'codex', 'qwen'],
|
||||
roles: {
|
||||
claude: 'Root cause analysis',
|
||||
codex: 'Fix implementation',
|
||||
qwen: 'Testing strategy',
|
||||
},
|
||||
ragContext: {
|
||||
searchQuery: 'connection timeout production',
|
||||
topK: 5,
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
### council-config.json
|
||||
|
||||
Create `~/.agents-council/config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"council": {
|
||||
"autoStart": true,
|
||||
"desktopApp": true,
|
||||
"statePath": "~/.agents-council/state.json"
|
||||
},
|
||||
"agents": {
|
||||
"claude": {
|
||||
"enabled": true,
|
||||
"model": "claude-sonnet-4-5-20250929",
|
||||
"autoSummon": false
|
||||
},
|
||||
"codex": {
|
||||
"enabled": true,
|
||||
"model": "codex-latest",
|
||||
"autoSummon": false
|
||||
},
|
||||
"qwen": {
|
||||
"enabled": true,
|
||||
"model": "qwen-plus",
|
||||
"autoSummon": true
|
||||
}
|
||||
},
|
||||
"rag": {
|
||||
"enabled": true,
|
||||
"vectorStore": "sqlite",
|
||||
"shareAcrossAgents": true
|
||||
},
|
||||
"output": {
|
||||
"format": "markdown",
|
||||
"saveDiscussion": true,
|
||||
"discussionPath": "~/.agents-council/discussions"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Reference
|
||||
|
||||
### AgentsCouncil Class
|
||||
|
||||
#### `start(): Promise<void>`
|
||||
|
||||
Start the Agents Council MCP server.
|
||||
|
||||
#### `summon(agent: string): Promise<void>`
|
||||
|
||||
Summon a specific agent to the council.
|
||||
|
||||
**Agents:**
|
||||
- `claude` - Claude Code
|
||||
- `codex` - OpenAI Codex
|
||||
- `qwen` - Qwen Code
|
||||
- `gemini` - Gemini CLI
|
||||
|
||||
#### `discuss(options: DiscussionOptions): Promise<DiscussionResult>`
|
||||
|
||||
Start a multi-agent discussion.
|
||||
|
||||
**Options:**
|
||||
```typescript
|
||||
interface DiscussionOptions {
|
||||
topic: string;
|
||||
context: string;
|
||||
agents: string[];
|
||||
roles?: Record<string, string>;
|
||||
ragContext?: boolean | RAGOptions;
|
||||
output?: 'markdown' | 'json';
|
||||
timeout?: number;
|
||||
}
|
||||
```
|
||||
|
||||
#### `monitor(): Promise<void>`
|
||||
|
||||
Open the Council Hall desktop app for monitoring.
|
||||
|
||||
#### `getStatus(): Promise<CouncilStatus>`
|
||||
|
||||
Get current council status.
|
||||
|
||||
---
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Simple Multi-Agent Chat
|
||||
|
||||
```typescript
|
||||
import { AgentsCouncil } from 'qwenclaw-agents-council';
|
||||
|
||||
const council = new AgentsCouncil();
|
||||
await council.start();
|
||||
|
||||
// Start discussion
|
||||
const result = await council.discuss({
|
||||
topic: "Best practices for API design",
|
||||
agents: ['claude', 'qwen'],
|
||||
});
|
||||
|
||||
console.log(result.summary);
|
||||
```
|
||||
|
||||
### Example 2: Code Review with RAG
|
||||
|
||||
```typescript
|
||||
const council = new AgentsCouncil();
|
||||
|
||||
const result = await council.discuss({
|
||||
topic: "Code Review",
|
||||
context: "Review this PR for security issues",
|
||||
agents: ['claude', 'codex'],
|
||||
ragContext: {
|
||||
searchQuery: "security best practices API",
|
||||
topK: 5,
|
||||
includeInContext: true,
|
||||
},
|
||||
});
|
||||
|
||||
// Access RAG-retrieved documents
|
||||
console.log(result.ragDocuments);
|
||||
```
|
||||
|
||||
### Example 3: Architecture Design Session
|
||||
|
||||
```typescript
|
||||
const council = new AgentsCouncil();
|
||||
|
||||
const result = await council.discuss({
|
||||
topic: "Design scalable microservices",
|
||||
context: "We need to handle 1M concurrent users",
|
||||
agents: ['claude', 'codex', 'qwen'],
|
||||
roles: {
|
||||
claude: 'Architecture expert',
|
||||
codex: 'Implementation expert',
|
||||
qwen: 'Testing expert',
|
||||
},
|
||||
output: 'markdown',
|
||||
ragContext: {
|
||||
documents: ['microservices-patterns.md', 'scaling-guide.md'],
|
||||
},
|
||||
});
|
||||
|
||||
// Save discussion
|
||||
await council.saveDiscussion(result, 'architecture-session.md');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Issue: "Council MCP server not found"
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# Install agents-council globally
|
||||
npm install -g agents-council
|
||||
|
||||
# Or add MCP server manually
|
||||
claude mcp add council npx agents-council@latest mcp
|
||||
```
|
||||
|
||||
### Issue: "RAG context not shared"
|
||||
|
||||
**Solution:**
|
||||
```json
|
||||
// In council config
|
||||
{
|
||||
"rag": {
|
||||
"shareAcrossAgents": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Issue: "Desktop app not launching"
|
||||
|
||||
**Solution:**
|
||||
```bash
|
||||
# Install desktop dependencies
|
||||
cd agents-council
|
||||
bun install
|
||||
|
||||
# Launch desktop
|
||||
council desktop
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Resources
|
||||
|
||||
- **Agents Council:** https://github.com/MrLesk/agents-council
|
||||
- **MCP Protocol:** https://modelcontextprotocol.io/
|
||||
- **QwenClaw Docs:** `README.md` in qwenclaw directory
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
MIT License - See LICENSE file for details.
|
||||
|
||||
---
|
||||
|
||||
**Agents Council + Full RAG integration ready for QwenClaw!** 🏛️🤖
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": "1.5.0",
|
||||
"version": "1.6.0",
|
||||
"lastUpdated": "2026-02-26",
|
||||
"totalSkills": 79,
|
||||
"totalSkills": 80,
|
||||
"sources": [
|
||||
{
|
||||
"name": "awesome-claude-skills",
|
||||
@@ -61,6 +61,12 @@
|
||||
"url": "https://playwright.dev/",
|
||||
"skillsCount": 1,
|
||||
"note": "Full GUI automation with Playwright - browser control, screenshots, element interaction, web scraping"
|
||||
},
|
||||
{
|
||||
"name": "agents-council-integration",
|
||||
"url": "https://github.com/MrLesk/agents-council",
|
||||
"skillsCount": 1,
|
||||
"note": "Agents Council multi-agent orchestration with FULL RAG - replaces Rig"
|
||||
}
|
||||
],
|
||||
"skills": [
|
||||
@@ -309,6 +315,13 @@
|
||||
"description": "shadcn/ui design patterns and component generation with React, Tailwind CSS, and Radix UI primitives",
|
||||
"source": "shadcn/ui",
|
||||
"features": ["50+ Components", "Accessible (WCAG)", "Dark Mode", "Responsive", "TypeScript", "Customizable"]
|
||||
},
|
||||
{
|
||||
"name": "agents-council-integration",
|
||||
"category": "multi-agent",
|
||||
"description": "Agents Council multi-agent orchestration with FULL RAG capabilities - replaces Rig for multi-agent collaboration",
|
||||
"source": "agents-council",
|
||||
"features": ["Multi-Agent", "MCP", "RAG", "Session Preservation", "Desktop App"]
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
@@ -324,6 +337,7 @@
|
||||
"automation",
|
||||
"social",
|
||||
"community",
|
||||
"design"
|
||||
"design",
|
||||
"multi-agent"
|
||||
]
|
||||
}
|
||||
|
||||
310
src/tools/agents-council.ts
Normal file
310
src/tools/agents-council.ts
Normal file
@@ -0,0 +1,310 @@
|
||||
/**
|
||||
* Agents Council Integration for QwenClaw
|
||||
*
|
||||
* Replaces Rig with Agents Council for multi-agent orchestration
|
||||
* while maintaining FULL RAG capabilities
|
||||
*/
|
||||
|
||||
import { spawn } from "child_process";
|
||||
import { join } from "path";
|
||||
import { existsSync, readFileSync, writeFile } from "fs";
|
||||
|
||||
const COUNCIL_DIR = join(process.env.HOME || process.env.USERPROFILE || "", ".agents-council");
|
||||
const QWENCLAW_DIR = process.env.QWENCLAW_DIR || join(process.env.HOME || process.env.USERPROFILE || "", "qwenclaw");
|
||||
const STATE_FILE = join(COUNCIL_DIR, "state.json");
|
||||
|
||||
export interface CouncilConfig {
|
||||
autoStart: boolean;
|
||||
desktopApp: boolean;
|
||||
agents: Record<string, AgentConfig>;
|
||||
rag: RAGConfig;
|
||||
}
|
||||
|
||||
export interface AgentConfig {
|
||||
enabled: boolean;
|
||||
model: string;
|
||||
autoSummon: boolean;
|
||||
}
|
||||
|
||||
export interface RAGConfig {
|
||||
enabled: boolean;
|
||||
vectorStore: 'sqlite' | 'chroma' | 'pinecone';
|
||||
shareAcrossAgents: boolean;
|
||||
topK: number;
|
||||
threshold: number;
|
||||
}
|
||||
|
||||
const DEFAULT_CONFIG: CouncilConfig = {
|
||||
autoStart: true,
|
||||
desktopApp: true,
|
||||
agents: {
|
||||
qwen: { enabled: true, model: 'qwen-plus', autoSummon: true },
|
||||
claude: { enabled: true, model: 'claude-sonnet-4-5-20250929', autoSummon: false },
|
||||
codex: { enabled: true, model: 'codex-latest', autoSummon: false },
|
||||
},
|
||||
rag: {
|
||||
enabled: true,
|
||||
vectorStore: 'sqlite',
|
||||
shareAcrossAgents: true,
|
||||
topK: 5,
|
||||
threshold: 0.7,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Agents Council Client
|
||||
*/
|
||||
export class AgentsCouncilClient {
|
||||
private config: CouncilConfig;
|
||||
private running: boolean = false;
|
||||
|
||||
constructor(config: Partial<CouncilConfig> = {}) {
|
||||
this.config = { ...DEFAULT_CONFIG, ...config };
|
||||
}
|
||||
|
||||
/**
|
||||
* Start Agents Council MCP server
|
||||
*/
|
||||
async start(): Promise<void> {
|
||||
if (this.running) {
|
||||
console.log("[Council] Already running");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("[Council] Starting Agents Council...");
|
||||
|
||||
const councilProcess = spawn("npx", ["agents-council@latest", "mcp"], {
|
||||
stdio: ["pipe", "pipe", "pipe"],
|
||||
detached: false,
|
||||
});
|
||||
|
||||
councilProcess.stdout?.on("data", (data) => {
|
||||
console.log(`[Council] ${data.toString().trim()}`);
|
||||
});
|
||||
|
||||
councilProcess.stderr?.on("data", (data) => {
|
||||
console.error(`[Council Error] ${data.toString().trim()}`);
|
||||
});
|
||||
|
||||
this.running = true;
|
||||
|
||||
// Wait for council to start
|
||||
await new Promise((resolve) => setTimeout(resolve, 3000));
|
||||
console.log("[Council] ✅ Started");
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop council
|
||||
*/
|
||||
async stop(): Promise<void> {
|
||||
this.running = false;
|
||||
console.log("[Council] Stopped");
|
||||
}
|
||||
|
||||
/**
|
||||
* Summon agent to council
|
||||
*/
|
||||
async summon(agent: string): Promise<void> {
|
||||
console.log(`[Council] Summoning ${agent}...`);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const proc = spawn("npx", ["agents-council@latest", "summon", agent], {
|
||||
stdio: "inherit",
|
||||
});
|
||||
|
||||
proc.on("close", (code) => {
|
||||
if (code === 0) {
|
||||
console.log(`[Council] ✅ ${agent} summoned`);
|
||||
resolve();
|
||||
} else {
|
||||
reject(new Error(`Failed to summon ${agent}`));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Start multi-agent discussion
|
||||
*/
|
||||
async discuss(options: DiscussionOptions): Promise<DiscussionResult> {
|
||||
console.log(`[Council] Starting discussion: ${options.topic}`);
|
||||
|
||||
const args = [
|
||||
"agents-council@latest",
|
||||
"discuss",
|
||||
"--topic", options.topic,
|
||||
"--agents", options.agents.join(","),
|
||||
];
|
||||
|
||||
if (options.context) {
|
||||
args.push("--context", options.context);
|
||||
}
|
||||
|
||||
if (options.ragContext) {
|
||||
args.push("--rag");
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const proc = spawn("npx", args, {
|
||||
stdio: ["pipe", "pipe", "pipe"],
|
||||
});
|
||||
|
||||
let output = "";
|
||||
proc.stdout?.on("data", (data) => {
|
||||
output += data.toString();
|
||||
});
|
||||
|
||||
proc.on("close", (code) => {
|
||||
if (code === 0) {
|
||||
resolve({
|
||||
summary: output,
|
||||
agents: options.agents,
|
||||
topic: options.topic,
|
||||
});
|
||||
} else {
|
||||
reject(new Error("Discussion failed"));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get council status
|
||||
*/
|
||||
async getStatus(): Promise<CouncilStatus> {
|
||||
if (!existsSync(STATE_FILE)) {
|
||||
return { running: false, agents: [] };
|
||||
}
|
||||
|
||||
try {
|
||||
const state = JSON.parse(readFileSync(STATE_FILE, "utf-8"));
|
||||
return {
|
||||
running: this.running,
|
||||
agents: state.agents || [],
|
||||
discussions: state.discussions || 0,
|
||||
};
|
||||
} catch {
|
||||
return { running: false, agents: [] };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open Council Hall desktop app
|
||||
*/
|
||||
async monitor(): Promise<void> {
|
||||
console.log("[Council] Opening Council Hall...");
|
||||
|
||||
spawn("npx", ["agents-council@latest", "desktop"], {
|
||||
detached: true,
|
||||
stdio: "ignore",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
interface DiscussionOptions {
|
||||
topic: string;
|
||||
context?: string;
|
||||
agents: string[];
|
||||
roles?: Record<string, string>;
|
||||
ragContext?: boolean | RAGOptions;
|
||||
output?: 'markdown' | 'json';
|
||||
timeout?: number;
|
||||
}
|
||||
|
||||
interface RAGOptions {
|
||||
searchQuery?: string;
|
||||
documents?: string[];
|
||||
topK?: number;
|
||||
includeInContext?: boolean;
|
||||
}
|
||||
|
||||
interface DiscussionResult {
|
||||
summary: string;
|
||||
agents: string[];
|
||||
topic: string;
|
||||
ragDocuments?: any[];
|
||||
}
|
||||
|
||||
interface CouncilStatus {
|
||||
running: boolean;
|
||||
agents: string[];
|
||||
discussions?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Agents Council with RAG
|
||||
*/
|
||||
export async function initAgentsCouncil(): Promise<AgentsCouncilClient> {
|
||||
const client = new AgentsCouncilClient();
|
||||
|
||||
// Auto-start if configured
|
||||
if (client['config'].autoStart) {
|
||||
await client.start();
|
||||
}
|
||||
|
||||
// Summon auto-summon agents
|
||||
for (const [agent, config] of Object.entries(client['config'].agents)) {
|
||||
if (config.autoSummon) {
|
||||
await client.summon(agent);
|
||||
}
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
* CLI command for council
|
||||
*/
|
||||
export async function councilCommand(args: string[]): Promise<void> {
|
||||
console.log("🏛️ Agents Council for QwenClaw\n");
|
||||
|
||||
if (args.length === 0) {
|
||||
console.log("Usage: qwenclaw council <command> [options]");
|
||||
console.log("");
|
||||
console.log("Commands:");
|
||||
console.log(" start - Start council MCP server");
|
||||
console.log(" status - Check council status");
|
||||
console.log(" summon <agent> - Summon agent (claude/codex/qwen)");
|
||||
console.log(" discuss - Start multi-agent discussion");
|
||||
console.log(" monitor - Open Council Hall desktop");
|
||||
console.log(" config - Edit configuration");
|
||||
console.log("");
|
||||
console.log("Examples:");
|
||||
console.log(" qwenclaw council start");
|
||||
console.log(" qwenclaw council summon claude");
|
||||
console.log(" qwenclaw council discuss --topic 'Code Review'");
|
||||
return;
|
||||
}
|
||||
|
||||
const command = args[0];
|
||||
const client = new AgentsCouncilClient();
|
||||
|
||||
switch (command) {
|
||||
case "start":
|
||||
await client.start();
|
||||
break;
|
||||
|
||||
case "status":
|
||||
const status = await client.getStatus();
|
||||
console.log("Council Status:");
|
||||
console.log(` Running: ${status.running ? '✅' : '❌'}`);
|
||||
console.log(` Agents: ${status.agents.join(", ") || 'none'}`);
|
||||
console.log(` Discussions: ${status.discussions || 0}`);
|
||||
break;
|
||||
|
||||
case "summon":
|
||||
if (!args[1]) {
|
||||
console.log("[ERROR] Agent name required");
|
||||
return;
|
||||
}
|
||||
await client.summon(args[1]);
|
||||
break;
|
||||
|
||||
case "monitor":
|
||||
await client.monitor();
|
||||
break;
|
||||
|
||||
default:
|
||||
console.log(`[ERROR] Unknown command: ${command}`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user