v1.1.0: Skills integration, cross-platform support, bug fixes

This commit is contained in:
admin
2026-02-26 02:34:00 +04:00
Unverified
parent c9799c1eac
commit 2f49d51abd
10 changed files with 1709 additions and 58 deletions

View File

@@ -157,30 +157,20 @@ function nextAllowedHeartbeatAt(
}
async function setupStatusline() {
console.log("[QwenClaw SetupStatusline] Starting...");
await mkdir(QWEN_DIR, { recursive: true });
console.log("[QwenClaw SetupStatusline] Directory created:", QWEN_DIR);
await writeFile(STATUSLINE_FILE, STATUSLINE_SCRIPT);
console.log("[QwenClaw SetupStatusline] Statusline script written:", STATUSLINE_FILE);
let settings: Record<string, unknown> = {};
try {
const settingsText = await Bun.file(QWEN_SETTINGS_FILE).text();
console.log("[QwenClaw SetupStatusline] Settings text read, length:", settingsText.length);
settings = JSON.parse(settingsText);
console.log("[QwenClaw SetupStatusline] Settings parsed");
} catch (err) {
console.log("[QwenClaw SetupStatusline] No existing settings or error:", err);
settings = await Bun.file(QWEN_SETTINGS_FILE).json();
} catch {
// file doesn't exist or isn't valid JSON
}
settings.statusLine = {
type: "command",
command: "node .qwen/statusline.cjs",
};
const settingsJson = JSON.stringify(settings, null, 2) + "\n";
console.log("[QwenClaw SetupStatusline] Writing settings:", settingsJson.substring(0, 100));
await writeFile(QWEN_SETTINGS_FILE, settingsJson);
console.log("[QwenClaw SetupStatusline] Settings written");
await writeFile(QWEN_SETTINGS_FILE, JSON.stringify(settings, null, 2) + "\n");
}
async function teardownStatusline() {
@@ -202,10 +192,6 @@ async function teardownStatusline() {
// --- Main ---
export async function start(args: string[] = []) {
console.log("[QwenClaw Start] Function called with args:", args);
try {
let hasPromptFlag = false;
let hasTriggerFlag = false;
let telegramFlag = false;
@@ -215,7 +201,6 @@ export async function start(args: string[] = []) {
let webPortFlag: number | null = null;
const payloadParts: string[] = [];
console.log("[QwenClaw Start] Parsing arguments...");
for (let i = 0; i < args.length; i++) {
const arg = args[i];
if (arg === "--prompt") {
@@ -248,8 +233,6 @@ export async function start(args: string[] = []) {
}
}
const payload = payloadParts.join(" ").trim();
console.log("[QwenClaw Start] Payload:", payload, "hasPromptFlag:", hasPromptFlag, "webFlag:", webFlag);
if (hasPromptFlag && !payload) {
console.error("Usage: qwenclaw start --prompt <prompt> [--trigger] [--telegram] [--debug] [--web] [--web-port <port>] [--replace-existing]");
process.exit(1);
@@ -267,7 +250,6 @@ export async function start(args: string[] = []) {
process.exit(1);
}
console.log("[QwenClaw Start] Checking existing daemon...");
// One-shot mode: explicit prompt without trigger.
if (hasPromptFlag && !hasTriggerFlag) {
const existingPid = await checkExistingDaemon();
@@ -315,31 +297,14 @@ export async function start(args: string[] = []) {
}
await initConfig();
console.log("[QwenClaw Start] Config initialized");
const settings = await loadSettings();
console.log("[QwenClaw Start] Settings loaded, web:", settings.web);
await ensureProjectQwenMd();
console.log("[QwenClaw Start] Project QWEN.md ensured");
const jobs = await loadJobs();
console.log("[QwenClaw Start] Jobs loaded:", jobs.length);
const webEnabled = webFlag || webPortFlag !== null || settings.web.enabled;
const webPort = webPortFlag ?? settings.web.port;
console.log("[QwenClaw Start] Web enabled:", webEnabled, "Port:", webPort);
try {
await setupStatusline();
console.log("[QwenClaw Start] Statusline setup complete");
} catch (err) {
console.error("[QwenClaw Start] Statusline setup error:", err);
}
await setupStatusline();
await writePidFile();
console.log("[QwenClaw Start] PID file written");
let web: WebServerHandle | null = null;
async function shutdown() {
@@ -688,9 +653,5 @@ export async function start(args: string[] = []) {
}
updateState();
}, 60_000);
} catch (err) {
console.error("[QwenClaw Start] Fatal error:", err);
process.exit(1);
}
}

View File

@@ -8,8 +8,6 @@ const args = process.argv.slice(2);
const command = args[0];
async function main() {
console.log("[QwenClaw] Index.ts - Command:", command);
if (command === "--stop-all") {
await stopAll();
} else if (command === "--stop") {
@@ -17,9 +15,7 @@ async function main() {
} else if (command === "--clear") {
await clear();
} else if (command === "start") {
console.log("[QwenClaw] Calling start function...");
await start(args.slice(1));
console.log("[QwenClaw] Start function returned");
} else if (command === "status") {
await status();
} else if (command === "telegram") {
@@ -27,7 +23,6 @@ async function main() {
} else if (command === "send") {
await send(args.slice(1));
} else {
console.log("[QwenClaw] No command, starting default...");
await start();
}
}
@@ -36,9 +31,3 @@ main().catch((err) => {
console.error("[QwenClaw] Fatal error:", err);
process.exit(1);
});
// Keep process alive
process.on('SIGINT', () => {
console.log('[QwenClaw] Received SIGINT, shutting down...');
process.exit(0);
});

View File

@@ -67,14 +67,20 @@ async function runQwenOnce(
const args = [...baseArgs];
if (model.trim()) args.push("--model", model.trim());
// Use qwen.cmd on Windows for proper execution
const qwenCommand = process.platform === "win32" ? "qwen.cmd" : "qwen";
// Cross-platform command detection
const qwenCommand = process.platform === "win32"
? "qwen.cmd"
: process.platform === "darwin"
? "qwen"
: "qwen";
const proc = Bun.spawn([qwenCommand, ...args], {
stdout: "pipe",
stderr: "pipe",
env: buildChildEnv(baseEnv, model, api),
shell: true,
// Detach on non-Windows to allow background execution
detached: process.platform !== "win32",
});
const [rawStdout, stderr] = await Promise.all([