hyperclaw 4.0.1 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/dist/a2ui-protocol-CT_jDEU9.js +75 -0
- package/dist/agents-routing-683Q2JGp.js +129 -0
- package/dist/agents-routing-BpZBswBH.js +4 -0
- package/dist/api-keys-guide-Dq5Obbp4.js +149 -0
- package/dist/audit-BYxPlnTQ.js +248 -0
- package/dist/bounty-tools-C6LyzxM-.js +211 -0
- package/dist/browser-tools-CQBSbIuO.js +5 -0
- package/dist/browser-tools-YQmwRLLM.js +179 -0
- package/dist/claw-tasks-BRLUvFRD.js +80 -0
- package/dist/connector-3HnyH8fn.js +167 -0
- package/dist/connector-6PMZo5Ky.js +189 -0
- package/dist/connector-B6eoF3DD.js +181 -0
- package/dist/connector-B9tLG8UZ.js +196 -0
- package/dist/connector-BOlqjXWP.js +182 -0
- package/dist/connector-BP8zsbP8.js +189 -0
- package/dist/connector-BPoSevxp.js +286 -0
- package/dist/connector-BRHj773i.js +163 -0
- package/dist/connector-BToxU-jV.js +267 -0
- package/dist/connector-BliDVsJQ.js +239 -0
- package/dist/connector-Bv6s9oP7.js +88 -0
- package/dist/connector-By5wWGTR.js +343 -0
- package/dist/connector-C1BaFFgN.js +213 -0
- package/dist/connector-CRRWY5Wv.js +167 -0
- package/dist/connector-CXPQVGyI.js +85 -0
- package/dist/connector-Cdk1CXKi.js +194 -0
- package/dist/connector-CwlgFgjx.js +181 -0
- package/dist/connector-DFchk6l7.js +178 -0
- package/dist/connector-DKw7tRAy.js +192 -0
- package/dist/connector-DRv1ahC_.js +2 -2
- package/dist/connector-DU63KW94.js +165 -0
- package/dist/connector-Dbvb1Cj9.js +280 -0
- package/dist/connector-DcZdQcgR.js +173 -0
- package/dist/connector-DxKL8VvZ.js +182 -0
- package/dist/connector-T_YdZtzv.js +162 -0
- package/dist/connector-i4gOS9xL.js +154 -0
- package/dist/connector-rHXE1ZD2.js +167 -0
- package/dist/connector-wdUXChwa.js +172 -0
- package/dist/cost-tracker-pVE15Yq4.js +103 -0
- package/dist/credentials-store-BvnMPJwi.js +4 -0
- package/dist/credentials-store-sb-TRLwR.js +77 -0
- package/dist/cron-tasks-BvDFNyiE.js +82 -0
- package/dist/delivery-D5Z98EVq.js +95 -0
- package/dist/delivery-DCOXhXEO.js +5 -0
- package/dist/destructive-gate-m-dWqUFg.js +101 -0
- package/dist/developer-keys-JaJK3T27.js +127 -0
- package/dist/developer-keys-kyqmtWK3.js +8 -0
- package/dist/doctor-3oi89QIc.js +175 -0
- package/dist/doctor-Cf1XSfp9.js +4 -0
- package/dist/engine-B4eMiTgl.js +7 -0
- package/dist/engine-B8M7dYul.js +7 -0
- package/dist/engine-BhT-1M9W.js +256 -0
- package/dist/engine-D49jnSd_.js +256 -0
- package/dist/env-resolve-DWOQ45jG.js +9 -0
- package/dist/env-resolve-szSWl0UF.js +94 -0
- package/dist/extraction-tools-D3qDFBJ1.js +91 -0
- package/dist/extraction-tools-DLr_AEwq.js +5 -0
- package/dist/form_data-B_hIUrxU.js +8657 -0
- package/dist/gmail-watch-setup-Czt8rXaX.js +40 -0
- package/dist/heartbeat-engine-CRqfPcFM.js +83 -0
- package/dist/hub-DTsqe5Bt.js +6 -0
- package/dist/hub-FrPTA33j.js +515 -0
- package/dist/hyperclawbot-D9KCtc4P.js +480 -0
- package/dist/hyperclawbot-Dw27pJo4.js +480 -0
- package/dist/inference-CTWJeX9Q.js +922 -0
- package/dist/inference-ix607p7k.js +6 -0
- package/dist/knowledge-graph-DqA-Fztl.js +131 -0
- package/dist/loader-CISCqBto.js +400 -0
- package/dist/loader-CYMQ8VOS.js +4 -0
- package/dist/logger-8tEtAd3y.js +83 -0
- package/dist/manager-CPjeRe-6.js +4 -0
- package/dist/manager-Cwzj7w5R.js +105 -0
- package/dist/manager-DLmZI-9R.js +6 -0
- package/dist/manager-DSGhn5i3.js +117 -0
- package/dist/manager-DgyF52mg.js +218 -0
- package/dist/manager-Dm8nrMFx.js +40 -0
- package/dist/mcp-B_9Ber63.js +139 -0
- package/dist/mcp-loader-DSM5UiFG.js +94 -0
- package/dist/mcp-loader-j5ZLLw5O.js +94 -0
- package/dist/memory-BI1kPkAN.js +4 -0
- package/dist/memory-BVFGkxxK.js +270 -0
- package/dist/memory-auto-Bc7euou4.js +306 -0
- package/dist/memory-auto-DPfbkMVt.js +5 -0
- package/dist/memory-integration-DZExqWr4.js +91 -0
- package/dist/moltbook-B6ZeGN5_.js +81 -0
- package/dist/node-pwL6O_KX.js +222 -0
- package/dist/nodes-registry-CsPm_-CJ.js +52 -0
- package/dist/oauth-flow-CpWlgvNB.js +150 -0
- package/dist/oauth-provider-BZb6qOw5.js +110 -0
- package/dist/observability-B43YvNQV.js +89 -0
- package/dist/onboard-Bd_wsYdi.js +4086 -0
- package/dist/onboard-CAN7x3me.js +3026 -0
- package/dist/onboard-DnegOHMh.js +4 -4
- package/dist/onboard-RYtDlYBw.js +9 -0
- package/dist/onboard-aTwlQs-4.js +9 -0
- package/dist/orchestrator-BSp2M5EU.js +189 -0
- package/dist/orchestrator-C7ko5tWa.js +6 -0
- package/dist/orchestrator-DfPkIx2Z.js +6 -0
- package/dist/orchestrator-NJQsmiBE.js +189 -0
- package/dist/pairing-DU0_J28n.js +87 -0
- package/dist/pairing-DWllbSbO.js +4 -0
- package/dist/pc-access-Ly-uA8mn.js +8 -0
- package/dist/pc-access-NxBvTrRj.js +819 -0
- package/dist/pending-approval-DIHvwwWS.js +22 -0
- package/dist/puppeteer-2o3QOwAy.js +2 -2
- package/dist/puppeteer-BYTMp3BI.js +2 -2
- package/dist/puppeteer-DQ45qwWk.js +2 -2
- package/dist/reminders-store-D79qdfN0.js +58 -0
- package/dist/renderer-pqlDRKbH.js +225 -0
- package/dist/rules-BooT_qFP.js +103 -0
- package/dist/run-main.js +289 -1031
- package/dist/runner-D1rjuMTJ.js +810 -0
- package/dist/sdk/index.js +2 -2
- package/dist/sdk/index.mjs +2 -2
- package/dist/security-C-5URby1.js +73 -0
- package/dist/security-_xve79aq.js +4 -0
- package/dist/server-0kgyELx4.js +1047 -0
- package/dist/server-BIuTobTC.js +4 -0
- package/dist/server-BRlCEjyT.js +1047 -0
- package/dist/server-CCI1hv45.js +2 -2
- package/dist/server-DU9POoWc.js +4 -0
- package/dist/session-store-CujxByI6.js +113 -0
- package/dist/session-store-qpJUg2M1.js +5 -0
- package/dist/sessions-tools-CB2qbwIk.js +5 -0
- package/dist/sessions-tools-DHMaTZIs.js +95 -0
- package/dist/skill-loader-BkceKkIg.js +7 -0
- package/dist/skill-loader-DhgIwK4J.js +159 -0
- package/dist/skill-runtime--LqxWrp5.js +102 -0
- package/dist/skill-runtime-C5l0Tgt-.js +5 -0
- package/dist/skill-runtime-DsXK_HYG.js +102 -0
- package/dist/skill-runtime-IVTiqrMR.js +5 -0
- package/dist/src-BEVLgaF1.js +63 -0
- package/dist/src-Bgu_OxTQ.js +458 -0
- package/dist/src-Bq-oKt7Z.js +458 -0
- package/dist/src-DWCUhnD4.js +20 -0
- package/dist/src-cfRTjFef.js +63 -0
- package/dist/sub-agent-tools-BD9DF8_g.js +39 -0
- package/dist/sub-agent-tools-V7b3T9_s.js +39 -0
- package/dist/tool-policy-DNvNRnve.js +189 -0
- package/dist/tts-elevenlabs-BUOGKL-k.js +61 -0
- package/dist/update-check-BD4qH7Am.js +81 -0
- package/dist/vision-DRq-f-Dj.js +121 -0
- package/dist/vision-tools-CFZEpQKm.js +5 -0
- package/dist/vision-tools-CQnBI9aa.js +51 -0
- package/dist/voice-transcription-CgWq54hn.js +138 -0
- package/dist/website-watch-tools-Bk_TnwuE.js +5 -0
- package/dist/website-watch-tools-DraMPxdl.js +139 -0
- package/package.json +1 -1
|
@@ -0,0 +1,480 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-jS-bbMI5.js');
|
|
2
|
+
require('./paths-AIyBxIzm.js');
|
|
3
|
+
require('./browser-tools-YQmwRLLM.js');
|
|
4
|
+
require('./src-DWCUhnD4.js');
|
|
5
|
+
require('./engine-BhT-1M9W.js');
|
|
6
|
+
require('./extraction-tools-D3qDFBJ1.js');
|
|
7
|
+
require('./inference-CTWJeX9Q.js');
|
|
8
|
+
require('./memory-auto-Bc7euou4.js');
|
|
9
|
+
require('./orchestrator-BSp2M5EU.js');
|
|
10
|
+
require('./pc-access-NxBvTrRj.js');
|
|
11
|
+
require('./session-store-CujxByI6.js');
|
|
12
|
+
require('./sessions-tools-DHMaTZIs.js');
|
|
13
|
+
require('./skill-loader-DhgIwK4J.js');
|
|
14
|
+
require('./skill-runtime--LqxWrp5.js');
|
|
15
|
+
require('./vision-tools-CQnBI9aa.js');
|
|
16
|
+
require('./website-watch-tools-DraMPxdl.js');
|
|
17
|
+
const require_src$1 = require('./src-Bgu_OxTQ.js');
|
|
18
|
+
const chalk = require_chunk.__toESM(require("chalk"));
|
|
19
|
+
const fs_extra = require_chunk.__toESM(require("fs-extra"));
|
|
20
|
+
const path = require_chunk.__toESM(require("path"));
|
|
21
|
+
const os = require_chunk.__toESM(require("os"));
|
|
22
|
+
const axios = require_chunk.__toESM(require("axios"));
|
|
23
|
+
|
|
24
|
+
//#region src/bot/hyperclawbot.ts
|
|
25
|
+
const HC_DIR = path.default.join(os.default.homedir(), ".hyperclaw");
|
|
26
|
+
const BOT_CONFIG_FILE = path.default.join(HC_DIR, "hyperclawbot.json");
|
|
27
|
+
const BOT_PID_FILE = path.default.join(HC_DIR, "hyperclawbot.pid");
|
|
28
|
+
async function getGatewayStatus(gatewayUrl, token) {
|
|
29
|
+
try {
|
|
30
|
+
const headers = token ? { Authorization: `Bearer ${token}` } : {};
|
|
31
|
+
const res = await axios.default.get(`${gatewayUrl}/api/status`, {
|
|
32
|
+
headers,
|
|
33
|
+
timeout: 3e3
|
|
34
|
+
});
|
|
35
|
+
const d = res.data;
|
|
36
|
+
return `⚡ *Gateway Status*\n\n🟢 Running on port ${d.port}\n🦅 Agent: ${d.agentName || "unknown"}\n📱 Channels: ${(d.channels || []).join(", ") || "none"}\n👥 Sessions: ${d.sessions || 0}\n⏱ Uptime: ${d.uptime || "?"}\n🧠 Model: ${d.model || "unknown"}`;
|
|
37
|
+
} catch {
|
|
38
|
+
return "🔴 *Gateway Offline*\n\nStart with: `hyperclaw daemon start`";
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async function getLogSummary(n = 20) {
|
|
42
|
+
const logFile = path.default.join(HC_DIR, "logs", "hyperclaw.log");
|
|
43
|
+
if (!await fs_extra.default.pathExists(logFile)) return "📋 No logs yet.";
|
|
44
|
+
const content = await fs_extra.default.readFile(logFile, "utf8");
|
|
45
|
+
const lines = content.trim().split("\n").slice(-n);
|
|
46
|
+
const formatted = lines.map((line) => {
|
|
47
|
+
try {
|
|
48
|
+
const e = JSON.parse(line);
|
|
49
|
+
const level = e.level?.toUpperCase() || "INFO";
|
|
50
|
+
const icon = {
|
|
51
|
+
ERROR: "🔴",
|
|
52
|
+
WARN: "🟡",
|
|
53
|
+
INFO: "🔵",
|
|
54
|
+
DEBUG: "⚪"
|
|
55
|
+
}[level] || "⚪";
|
|
56
|
+
return `${icon} ${e.ts?.slice(11, 19) || ""} [${e.module || "?"}] ${e.message || ""}`;
|
|
57
|
+
} catch {
|
|
58
|
+
return line;
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
return `📋 *Last ${n} log entries*\n\n\`\`\`\n${formatted.join("\n").slice(0, 3500)}\n\`\`\``;
|
|
62
|
+
}
|
|
63
|
+
async function approveCode(channelId, code) {
|
|
64
|
+
try {
|
|
65
|
+
const { PairingStore } = await Promise.resolve().then(() => require("./pairing-DWllbSbO.js"));
|
|
66
|
+
const store = new PairingStore();
|
|
67
|
+
await store.approve(channelId, code);
|
|
68
|
+
return `✅ Approved pairing code *${code}* on *${channelId}*`;
|
|
69
|
+
} catch (e) {
|
|
70
|
+
return `❌ Failed: ${e.message}`;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
async function listChannels() {
|
|
74
|
+
try {
|
|
75
|
+
const cfg = await fs_extra.default.readJson(path.default.join(HC_DIR, "hyperclaw.json"));
|
|
76
|
+
const channels = Object.entries(cfg.channelConfigs || {}).map(([id]) => `• ${id}`).join("\n");
|
|
77
|
+
return `📱 *Active Channels*\n\n${channels || "(none configured)"}`;
|
|
78
|
+
} catch {
|
|
79
|
+
return "❌ Could not read config";
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
async function listHooks() {
|
|
83
|
+
try {
|
|
84
|
+
const { HookLoader } = await Promise.resolve().then(() => require("./loader-CYMQ8VOS.js"));
|
|
85
|
+
const loader = new HookLoader();
|
|
86
|
+
loader.loadState();
|
|
87
|
+
const hooks = loader.getHooks().map((h) => `${h.enabled && h.eligible ? "✅" : "⬜"} ${h.id} — ${h.trigger}`).join("\n");
|
|
88
|
+
return `🪝 *Hooks*\n\n${hooks}`;
|
|
89
|
+
} catch {
|
|
90
|
+
return "❌ Could not load hooks";
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
async function sendToAgent(message, gatewayUrl, gatewayToken, surface = "telegram") {
|
|
94
|
+
try {
|
|
95
|
+
const headers = gatewayToken ? { Authorization: `Bearer ${gatewayToken}` } : {};
|
|
96
|
+
const res = await axios.default.post(`${gatewayUrl}/api/chat`, {
|
|
97
|
+
message,
|
|
98
|
+
thinking: "none"
|
|
99
|
+
}, {
|
|
100
|
+
headers,
|
|
101
|
+
timeout: 3e4
|
|
102
|
+
});
|
|
103
|
+
const { formatAgentResponse } = (require_src$1.init_src(), require_chunk.__toCommonJS(require_src$1.src_exports));
|
|
104
|
+
return formatAgentResponse(res.data.response ?? "", surface);
|
|
105
|
+
} catch {
|
|
106
|
+
return "❌ Gateway unreachable — start with: `hyperclaw daemon start`";
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function parseCommand(text) {
|
|
110
|
+
const parts = text.trim().split(/\s+/);
|
|
111
|
+
const cmd = parts[0].replace("/", "").toLowerCase();
|
|
112
|
+
return {
|
|
113
|
+
cmd,
|
|
114
|
+
args: parts.slice(1)
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function getHelp(platform) {
|
|
118
|
+
const { getAgentHelp } = (require_src$1.init_src(), require_chunk.__toCommonJS(require_src$1.src_exports));
|
|
119
|
+
return getAgentHelp(platform === "discord" ? "discord" : "telegram");
|
|
120
|
+
}
|
|
121
|
+
var TelegramHyperClawBot = class {
|
|
122
|
+
config;
|
|
123
|
+
offset = 0;
|
|
124
|
+
running = false;
|
|
125
|
+
apiBase;
|
|
126
|
+
botUsername = "";
|
|
127
|
+
constructor(config) {
|
|
128
|
+
this.config = config;
|
|
129
|
+
this.apiBase = `https://api.telegram.org/bot${config.token}`;
|
|
130
|
+
}
|
|
131
|
+
async api(method, body) {
|
|
132
|
+
const res = await axios.default.post(`${this.apiBase}/${method}`, body, { timeout: 1e4 });
|
|
133
|
+
return res.data;
|
|
134
|
+
}
|
|
135
|
+
isAllowed(userId) {
|
|
136
|
+
if (this.config.allowedUsers.length === 0) return true;
|
|
137
|
+
return this.config.allowedUsers.includes(String(userId));
|
|
138
|
+
}
|
|
139
|
+
async sendMessage(chatId, text) {
|
|
140
|
+
await this.api("sendMessage", {
|
|
141
|
+
chat_id: chatId,
|
|
142
|
+
text: text.slice(0, 4096),
|
|
143
|
+
parse_mode: "Markdown"
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
async downloadAndTranscribeVoice(fileId) {
|
|
147
|
+
const fileRes = await this.api("getFile", { file_id: fileId });
|
|
148
|
+
const filePath = fileRes.result?.file_path;
|
|
149
|
+
if (!filePath) throw new Error("Could not get file path");
|
|
150
|
+
const url = `https://api.telegram.org/file/bot${this.config.token}/${filePath}`;
|
|
151
|
+
const res = await axios.default.get(url, { responseType: "arraybuffer" });
|
|
152
|
+
const buffer = Buffer.from(res.data);
|
|
153
|
+
const { transcribeVoiceNote } = await Promise.resolve().then(() => require("./voice-transcription-CgWq54hn.js"));
|
|
154
|
+
return transcribeVoiceNote(buffer);
|
|
155
|
+
}
|
|
156
|
+
shouldRespondInGroup(msg) {
|
|
157
|
+
const chatType = msg.chat.type || "";
|
|
158
|
+
if (chatType !== "group" && chatType !== "supergroup") return true;
|
|
159
|
+
if (msg.reply_to_message?.from?.is_bot) return true;
|
|
160
|
+
const mention = msg.entities?.find((e) => e.type === "mention" || e.type === "text_mention");
|
|
161
|
+
if (mention && msg.text) {
|
|
162
|
+
const mentioned = msg.text.slice(mention.offset, mention.offset + mention.length);
|
|
163
|
+
if (this.botUsername && mentioned.toLowerCase().includes(this.botUsername.toLowerCase())) return true;
|
|
164
|
+
}
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
async handleUpdate(update) {
|
|
168
|
+
const msg = update.message;
|
|
169
|
+
if (!msg) return;
|
|
170
|
+
const userId = msg.from?.id;
|
|
171
|
+
if (!userId || !this.isAllowed(userId)) {
|
|
172
|
+
await this.sendMessage(msg.chat.id, "🚫 Unauthorized");
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (!this.shouldRespondInGroup(msg)) return;
|
|
176
|
+
let text = msg.text || "";
|
|
177
|
+
let isFromVoice = false;
|
|
178
|
+
if (!text && msg.voice) try {
|
|
179
|
+
await this.sendMessage(msg.chat.id, "🎤 Transcribing...");
|
|
180
|
+
text = await this.downloadAndTranscribeVoice(msg.voice.file_id);
|
|
181
|
+
if (!text || text.startsWith("[")) {
|
|
182
|
+
await this.sendMessage(msg.chat.id, text || "❌ Transcription failed");
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
isFromVoice = true;
|
|
186
|
+
} catch (e) {
|
|
187
|
+
await this.sendMessage(msg.chat.id, `❌ Transcription failed: ${e.message}`);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
if (!text.trim()) return;
|
|
191
|
+
const { cmd, args } = isFromVoice && !text.startsWith("/") ? {
|
|
192
|
+
cmd: "agent",
|
|
193
|
+
args: text.trim().split(/\s+/)
|
|
194
|
+
} : parseCommand(text);
|
|
195
|
+
const { gatewayUrl, gatewayToken } = this.config;
|
|
196
|
+
let response = "";
|
|
197
|
+
switch (cmd) {
|
|
198
|
+
case "start":
|
|
199
|
+
case "help":
|
|
200
|
+
response = getHelp(this.config.platform);
|
|
201
|
+
break;
|
|
202
|
+
case "status":
|
|
203
|
+
response = await getGatewayStatus(gatewayUrl, gatewayToken);
|
|
204
|
+
break;
|
|
205
|
+
case "logs":
|
|
206
|
+
response = await getLogSummary(parseInt(args[0]) || 20);
|
|
207
|
+
break;
|
|
208
|
+
case "approve":
|
|
209
|
+
if (args.length < 2) {
|
|
210
|
+
response = "❌ Usage: /approve <channel> <code>";
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
response = await approveCode(args[0], args[1]);
|
|
214
|
+
break;
|
|
215
|
+
case "channels":
|
|
216
|
+
response = await listChannels();
|
|
217
|
+
break;
|
|
218
|
+
case "hook":
|
|
219
|
+
if (args[0] === "list" || !args[0]) {
|
|
220
|
+
response = await listHooks();
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
if ((args[0] === "on" || args[0] === "off") && args[1]) {
|
|
224
|
+
const { HookLoader } = await Promise.resolve().then(() => require("./loader-CYMQ8VOS.js"));
|
|
225
|
+
const loader = new HookLoader();
|
|
226
|
+
loader.loadState();
|
|
227
|
+
if (args[0] === "on") await loader.enable(args[1]);
|
|
228
|
+
else await loader.disable(args[1]);
|
|
229
|
+
response = `${args[0] === "on" ? "✅" : "⬜"} Hook ${args[0] === "on" ? "enabled" : "disabled"}: ${args[1]}`;
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
response = "❌ Usage: /hook list | /hook on <id> | /hook off <id>";
|
|
233
|
+
break;
|
|
234
|
+
case "restart":
|
|
235
|
+
response = "🔄 Restarting gateway...";
|
|
236
|
+
await this.sendMessage(msg.chat.id, response);
|
|
237
|
+
try {
|
|
238
|
+
const r = await axios.default.post(`${gatewayUrl}/api/remote/restart`, {}, {
|
|
239
|
+
headers: gatewayToken ? { Authorization: `Bearer ${gatewayToken}` } : {},
|
|
240
|
+
timeout: 5e3
|
|
241
|
+
});
|
|
242
|
+
response = (r.data?.restarted ? "✅ Gateway restarted" : r.data?.message) || "✅ Request accepted";
|
|
243
|
+
} catch {
|
|
244
|
+
response = "⚠️ Could not reach gateway to restart";
|
|
245
|
+
}
|
|
246
|
+
break;
|
|
247
|
+
case "agent":
|
|
248
|
+
if (!args.length) {
|
|
249
|
+
response = "❌ Usage: /agent <message>";
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
response = await sendToAgent(args.join(" "), gatewayUrl, gatewayToken, "telegram");
|
|
253
|
+
break;
|
|
254
|
+
case "secrets":
|
|
255
|
+
response = "🔍 Run locally: `hyperclaw secrets audit`";
|
|
256
|
+
break;
|
|
257
|
+
case "security":
|
|
258
|
+
response = "🔐 Run locally: `hyperclaw security audit --deep`";
|
|
259
|
+
break;
|
|
260
|
+
default: response = `❓ Unknown command: /${cmd}\n\nTry /help`;
|
|
261
|
+
}
|
|
262
|
+
await this.sendMessage(msg.chat.id, response);
|
|
263
|
+
}
|
|
264
|
+
async start() {
|
|
265
|
+
this.running = true;
|
|
266
|
+
try {
|
|
267
|
+
const me = await this.api("getMe");
|
|
268
|
+
this.botUsername = me.result?.username || "";
|
|
269
|
+
} catch {}
|
|
270
|
+
console.log(chalk.default.green("\n ✔ HyperClaw Bot (Telegram) started"));
|
|
271
|
+
console.log(chalk.default.gray(` Polling updates...\n Send /status to your bot to test.\n`));
|
|
272
|
+
while (this.running) try {
|
|
273
|
+
const result = await this.api("getUpdates", {
|
|
274
|
+
offset: this.offset,
|
|
275
|
+
timeout: 30,
|
|
276
|
+
allowed_updates: ["message"]
|
|
277
|
+
});
|
|
278
|
+
for (const update of result.result || []) {
|
|
279
|
+
this.offset = update.update_id + 1;
|
|
280
|
+
await this.handleUpdate(update).catch((e) => console.log(chalk.default.yellow(` ⚠ HyperClaw Bot error: ${e.message}`)));
|
|
281
|
+
}
|
|
282
|
+
} catch {
|
|
283
|
+
await new Promise((r) => setTimeout(r, 3e3));
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
stop() {
|
|
287
|
+
this.running = false;
|
|
288
|
+
}
|
|
289
|
+
};
|
|
290
|
+
var DiscordHyperClawBot = class {
|
|
291
|
+
config;
|
|
292
|
+
client;
|
|
293
|
+
running = false;
|
|
294
|
+
constructor(config) {
|
|
295
|
+
this.config = config;
|
|
296
|
+
this.client = null;
|
|
297
|
+
}
|
|
298
|
+
isAllowed(userId) {
|
|
299
|
+
if (this.config.allowedUsers.length === 0) return true;
|
|
300
|
+
return this.config.allowedUsers.includes(userId);
|
|
301
|
+
}
|
|
302
|
+
async handleCommand(cmd, args, reply) {
|
|
303
|
+
const { gatewayUrl, gatewayToken } = this.config;
|
|
304
|
+
let response = "";
|
|
305
|
+
switch (cmd) {
|
|
306
|
+
case "start":
|
|
307
|
+
case "help":
|
|
308
|
+
response = getHelp("discord");
|
|
309
|
+
break;
|
|
310
|
+
case "status":
|
|
311
|
+
response = (await getGatewayStatus(gatewayUrl, gatewayToken)).replace(/\*/g, "**");
|
|
312
|
+
break;
|
|
313
|
+
case "logs":
|
|
314
|
+
response = (await getLogSummary(parseInt(args[0]) || 20)).replace(/\*/g, "**");
|
|
315
|
+
break;
|
|
316
|
+
case "approve":
|
|
317
|
+
if (args.length < 2) {
|
|
318
|
+
response = "❌ Usage: /approve <channel> <code>";
|
|
319
|
+
break;
|
|
320
|
+
}
|
|
321
|
+
response = await approveCode(args[0], args[1]);
|
|
322
|
+
break;
|
|
323
|
+
case "channels":
|
|
324
|
+
response = (await listChannels()).replace(/\*/g, "**");
|
|
325
|
+
break;
|
|
326
|
+
case "hook":
|
|
327
|
+
if (args[0] === "list" || !args[0]) {
|
|
328
|
+
response = (await listHooks()).replace(/\*/g, "**");
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
if ((args[0] === "on" || args[0] === "off") && args[1]) {
|
|
332
|
+
const { HookLoader } = await Promise.resolve().then(() => require("./loader-CYMQ8VOS.js"));
|
|
333
|
+
const loader = new HookLoader();
|
|
334
|
+
loader.loadState();
|
|
335
|
+
if (args[0] === "on") await loader.enable(args[1]);
|
|
336
|
+
else await loader.disable(args[1]);
|
|
337
|
+
response = `${args[0] === "on" ? "✅" : "⬜"} Hook ${args[0] === "on" ? "enabled" : "disabled"}: ${args[1]}`;
|
|
338
|
+
break;
|
|
339
|
+
}
|
|
340
|
+
response = "❌ Usage: /hook list | /hook on <id> | /hook off <id>";
|
|
341
|
+
break;
|
|
342
|
+
case "restart":
|
|
343
|
+
await reply("🔄 Restarting gateway...");
|
|
344
|
+
try {
|
|
345
|
+
const r = await axios.default.post(`${gatewayUrl}/api/remote/restart`, {}, {
|
|
346
|
+
headers: gatewayToken ? { Authorization: `Bearer ${gatewayToken}` } : {},
|
|
347
|
+
timeout: 5e3
|
|
348
|
+
});
|
|
349
|
+
response = (r.data?.restarted ? "✅ Gateway restarted" : r.data?.message) || "✅ Request accepted";
|
|
350
|
+
} catch {
|
|
351
|
+
response = "⚠️ Could not reach gateway to restart";
|
|
352
|
+
}
|
|
353
|
+
break;
|
|
354
|
+
case "agent":
|
|
355
|
+
if (!args.length) {
|
|
356
|
+
response = "❌ Usage: /agent <message>";
|
|
357
|
+
break;
|
|
358
|
+
}
|
|
359
|
+
response = await sendToAgent(args.join(" "), gatewayUrl, gatewayToken, "discord");
|
|
360
|
+
break;
|
|
361
|
+
case "secrets":
|
|
362
|
+
response = "🔍 Run locally: `hyperclaw secrets audit`";
|
|
363
|
+
break;
|
|
364
|
+
case "security":
|
|
365
|
+
response = "🔐 Run locally: `hyperclaw security audit --deep`";
|
|
366
|
+
break;
|
|
367
|
+
default: response = `❓ Unknown command: /${cmd}\n\nTry /help`;
|
|
368
|
+
}
|
|
369
|
+
await reply(response.slice(0, 2e3));
|
|
370
|
+
}
|
|
371
|
+
async start() {
|
|
372
|
+
try {
|
|
373
|
+
const { Client, GatewayIntentBits } = await import("discord.js");
|
|
374
|
+
this.client = new Client({ intents: [
|
|
375
|
+
GatewayIntentBits.Guilds,
|
|
376
|
+
GatewayIntentBits.GuildMessages,
|
|
377
|
+
GatewayIntentBits.DirectMessages,
|
|
378
|
+
GatewayIntentBits.MessageContent
|
|
379
|
+
] });
|
|
380
|
+
this.running = true;
|
|
381
|
+
this.client.on("ready", () => {
|
|
382
|
+
console.log(chalk.default.green(`\n ✔ HyperClaw Bot (Discord) started as ${this.client.user?.tag}`));
|
|
383
|
+
console.log(chalk.default.gray(` Send /status to your bot to test.\n`));
|
|
384
|
+
});
|
|
385
|
+
this.client.on("messageCreate", async (msg) => {
|
|
386
|
+
if (msg.author?.bot) return;
|
|
387
|
+
const userId = msg.author?.id;
|
|
388
|
+
if (!userId || !this.isAllowed(userId)) {
|
|
389
|
+
await msg.reply("🚫 Unauthorized").catch(() => {});
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
const text = (msg.content || "").trim();
|
|
393
|
+
if (!text || !text.startsWith("/")) return;
|
|
394
|
+
const { cmd, args } = parseCommand(text);
|
|
395
|
+
const reply = async (t) => {
|
|
396
|
+
try {
|
|
397
|
+
await msg.reply({ content: t.slice(0, 2e3) });
|
|
398
|
+
} catch (e) {
|
|
399
|
+
console.log(chalk.default.yellow(` ⚠ Discord reply error: ${e.message}`));
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
await this.handleCommand(cmd, args, reply).catch((e) => console.log(chalk.default.yellow(` ⚠ HyperClaw Bot error: ${e.message}`)));
|
|
403
|
+
});
|
|
404
|
+
await this.client.login(this.config.token);
|
|
405
|
+
} catch (e) {
|
|
406
|
+
if (e.code === "MODULE_NOT_FOUND" || e.message?.includes("discord.js")) {
|
|
407
|
+
console.log(chalk.default.red("\n ✖ discord.js not installed. Run: npm install discord.js\n"));
|
|
408
|
+
process.exit(1);
|
|
409
|
+
}
|
|
410
|
+
throw e;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
stop() {
|
|
414
|
+
this.running = false;
|
|
415
|
+
if (this.client) {
|
|
416
|
+
this.client.destroy().catch(() => {});
|
|
417
|
+
this.client = null;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
async function loadBotConfig() {
|
|
422
|
+
try {
|
|
423
|
+
const cfg = await fs_extra.default.readJson(BOT_CONFIG_FILE);
|
|
424
|
+
return cfg;
|
|
425
|
+
} catch {
|
|
426
|
+
try {
|
|
427
|
+
for (const p of [path.default.join(HC_DIR, "hyperclaw-bot.json"), path.default.join(HC_DIR, "bot-config.json")]) if (await fs_extra.default.pathExists(p)) return await fs_extra.default.readJson(p);
|
|
428
|
+
} catch {}
|
|
429
|
+
return null;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
async function saveBotConfig(config) {
|
|
433
|
+
await fs_extra.default.ensureDir(path.default.dirname(BOT_CONFIG_FILE));
|
|
434
|
+
await fs_extra.default.writeJson(BOT_CONFIG_FILE, config, { spaces: 2 });
|
|
435
|
+
await fs_extra.default.chmod(BOT_CONFIG_FILE, 384);
|
|
436
|
+
}
|
|
437
|
+
async function stopBotProcess() {
|
|
438
|
+
try {
|
|
439
|
+
if (!await fs_extra.default.pathExists(BOT_PID_FILE)) return false;
|
|
440
|
+
const pid = parseInt(await fs_extra.default.readFile(BOT_PID_FILE, "utf8"), 10);
|
|
441
|
+
if (isNaN(pid)) return false;
|
|
442
|
+
try {
|
|
443
|
+
process.kill(pid, "SIGTERM");
|
|
444
|
+
} catch {}
|
|
445
|
+
await fs_extra.default.remove(BOT_PID_FILE);
|
|
446
|
+
return true;
|
|
447
|
+
} catch {
|
|
448
|
+
return false;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
async function writeBotPid(pid) {
|
|
452
|
+
await fs_extra.default.ensureDir(path.default.dirname(BOT_PID_FILE));
|
|
453
|
+
await fs_extra.default.writeFile(BOT_PID_FILE, String(pid), "utf8");
|
|
454
|
+
}
|
|
455
|
+
async function showBotStatus() {
|
|
456
|
+
const cfg = await loadBotConfig();
|
|
457
|
+
console.log(chalk.default.bold.cyan("\n 🦅 HYPERCLAW BOT\n"));
|
|
458
|
+
if (!cfg || !cfg.enabled) {
|
|
459
|
+
console.log(chalk.default.gray(" HyperClaw Bot is not configured.\n"));
|
|
460
|
+
console.log(chalk.default.gray(" Setup: hyperclaw bot setup\n"));
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
console.log(` ${chalk.default.green("●")} ${chalk.default.white(cfg.platform === "telegram" ? "Telegram" : "Discord")} bot`);
|
|
464
|
+
console.log(` ${chalk.default.gray("Token:")} ${cfg.token.slice(0, 8)}...`);
|
|
465
|
+
console.log(` ${chalk.default.gray("Gateway:")} ${cfg.gatewayUrl}`);
|
|
466
|
+
console.log(` ${chalk.default.gray("Allowed users:")} ${cfg.allowedUsers.length === 0 ? "(anyone)" : cfg.allowedUsers.join(", ")}`);
|
|
467
|
+
console.log(` ${chalk.default.gray("Status:")} ${cfg.enabled ? chalk.default.green("enabled") : chalk.default.gray("disabled")}`);
|
|
468
|
+
console.log();
|
|
469
|
+
console.log(chalk.default.gray(" Commands: hyperclaw bot start | stop | setup"));
|
|
470
|
+
console.log();
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
//#endregion
|
|
474
|
+
exports.DiscordHyperClawBot = DiscordHyperClawBot;
|
|
475
|
+
exports.TelegramHyperClawBot = TelegramHyperClawBot;
|
|
476
|
+
exports.loadBotConfig = loadBotConfig;
|
|
477
|
+
exports.saveBotConfig = saveBotConfig;
|
|
478
|
+
exports.showBotStatus = showBotStatus;
|
|
479
|
+
exports.stopBotProcess = stopBotProcess;
|
|
480
|
+
exports.writeBotPid = writeBotPid;
|