diff --git a/.claude/settings.local.json b/.claude/settings.local.json deleted file mode 100644 index 46a693c21..000000000 --- a/.claude/settings.local.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "permissions": { - "allow": [ - "Bash(*)", - "Bash(grep:*)", - "WebSearch", - "WebFetch(domain:github.com)", - "Bash(pnpm exec tsc:*)", - "Bash(npx tsc:*)", - "Bash(node:*)", - "Bash(pnpm build:*)", - "Bash(pnpm install)", - "Bash(pnpm lint:*)", - "Bash(pnpm exec oxlint:*)", - "Bash(pnpm exec vitest:*)", - "Bash(npm test)", - "Bash(npx vitest:*)", - "Bash(echo:*)", - "Bash(npx eslint:*)", - "Bash(dir \"D:\\\\Download\\\\Chrome\\\\NapCat.Shell.Windows.OneKey\\\\NapCat.44498.Shell\\\\versions\\\\9.9.26-44498\\\\resources\\\\app\\\\napcat\\\\config\")", - "Bash(npx tsx:*)", - "Bash(ls:*)", - "Bash(NODE_OPTIONS=\"--import tsx\" node:*)", - "Bash(curl:*)", - "Bash(taskkill:*)", - "Bash(powershell -Command \"Stop-Process -Id 38624 -Force\")", - "Bash(dir:*)", - "Bash(npx moltbot gateway stop)", - "Bash(npm run build:*)", - "Bash(tasklist:*)", - "Bash(wmic process where \"name=''node.exe''\" get processid,commandline)", - "Bash(powershell.exe -Command \"Get-Process node -ErrorAction SilentlyContinue | Format-Table Id, ProcessName -AutoSize\")", - "Bash(powershell.exe -Command \"Get-NetTCPConnection -LocalPort 18789 -ErrorAction SilentlyContinue | Format-Table OwningProcess, State -AutoSize\")", - "Bash(powershell.exe -Command \"Stop-Process -Id 29716 -Force\")", - "Bash(CLAWDBOT_TS_COMPILER=tsc node:*)" - ] - } -} diff --git a/extensions/qq/src/onebot/client.ts b/extensions/qq/src/onebot/client.ts index d67bcb4c8..6576fb5bf 100644 --- a/extensions/qq/src/onebot/client.ts +++ b/extensions/qq/src/onebot/client.ts @@ -233,6 +233,13 @@ export class OneBotClient { this.state = "disconnected"; this.ws = null; + // Clean up pending requests to prevent memory leak + for (const [echo, pending] of this.pendingRequests) { + clearTimeout(pending.timeoutId); + pending.reject(new Error(`Connection closed (code: ${code})`)); + } + this.pendingRequests.clear(); + this.events.onDisconnect?.(code, reason.toString()); // Auto-reconnect if enabled and not manually disconnected diff --git a/extensions/qq/test-connection.ts b/extensions/qq/test-connection.ts deleted file mode 100644 index 0fc713db9..000000000 --- a/extensions/qq/test-connection.ts +++ /dev/null @@ -1,82 +0,0 @@ -/** - * QQ Connection Test Script - * - * Tests connection to NapCat OneBot WebSocket server. - * Run with: npx tsx extensions/qq/test-connection.ts - */ - -import WebSocket from "ws"; - -const WS_URL = "ws://127.0.0.1:3001"; - -console.log(`\n🔌 Connecting to NapCat at ${WS_URL}...\n`); - -const ws = new WebSocket(WS_URL); - -ws.on("open", () => { - console.log("✅ Connected to NapCat!\n"); - - // Request login info - const request = { - action: "get_login_info", - params: {}, - echo: "test_login_info" - }; - - console.log("📤 Sending get_login_info request..."); - ws.send(JSON.stringify(request)); -}); - -ws.on("message", (data) => { - try { - const message = JSON.parse(data.toString()); - - // Check if it's our API response - if (message.echo === "test_login_info") { - if (message.status === "ok") { - console.log("\n✅ Login info received:"); - console.log(` QQ号: ${message.data.user_id}`); - console.log(` 昵称: ${message.data.nickname}`); - } else { - console.log("\n❌ API call failed:", message.message || message.wording); - } - - // Close connection after getting info - setTimeout(() => { - console.log("\n👋 Closing connection..."); - ws.close(); - }, 500); - return; - } - - // It's an event - if (message.post_type === "message") { - const chatType = message.message_type === "group" ? "群聊" : "私聊"; - const sender = message.sender?.nickname || message.user_id; - console.log(`\n📨 收到${chatType}消息 [${sender}]: ${message.raw_message?.slice(0, 50)}...`); - } else if (message.post_type === "meta_event" && message.meta_event_type === "heartbeat") { - console.log("💓 Heartbeat"); - } else if (message.post_type === "meta_event" && message.meta_event_type === "lifecycle") { - console.log(`🔄 Lifecycle event: ${message.sub_type}`); - } - } catch (err) { - console.log("⚠️ Failed to parse message:", data.toString().slice(0, 100)); - } -}); - -ws.on("error", (error) => { - console.error("\n❌ Connection error:", error.message); - console.log("\n提示: 请确保 NapCat 已启动且 WebSocket 服务器已配置在端口 3001"); - process.exit(1); -}); - -ws.on("close", (code, reason) => { - console.log(`\n🔌 Connection closed (code: ${code})`); - process.exit(0); -}); - -// Timeout after 10 seconds -setTimeout(() => { - console.log("\n⏱️ Timeout - closing connection"); - ws.close(); -}, 10000); diff --git a/extensions/qq/test-send.ts b/extensions/qq/test-send.ts deleted file mode 100644 index 024361eb8..000000000 --- a/extensions/qq/test-send.ts +++ /dev/null @@ -1,98 +0,0 @@ -/** - * QQ Send Message Test - * - * Tests sending a message via OneBot API. - * Usage: npx tsx extensions/qq/test-send.ts - * - * Examples: - * npx tsx extensions/qq/test-send.ts 123456789 "Hello!" - * npx tsx extensions/qq/test-send.ts group:740112783 "Hello group!" - */ - -import WebSocket from "ws"; - -const WS_URL = "ws://127.0.0.1:3001"; - -// Parse arguments -const args = process.argv.slice(2); -if (args.length < 2) { - console.log("Usage: npx tsx extensions/qq/test-send.ts "); - console.log(""); - console.log("Examples:"); - console.log(' npx tsx extensions/qq/test-send.ts 123456789 "Hello!"'); - console.log(' npx tsx extensions/qq/test-send.ts group:740112783 "Hello group!"'); - process.exit(1); -} - -const [target, ...messageParts] = args; -const message = messageParts.join(" "); - -// Parse target -const isGroup = target.startsWith("group:"); -const targetId = isGroup ? Number(target.slice(6)) : Number(target); - -if (Number.isNaN(targetId)) { - console.error("❌ Invalid target ID:", target); - process.exit(1); -} - -console.log(`\n🔌 Connecting to NapCat at ${WS_URL}...`); - -const ws = new WebSocket(WS_URL); - -ws.on("open", () => { - console.log("✅ Connected!\n"); - - const action = isGroup ? "send_group_msg" : "send_private_msg"; - const params = isGroup - ? { group_id: targetId, message: [{ type: "text", data: { text: message } }] } - : { user_id: targetId, message: [{ type: "text", data: { text: message } }] }; - - const request = { - action, - params, - echo: "test_send" - }; - - console.log(`📤 Sending ${isGroup ? "group" : "private"} message to ${targetId}...`); - console.log(` Content: "${message}"`); - ws.send(JSON.stringify(request)); -}); - -ws.on("message", (data) => { - try { - const response = JSON.parse(data.toString()); - - if (response.echo === "test_send") { - if (response.status === "ok") { - console.log(`\n✅ Message sent successfully!`); - console.log(` Message ID: ${response.data?.message_id}`); - } else { - console.log(`\n❌ Failed to send message:`); - console.log(` Error: ${response.message || response.wording || "Unknown error"}`); - console.log(` Retcode: ${response.retcode}`); - } - - setTimeout(() => { - ws.close(); - }, 500); - } - } catch { - // Ignore parse errors - } -}); - -ws.on("error", (error) => { - console.error("\n❌ Connection error:", error.message); - process.exit(1); -}); - -ws.on("close", () => { - console.log("\n👋 Done!"); - process.exit(0); -}); - -setTimeout(() => { - console.log("\n⏱️ Timeout"); - ws.close(); -}, 10000); diff --git a/src/discord/targets.ts b/src/discord/targets.ts index 103f3ea0b..5ea6f5b1b 100644 --- a/src/discord/targets.ts +++ b/src/discord/targets.ts @@ -6,6 +6,7 @@ import { type MessagingTargetKind, type MessagingTargetParseOptions, } from "../channels/targets.js"; + import type { DirectoryConfigParams } from "../channels/plugins/directory-config.js"; import { listDiscordDirectoryPeersLive } from "./directory-live.js";