0xkobold 0.2.0 → 0.3.0
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/HEARTBEAT.md +40 -58
- package/README.md +387 -337
- package/dist/package.json +4 -2
- package/dist/src/auth/device-auth.js +202 -0
- package/dist/src/auth/device-auth.js.map +1 -0
- package/dist/src/auth/index.js +3 -0
- package/dist/src/auth/index.js.map +1 -0
- package/dist/src/channels/index.js +8 -0
- package/dist/src/channels/index.js.map +1 -0
- package/dist/src/channels/slack/webhook.js +128 -0
- package/dist/src/channels/slack/webhook.js.map +1 -0
- package/dist/src/channels/telegram/bot.js +223 -0
- package/dist/src/channels/telegram/bot.js.map +1 -0
- package/dist/src/channels/whatsapp/integration.js +325 -0
- package/dist/src/channels/whatsapp/integration.js.map +1 -0
- package/dist/src/cli/commands/check.js +69 -0
- package/dist/src/cli/commands/check.js.map +1 -0
- package/dist/src/cli/commands/migrate.js +24 -0
- package/dist/src/cli/commands/migrate.js.map +1 -0
- package/dist/src/cli/commands/tailscale.js +81 -0
- package/dist/src/cli/commands/tailscale.js.map +1 -0
- package/dist/src/cli/commands/telegram.js +111 -0
- package/dist/src/cli/commands/telegram.js.map +1 -0
- package/dist/src/cli/commands/tui.js +40 -22
- package/dist/src/cli/commands/tui.js.map +1 -1
- package/dist/src/cli/commands/whatsapp.js +116 -0
- package/dist/src/cli/commands/whatsapp.js.map +1 -0
- package/dist/src/cli/program.js +20 -0
- package/dist/src/cli/program.js.map +1 -1
- package/dist/src/config/index.js +2 -9
- package/dist/src/config/index.js.map +1 -1
- package/dist/src/config/manager.js +222 -0
- package/dist/src/config/manager.js.map +1 -0
- package/dist/src/documents/index.js +3 -0
- package/dist/src/documents/index.js.map +1 -0
- package/dist/src/documents/pdf.js +168 -0
- package/dist/src/documents/pdf.js.map +1 -0
- package/dist/src/gateway/client.js +318 -0
- package/dist/src/gateway/client.js.map +1 -0
- package/dist/src/infra/index.js +3 -0
- package/dist/src/infra/index.js.map +1 -0
- package/dist/src/infra/tailscale.js +163 -0
- package/dist/src/infra/tailscale.js.map +1 -0
- package/dist/src/media/audio.js +130 -0
- package/dist/src/media/audio.js.map +1 -0
- package/dist/src/media/index.js +4 -0
- package/dist/src/media/index.js.map +1 -0
- package/dist/src/media/vision.js +131 -0
- package/dist/src/media/vision.js.map +1 -0
- package/dist/src/migration/openclaw.js +498 -0
- package/dist/src/migration/openclaw.js.map +1 -0
- package/dist/src/sandbox/docker-runner.js +228 -0
- package/dist/src/sandbox/docker-runner.js.map +1 -0
- package/dist/src/sandbox/index.js +3 -0
- package/dist/src/sandbox/index.js.map +1 -0
- package/dist/src/skills/builtin/duplicate-detector.js +469 -0
- package/dist/src/skills/builtin/duplicate-detector.js.map +1 -0
- package/dist/src/skills/index.js +2 -0
- package/dist/src/skills/index.js.map +1 -1
- package/package.json +4 -2
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WhatsApp Integration - v0.3.0
|
|
3
|
+
*
|
|
4
|
+
* Real WhatsApp channel using Baileys library.
|
|
5
|
+
* Part of "The Gap Closer" - matching OpenClaw's multi-channel support.
|
|
6
|
+
*/
|
|
7
|
+
import { makeWASocket, DisconnectReason, useMultiFileAuthState, fetchLatestBaileysVersion, makeCacheableSignalKeyStore, } from "@whiskeysockets/baileys";
|
|
8
|
+
import { EventEmitter } from "events";
|
|
9
|
+
import * as fs from "node:fs/promises";
|
|
10
|
+
import * as path from "node:path";
|
|
11
|
+
import { getRealGateway } from "../../gateway/index.js";
|
|
12
|
+
const DEFAULT_CONFIG = {
|
|
13
|
+
sessionPath: path.join(process.env.HOME || "~", ".0xkobold", "whatsapp-session"),
|
|
14
|
+
qrTimeout: 60000,
|
|
15
|
+
reconnectInterval: 5000,
|
|
16
|
+
markOnlineOnConnect: true,
|
|
17
|
+
defaultMessageDelay: 1000,
|
|
18
|
+
};
|
|
19
|
+
class WhatsAppIntegration extends EventEmitter {
|
|
20
|
+
config;
|
|
21
|
+
socket = null;
|
|
22
|
+
connected = false;
|
|
23
|
+
qrCode = null;
|
|
24
|
+
gatewayConnectionId;
|
|
25
|
+
reconnectTimer;
|
|
26
|
+
sendQueue = [];
|
|
27
|
+
constructor(config = {}) {
|
|
28
|
+
super();
|
|
29
|
+
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Start WhatsApp connection
|
|
33
|
+
*/
|
|
34
|
+
async start() {
|
|
35
|
+
if (this.connected)
|
|
36
|
+
return;
|
|
37
|
+
console.log("[WhatsApp] Starting connection...");
|
|
38
|
+
// Ensure session directory exists
|
|
39
|
+
await fs.mkdir(this.config.sessionPath, { recursive: true });
|
|
40
|
+
// Get latest Baileys version
|
|
41
|
+
const { version, isLatest } = await fetchLatestBaileysVersion();
|
|
42
|
+
console.log(`[WhatsApp] Using Baileys v${version.join(".")} (latest: ${isLatest})`);
|
|
43
|
+
// Load auth state
|
|
44
|
+
const { state, saveCreds } = await useMultiFileAuthState(this.config.sessionPath);
|
|
45
|
+
// Create socket
|
|
46
|
+
this.socket = makeWASocket({
|
|
47
|
+
version,
|
|
48
|
+
logger: { info: () => { }, error: () => { }, debug: () => { }, warn: () => { } },
|
|
49
|
+
printQRInTerminal: true,
|
|
50
|
+
auth: {
|
|
51
|
+
creds: state.creds,
|
|
52
|
+
keys: makeCacheableSignalKeyStore(state.keys, { info: () => { } }),
|
|
53
|
+
},
|
|
54
|
+
markOnlineOnConnect: this.config.markOnlineOnConnect,
|
|
55
|
+
defaultQueryTimeoutMs: 60000,
|
|
56
|
+
});
|
|
57
|
+
// Handle connection updates
|
|
58
|
+
this.socket.ev.on("connection.update", async (update) => {
|
|
59
|
+
const { connection, lastDisconnect, qr } = update;
|
|
60
|
+
// QR code for pairing
|
|
61
|
+
if (qr) {
|
|
62
|
+
this.qrCode = qr;
|
|
63
|
+
console.log("[WhatsApp] QR Code generated - scan with WhatsApp app");
|
|
64
|
+
this.emit("qr", qr);
|
|
65
|
+
}
|
|
66
|
+
// Connection established
|
|
67
|
+
if (connection === "open") {
|
|
68
|
+
this.connected = true;
|
|
69
|
+
this.qrCode = null;
|
|
70
|
+
console.log("[WhatsApp] ✅ Connected successfully");
|
|
71
|
+
// Register with gateway
|
|
72
|
+
this.registerWithGateway();
|
|
73
|
+
// Process queued messages
|
|
74
|
+
this.processSendQueue();
|
|
75
|
+
this.emit("connected", { user: this.socket?.user });
|
|
76
|
+
}
|
|
77
|
+
// Connection closed
|
|
78
|
+
if (connection === "close") {
|
|
79
|
+
this.connected = false;
|
|
80
|
+
this.unregisterFromGateway();
|
|
81
|
+
const shouldReconnect = lastDisconnect?.error?.output?.statusCode !== DisconnectReason.loggedOut;
|
|
82
|
+
console.log(`[WhatsApp] Disconnected. Reconnect: ${shouldReconnect}`);
|
|
83
|
+
this.emit("disconnected", { shouldReconnect });
|
|
84
|
+
if (shouldReconnect) {
|
|
85
|
+
this.scheduleReconnect();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
// Handle credentials update
|
|
90
|
+
this.socket.ev.on("creds.update", saveCreds);
|
|
91
|
+
// Handle messages
|
|
92
|
+
this.socket.ev.on("messages.upsert", async (event) => {
|
|
93
|
+
for (const msg of event.messages) {
|
|
94
|
+
if (msg.key.fromMe)
|
|
95
|
+
continue; // Skip own messages
|
|
96
|
+
await this.handleIncomingMessage(msg);
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
// Handle group events
|
|
100
|
+
this.socket.ev.on("groups.upsert", (groups) => {
|
|
101
|
+
console.log("[WhatsApp] Groups updated:", groups.length);
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Stop WhatsApp connection
|
|
106
|
+
*/
|
|
107
|
+
async stop() {
|
|
108
|
+
console.log("[WhatsApp] Stopping...");
|
|
109
|
+
if (this.reconnectTimer) {
|
|
110
|
+
clearTimeout(this.reconnectTimer);
|
|
111
|
+
}
|
|
112
|
+
this.unregisterFromGateway();
|
|
113
|
+
if (this.socket) {
|
|
114
|
+
await this.socket.logout();
|
|
115
|
+
this.socket = null;
|
|
116
|
+
}
|
|
117
|
+
this.connected = false;
|
|
118
|
+
console.log("[WhatsApp] Stopped");
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Send text message
|
|
122
|
+
*/
|
|
123
|
+
async sendText(to, text) {
|
|
124
|
+
const jid = this.formatJid(to);
|
|
125
|
+
return new Promise((resolve, reject) => {
|
|
126
|
+
if (!this.connected || !this.socket) {
|
|
127
|
+
// Queue for later
|
|
128
|
+
this.sendQueue.push({
|
|
129
|
+
to: jid,
|
|
130
|
+
message: { text },
|
|
131
|
+
resolve,
|
|
132
|
+
});
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
this.socket.sendMessage(jid, { text })
|
|
136
|
+
.then(resolve)
|
|
137
|
+
.catch(reject);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Send typing indicator
|
|
142
|
+
*/
|
|
143
|
+
async sendTyping(to) {
|
|
144
|
+
if (!this.connected || !this.socket)
|
|
145
|
+
return;
|
|
146
|
+
const jid = this.formatJid(to);
|
|
147
|
+
await this.socket.sendPresenceUpdate("composing", jid);
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Send image
|
|
151
|
+
*/
|
|
152
|
+
async sendImage(to, imagePath, caption) {
|
|
153
|
+
if (!this.connected || !this.socket) {
|
|
154
|
+
throw new Error("Not connected");
|
|
155
|
+
}
|
|
156
|
+
const jid = this.formatJid(to);
|
|
157
|
+
const imageBuffer = await fs.readFile(imagePath);
|
|
158
|
+
return this.socket.sendMessage(jid, {
|
|
159
|
+
image: imageBuffer,
|
|
160
|
+
caption,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get groups
|
|
165
|
+
*/
|
|
166
|
+
async getGroups() {
|
|
167
|
+
if (!this.connected || !this.socket) {
|
|
168
|
+
throw new Error("Not connected");
|
|
169
|
+
}
|
|
170
|
+
const groups = await this.socket.groupFetchAllParticipating();
|
|
171
|
+
return Object.keys(groups);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Handle incoming message
|
|
175
|
+
*/
|
|
176
|
+
async handleIncomingMessage(msg) {
|
|
177
|
+
const from = msg.key.remoteJid || "";
|
|
178
|
+
const isGroup = from.endsWith("@g.us");
|
|
179
|
+
// Extract message body
|
|
180
|
+
let body = "";
|
|
181
|
+
let type = "text";
|
|
182
|
+
if (msg.message?.conversation) {
|
|
183
|
+
body = msg.message.conversation;
|
|
184
|
+
}
|
|
185
|
+
else if (msg.message?.extendedTextMessage?.text) {
|
|
186
|
+
body = msg.message.extendedTextMessage.text;
|
|
187
|
+
}
|
|
188
|
+
else if (msg.message?.imageMessage) {
|
|
189
|
+
body = msg.message.imageMessage.caption || "";
|
|
190
|
+
type = "image";
|
|
191
|
+
}
|
|
192
|
+
else if (msg.message?.videoMessage) {
|
|
193
|
+
body = msg.message.videoMessage.caption || "";
|
|
194
|
+
type = "video";
|
|
195
|
+
}
|
|
196
|
+
const message = {
|
|
197
|
+
id: msg.key.id || "",
|
|
198
|
+
from,
|
|
199
|
+
fromMe: msg.key.fromMe || false,
|
|
200
|
+
body,
|
|
201
|
+
type,
|
|
202
|
+
timestamp: msg.messageTimestamp ? Number(msg.messageTimestamp) * 1000 : Date.now(),
|
|
203
|
+
isGroup,
|
|
204
|
+
groupName: isGroup ? await this.getGroupName(from) : undefined,
|
|
205
|
+
senderName: msg.pushName,
|
|
206
|
+
};
|
|
207
|
+
console.log(`[WhatsApp] Message from ${isGroup ? "group" : "user"}: ${body.slice(0, 50)}...`);
|
|
208
|
+
// Forward to gateway
|
|
209
|
+
this.forwardToGateway(message);
|
|
210
|
+
this.emit("message", message);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Forward to gateway
|
|
214
|
+
*/
|
|
215
|
+
forwardToGateway(message) {
|
|
216
|
+
const gateway = getRealGateway();
|
|
217
|
+
gateway.emit("message", {
|
|
218
|
+
connection: {
|
|
219
|
+
id: this.gatewayConnectionId,
|
|
220
|
+
type: "whatsapp",
|
|
221
|
+
channel: message.isGroup ? "group" : "dm",
|
|
222
|
+
user: message.from,
|
|
223
|
+
},
|
|
224
|
+
data: {
|
|
225
|
+
type: "chat",
|
|
226
|
+
id: message.id,
|
|
227
|
+
payload: message,
|
|
228
|
+
timestamp: message.timestamp,
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Register with gateway
|
|
234
|
+
*/
|
|
235
|
+
registerWithGateway() {
|
|
236
|
+
const gateway = getRealGateway();
|
|
237
|
+
this.gatewayConnectionId = gateway.registerConnection({
|
|
238
|
+
type: "whatsapp",
|
|
239
|
+
channel: "whatsapp",
|
|
240
|
+
user: this.socket?.user?.id,
|
|
241
|
+
});
|
|
242
|
+
// Listen for gateway messages to send to WhatsApp
|
|
243
|
+
gateway.on("message", (event) => {
|
|
244
|
+
if (event.type === "whatsapp") {
|
|
245
|
+
const data = event.message;
|
|
246
|
+
this.sendText(data.to, data.text).catch(console.error);
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Unregister from gateway
|
|
252
|
+
*/
|
|
253
|
+
unregisterFromGateway() {
|
|
254
|
+
if (this.gatewayConnectionId) {
|
|
255
|
+
const gateway = getRealGateway();
|
|
256
|
+
gateway.removeConnection(this.gatewayConnectionId);
|
|
257
|
+
this.gatewayConnectionId = undefined;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Get group name
|
|
262
|
+
*/
|
|
263
|
+
async getGroupName(jid) {
|
|
264
|
+
if (!this.socket)
|
|
265
|
+
return undefined;
|
|
266
|
+
try {
|
|
267
|
+
const metadata = await this.socket.groupMetadata(jid);
|
|
268
|
+
return metadata.subject;
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
return undefined;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Format JID
|
|
276
|
+
*/
|
|
277
|
+
formatJid(input) {
|
|
278
|
+
if (input.includes("@"))
|
|
279
|
+
return input;
|
|
280
|
+
return `${input.replace(/\D/g, "")}@s.whatsapp.net`;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Process queued messages
|
|
284
|
+
*/
|
|
285
|
+
processSendQueue() {
|
|
286
|
+
while (this.sendQueue.length > 0 && this.connected) {
|
|
287
|
+
const item = this.sendQueue.shift();
|
|
288
|
+
if (item) {
|
|
289
|
+
this.socket?.sendMessage(item.to, item.message)
|
|
290
|
+
.then(item.resolve)
|
|
291
|
+
.catch(console.error);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Schedule reconnect
|
|
297
|
+
*/
|
|
298
|
+
scheduleReconnect() {
|
|
299
|
+
this.reconnectTimer = setTimeout(async () => {
|
|
300
|
+
console.log("[WhatsApp] Reconnecting...");
|
|
301
|
+
await this.start();
|
|
302
|
+
}, this.config.reconnectInterval);
|
|
303
|
+
}
|
|
304
|
+
getStatus() {
|
|
305
|
+
return {
|
|
306
|
+
connected: this.connected,
|
|
307
|
+
qr: this.qrCode,
|
|
308
|
+
user: this.socket?.user?.id,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
// Singleton
|
|
313
|
+
let instance = null;
|
|
314
|
+
export function getWhatsAppIntegration(config) {
|
|
315
|
+
if (!instance) {
|
|
316
|
+
instance = new WhatsAppIntegration(config);
|
|
317
|
+
}
|
|
318
|
+
return instance;
|
|
319
|
+
}
|
|
320
|
+
export function resetWhatsAppIntegration() {
|
|
321
|
+
instance?.stop();
|
|
322
|
+
instance = null;
|
|
323
|
+
}
|
|
324
|
+
export default WhatsAppIntegration;
|
|
325
|
+
//# sourceMappingURL=integration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"integration.js","sourceRoot":"","sources":["../../../../src/channels/whatsapp/integration.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check Command - v0.3.0
|
|
3
|
+
*
|
|
4
|
+
* Check for duplicate implementations before adding new code.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
import { getDuplicateDetector } from "../../skills/index.js";
|
|
8
|
+
export const checkCommand = new Command("check")
|
|
9
|
+
.description("Check for existing implementations before adding new code")
|
|
10
|
+
.argument("<description>", "Description of what you want to add")
|
|
11
|
+
.option("-f, --function <name>", "Check for function")
|
|
12
|
+
.option("-c, --class <name>", "Check for class")
|
|
13
|
+
.option("-s, --signature <signature>", "Function signature to compare")
|
|
14
|
+
.option("--similarity <threshold>", "Similarity threshold (0.0-1.0)", "0.7")
|
|
15
|
+
.option("--max-results <n>", "Max results to show", "5")
|
|
16
|
+
.action(async (description, options) => {
|
|
17
|
+
console.log("🔍 Checking for existing implementations...\n");
|
|
18
|
+
const detector = getDuplicateDetector({
|
|
19
|
+
scanPaths: ["src", "lib"],
|
|
20
|
+
similarityThreshold: parseFloat(options.similarity),
|
|
21
|
+
maxResults: parseInt(options.maxResults),
|
|
22
|
+
excludePatterns: ["node_modules", ".git", "test", "*.test.ts"],
|
|
23
|
+
});
|
|
24
|
+
let result;
|
|
25
|
+
if (options.function) {
|
|
26
|
+
console.log(`Checking for function: ${options.function}`);
|
|
27
|
+
result = await detector.checkFunction(options.function, options.signature || "");
|
|
28
|
+
}
|
|
29
|
+
else if (options.class) {
|
|
30
|
+
console.log(`Checking for class: ${options.class}`);
|
|
31
|
+
const methods = options.signature
|
|
32
|
+
? options.signature.split(",").map((m) => m.trim())
|
|
33
|
+
: undefined;
|
|
34
|
+
result = await detector.checkClass(options.class, methods);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.log(`Checking: ${description}`);
|
|
38
|
+
result = await detector.check(description);
|
|
39
|
+
}
|
|
40
|
+
console.log("\n" + "=".repeat(60));
|
|
41
|
+
console.log("RESULTS");
|
|
42
|
+
console.log("=".repeat(60));
|
|
43
|
+
if (result.exists) {
|
|
44
|
+
console.log(`\n⚠️ EXISTING IMPLEMENTATION FOUND`);
|
|
45
|
+
console.log(` Confidence: ${Math.round(result.confidence * 100)}%\n`);
|
|
46
|
+
}
|
|
47
|
+
else if (result.matches.length > 0) {
|
|
48
|
+
console.log(`\n⚡ SIMILAR IMPLEMENTATIONS FOUND`);
|
|
49
|
+
console.log(` Best match: ${Math.round(result.confidence * 100)}%\n`);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
console.log(`\n✅ NO EXISTING IMPLEMENTATION FOUND`);
|
|
53
|
+
console.log(` Safe to proceed with implementation.\n`);
|
|
54
|
+
}
|
|
55
|
+
if (result.matches.length > 0) {
|
|
56
|
+
console.log("Similar files:");
|
|
57
|
+
result.matches.forEach((match, i) => {
|
|
58
|
+
console.log(` ${i + 1}. ${match.file}:${match.line} (${Math.round(match.similarity * 100)}%)`);
|
|
59
|
+
console.log(` ${match.snippet.slice(0, 60)}...`);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
console.log("\n" + "=".repeat(60));
|
|
63
|
+
console.log("SUGGESTION");
|
|
64
|
+
console.log("=".repeat(60));
|
|
65
|
+
console.log(result.suggestion);
|
|
66
|
+
// Return exit code
|
|
67
|
+
process.exit(result.exists && result.confidence > 0.9 ? 1 : 0);
|
|
68
|
+
});
|
|
69
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../../../src/cli/commands/check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migrate Command - v0.3.0
|
|
3
|
+
*
|
|
4
|
+
* Migrate from OpenClaw to 0xKobold
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
import { runMigration } from "../../migration/openclaw.js";
|
|
8
|
+
export const migrateCommand = new Command("migrate")
|
|
9
|
+
.description("Migrate from OpenClaw (koclaw) to 0xKobold")
|
|
10
|
+
.option("-s, --source <path>", "OpenClaw source directory", "~/.openclaw")
|
|
11
|
+
.option("-t, --target <path>", "0xKobold target directory", "~/.0xkobold")
|
|
12
|
+
.option("--dry-run", "Preview changes without applying", true)
|
|
13
|
+
.option("--live", "Apply changes (default is dry-run)", false)
|
|
14
|
+
.option("-f, --force", "Force migration (skip dry-run)", false)
|
|
15
|
+
.action(async (options) => {
|
|
16
|
+
const dryRun = !options.live && !options.force;
|
|
17
|
+
await runMigration({
|
|
18
|
+
source: options.source,
|
|
19
|
+
target: options.target,
|
|
20
|
+
dryRun,
|
|
21
|
+
force: options.force,
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../../../../src/cli/commands/migrate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,MAAM,CAAC,MAAM,cAAc,GAAG,IAAI,OAAO,CAAC,SAAS,CAAC;KACjD,WAAW,CAAC,4CAA4C,CAAC;KACzD,MAAM,CAAC,qBAAqB,EAAE,2BAA2B,EAAE,aAAa,CAAC;KACzE,MAAM,CAAC,qBAAqB,EAAE,2BAA2B,EAAE,aAAa,CAAC;KACzE,MAAM,CAAC,WAAW,EAAE,kCAAkC,EAAE,IAAI,CAAC;KAC7D,MAAM,CAAC,QAAQ,EAAE,oCAAoC,EAAE,KAAK,CAAC;KAC7D,MAAM,CAAC,aAAa,EAAE,gCAAgC,EAAE,KAAK,CAAC;KAC9D,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC;IAE/C,MAAM,YAAY,CAAC;QACjB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,MAAM;QACN,KAAK,EAAE,OAAO,CAAC,KAAK;KACrB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tailscale CLI Command - v0.3.0
|
|
3
|
+
*
|
|
4
|
+
* Manage Tailscale VPN connection for secure remote access.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
import { getTailscaleIntegration } from "../../infra/index.js";
|
|
8
|
+
export function createTailscaleCommand() {
|
|
9
|
+
const cmd = new Command("tailscale")
|
|
10
|
+
.description("Manage Tailscale VPN connection");
|
|
11
|
+
// Status
|
|
12
|
+
cmd
|
|
13
|
+
.command("status")
|
|
14
|
+
.description("Check Tailscale status")
|
|
15
|
+
.action(async () => {
|
|
16
|
+
const ts = getTailscaleIntegration();
|
|
17
|
+
const status = await ts.getStatus();
|
|
18
|
+
console.log("🔍 Tailscale Status\n");
|
|
19
|
+
if (!status.installed) {
|
|
20
|
+
console.log("❌ Tailscale not installed");
|
|
21
|
+
console.log(" Install: https://tailscale.com/download");
|
|
22
|
+
console.log(" macOS: brew install tailscale");
|
|
23
|
+
console.log(" Linux: curl -fsSL https://tailscale.com/install.sh | sh");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
console.log(`✅ Tailscale installed`);
|
|
27
|
+
console.log(` Running: ${status.running ? "✅" : "❌"}`);
|
|
28
|
+
console.log(` Connected: ${status.connected ? "✅" : "❌"}`);
|
|
29
|
+
if (status.myIP) {
|
|
30
|
+
console.log(` IP: ${status.myIP}`);
|
|
31
|
+
// Show gateway URL
|
|
32
|
+
const url = await ts.getGatewayURL();
|
|
33
|
+
if (url) {
|
|
34
|
+
console.log(`\n🌐 Gateway URL: ${url}`);
|
|
35
|
+
console.log(` Use: 0xkobold tui --local --remote ${url}`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
// Start
|
|
40
|
+
cmd
|
|
41
|
+
.command("start")
|
|
42
|
+
.description("Start Tailscale daemon")
|
|
43
|
+
.action(async () => {
|
|
44
|
+
const ts = getTailscaleIntegration();
|
|
45
|
+
ts.on("ready", ({ ip }) => {
|
|
46
|
+
console.log(`✅ Tailscale ready! IP: ${ip}`);
|
|
47
|
+
});
|
|
48
|
+
const success = await ts.start();
|
|
49
|
+
if (!success) {
|
|
50
|
+
console.log("\n⚠️ Manual start required:");
|
|
51
|
+
console.log(" sudo tailscale up");
|
|
52
|
+
console.log("\n Or use Tailscale GUI app");
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
// Stop
|
|
56
|
+
cmd
|
|
57
|
+
.command("stop")
|
|
58
|
+
.description("Stop Tailscale")
|
|
59
|
+
.action(async () => {
|
|
60
|
+
console.log("🛑 Stopping Tailscale...");
|
|
61
|
+
console.log(" Run: sudo tailscale down");
|
|
62
|
+
});
|
|
63
|
+
// Get URL
|
|
64
|
+
cmd
|
|
65
|
+
.command("url")
|
|
66
|
+
.description("Get Tailscale gateway URL")
|
|
67
|
+
.option("-p, --port <port>", "Gateway port", "7777")
|
|
68
|
+
.action(async (options) => {
|
|
69
|
+
const ts = getTailscaleIntegration();
|
|
70
|
+
const url = await ts.getGatewayURL(parseInt(options.port));
|
|
71
|
+
if (url) {
|
|
72
|
+
console.log(url);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
console.error("❌ Tailscale not running or not installed");
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return cmd;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=tailscale.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tailscale.js","sourceRoot":"","sources":["../../../../src/cli/commands/tailscale.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telegram CLI Command - v0.3.0
|
|
3
|
+
*
|
|
4
|
+
* Manage Telegram bot integration.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
import { getTelegramIntegration, resetTelegramIntegration, } from "../../channels/index.js";
|
|
8
|
+
export function createTelegramCommand() {
|
|
9
|
+
const cmd = new Command("telegram")
|
|
10
|
+
.description("Manage Telegram integration");
|
|
11
|
+
// Start Telegram
|
|
12
|
+
cmd
|
|
13
|
+
.command("start")
|
|
14
|
+
.description("Start Telegram bot")
|
|
15
|
+
.option("--token <token>", "Bot token (or set TELEGRAM_BOT_TOKEN)")
|
|
16
|
+
.option("--mode <mode>", "Connection mode (polling|webhook)", "polling")
|
|
17
|
+
.action(async (options) => {
|
|
18
|
+
const token = options.token || process.env.TELEGRAM_BOT_TOKEN;
|
|
19
|
+
if (!token) {
|
|
20
|
+
console.error("❌ Telegram bot token required");
|
|
21
|
+
console.error("Set TELEGRAM_BOT_TOKEN or use --token");
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
console.log("📱 Starting Telegram bot...");
|
|
25
|
+
try {
|
|
26
|
+
const telegram = getTelegramIntegration({
|
|
27
|
+
token,
|
|
28
|
+
mode: options.mode,
|
|
29
|
+
});
|
|
30
|
+
telegram.on("connected", () => {
|
|
31
|
+
console.log("✅ Telegram bot connected!");
|
|
32
|
+
console.log("Mode:", options.mode);
|
|
33
|
+
});
|
|
34
|
+
telegram.on("message", (msg) => {
|
|
35
|
+
console.log(`📩 ${msg.isGroup ? "Group" : "DM"}: ${msg.text?.slice(0, 50)}...`);
|
|
36
|
+
});
|
|
37
|
+
telegram.on("error", (err) => {
|
|
38
|
+
console.error("❌ Telegram error:", err.message);
|
|
39
|
+
});
|
|
40
|
+
await telegram.start();
|
|
41
|
+
console.log("\n🔄 Telegram bot running...");
|
|
42
|
+
console.log("Press Ctrl+C to stop\n");
|
|
43
|
+
process.on("SIGINT", async () => {
|
|
44
|
+
console.log("\n🛑 Stopping Telegram...");
|
|
45
|
+
await resetTelegramIntegration();
|
|
46
|
+
console.log("✅ Telegram stopped");
|
|
47
|
+
process.exit(0);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
console.error("❌ Failed to start Telegram:", error);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
// Stop
|
|
56
|
+
cmd
|
|
57
|
+
.command("stop")
|
|
58
|
+
.description("Stop Telegram bot")
|
|
59
|
+
.action(async () => {
|
|
60
|
+
console.log("🛑 Stopping Telegram...");
|
|
61
|
+
await resetTelegramIntegration();
|
|
62
|
+
console.log("✅ Telegram stopped");
|
|
63
|
+
});
|
|
64
|
+
// Status
|
|
65
|
+
cmd
|
|
66
|
+
.command("status")
|
|
67
|
+
.description("Check Telegram status")
|
|
68
|
+
.action(() => {
|
|
69
|
+
try {
|
|
70
|
+
const telegram = getTelegramIntegration();
|
|
71
|
+
const status = telegram.getStatus();
|
|
72
|
+
if (status.connected) {
|
|
73
|
+
console.log("🟢 Telegram: Connected");
|
|
74
|
+
console.log(` Mode: ${status.mode}`);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
console.log("🔴 Telegram: Not running");
|
|
78
|
+
console.log(" Run: 0xkobold telegram start");
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
console.log("🔴 Telegram: Not initialized");
|
|
83
|
+
console.log(" Run: 0xkobold telegram start --token <token>");
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
// Send message
|
|
87
|
+
cmd
|
|
88
|
+
.command("send")
|
|
89
|
+
.description("Send test message")
|
|
90
|
+
.argument("<chatId>", "Chat ID (e.g., 123456789)")
|
|
91
|
+
.argument("<message>", "Message text")
|
|
92
|
+
.option("--token <token>", "Bot token")
|
|
93
|
+
.action(async (chatId, message, options) => {
|
|
94
|
+
try {
|
|
95
|
+
const token = options.token || process.env.TELEGRAM_BOT_TOKEN;
|
|
96
|
+
const telegram = getTelegramIntegration(token ? { token, mode: "polling" } : undefined);
|
|
97
|
+
if (!telegram.getStatus().connected) {
|
|
98
|
+
console.error("❌ Telegram not connected");
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
await telegram.sendMessage(chatId, message);
|
|
102
|
+
console.log("✅ Message sent");
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
console.error("❌ Failed to send:", error);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
return cmd;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=telegram.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../../../src/cli/commands/telegram.ts"],"names":[],"mappings":"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"}
|