openclaw-imclaw-ext 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/README.md +132 -0
- package/dist/accounts.d.ts +15 -0
- package/dist/accounts.d.ts.map +1 -0
- package/dist/accounts.js +23 -0
- package/dist/accounts.js.map +1 -0
- package/dist/channel.d.ts +67 -0
- package/dist/channel.d.ts.map +1 -0
- package/dist/channel.js +292 -0
- package/dist/channel.js.map +1 -0
- package/dist/contact-cache.d.ts +17 -0
- package/dist/contact-cache.d.ts.map +1 -0
- package/dist/contact-cache.js +26 -0
- package/dist/contact-cache.js.map +1 -0
- package/dist/daemon/cli.d.ts +3 -0
- package/dist/daemon/cli.d.ts.map +1 -0
- package/dist/daemon/cli.js +62 -0
- package/dist/daemon/cli.js.map +1 -0
- package/dist/daemon/config.d.ts +27 -0
- package/dist/daemon/config.d.ts.map +1 -0
- package/dist/daemon/config.js +63 -0
- package/dist/daemon/config.js.map +1 -0
- package/dist/daemon/daemon.d.ts +14 -0
- package/dist/daemon/daemon.d.ts.map +1 -0
- package/dist/daemon/daemon.js +121 -0
- package/dist/daemon/daemon.js.map +1 -0
- package/dist/daemon/local-api.d.ts +10 -0
- package/dist/daemon/local-api.d.ts.map +1 -0
- package/dist/daemon/local-api.js +139 -0
- package/dist/daemon/local-api.js.map +1 -0
- package/dist/imclaw-bridge.d.ts +49 -0
- package/dist/imclaw-bridge.d.ts.map +1 -0
- package/dist/imclaw-bridge.js +126 -0
- package/dist/imclaw-bridge.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/media-store.d.ts +4 -0
- package/dist/media-store.d.ts.map +1 -0
- package/dist/media-store.js +33 -0
- package/dist/media-store.js.map +1 -0
- package/dist/message-store.d.ts +32 -0
- package/dist/message-store.d.ts.map +1 -0
- package/dist/message-store.js +103 -0
- package/dist/message-store.js.map +1 -0
- package/dist/plugin-entry.d.ts +2 -0
- package/dist/plugin-entry.d.ts.map +1 -0
- package/dist/plugin-entry.js +12 -0
- package/dist/plugin-entry.js.map +1 -0
- package/dist/tinode-client.d.ts +43 -0
- package/dist/tinode-client.d.ts.map +1 -0
- package/dist/tinode-client.js +250 -0
- package/dist/tinode-client.js.map +1 -0
- package/openclaw.plugin.json +45 -0
- package/package.json +81 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { TinodeClient } from './tinode-client.js';
|
|
2
|
+
import { MessageStore } from './message-store.js';
|
|
3
|
+
import { ContactCache } from './contact-cache.js';
|
|
4
|
+
export class ImclawBridge {
|
|
5
|
+
client;
|
|
6
|
+
store;
|
|
7
|
+
cache;
|
|
8
|
+
config;
|
|
9
|
+
messageHandler = null;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.config = config;
|
|
12
|
+
const clientOptions = {
|
|
13
|
+
serverUrl: config.tinodeServerUrl,
|
|
14
|
+
username: config.tinodeUsername,
|
|
15
|
+
password: config.tinodePassword,
|
|
16
|
+
apiKey: config.tinodeApiKey,
|
|
17
|
+
};
|
|
18
|
+
this.client = new TinodeClient(clientOptions);
|
|
19
|
+
this.store = new MessageStore(config.dbPath);
|
|
20
|
+
this.cache = new ContactCache();
|
|
21
|
+
this.client.on('message', (msg) => {
|
|
22
|
+
// 1. Skip own messages (agent's own replies echoed back)
|
|
23
|
+
if (msg.from === this.client.getSelfUid())
|
|
24
|
+
return;
|
|
25
|
+
// 2. Check last known seq for dedup
|
|
26
|
+
const lastSeq = this.store.getLastSeq(msg.topic);
|
|
27
|
+
// 3. Persist locally (INSERT OR IGNORE — idempotent)
|
|
28
|
+
this.store.saveMessage(msg.topic, msg.from, msg.seqId, msg.content, msg.timestamp, config.clawId);
|
|
29
|
+
// 4. Only dispatch genuinely new messages
|
|
30
|
+
if (msg.seqId <= lastSeq)
|
|
31
|
+
return;
|
|
32
|
+
// 5. Skip stale messages (history replay older than 2 minutes)
|
|
33
|
+
const ageMs = Date.now() - msg.timestamp.getTime();
|
|
34
|
+
if (ageMs > 2 * 60 * 1000)
|
|
35
|
+
return;
|
|
36
|
+
// Dispatch to handler
|
|
37
|
+
if (this.messageHandler) {
|
|
38
|
+
const inbound = {
|
|
39
|
+
topic: msg.topic,
|
|
40
|
+
from: msg.from,
|
|
41
|
+
content: msg.content,
|
|
42
|
+
seqId: msg.seqId,
|
|
43
|
+
timestamp: msg.timestamp,
|
|
44
|
+
};
|
|
45
|
+
Promise.resolve(this.messageHandler(inbound)).catch((err) => {
|
|
46
|
+
console.error('Message handler error:', err);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
this.client.on('disconnected', () => {
|
|
51
|
+
console.log('IMClaw: disconnected from Tinode');
|
|
52
|
+
});
|
|
53
|
+
this.client.on('error', (err) => {
|
|
54
|
+
console.error('IMClaw: Tinode error:', err.message);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
onMessage(handler) {
|
|
58
|
+
this.messageHandler = handler;
|
|
59
|
+
}
|
|
60
|
+
async start() {
|
|
61
|
+
await this.client.connect();
|
|
62
|
+
console.log('IMClaw: connected to Tinode');
|
|
63
|
+
}
|
|
64
|
+
async sendMessage(topicName, content) {
|
|
65
|
+
return this.client.sendMessage(topicName, content);
|
|
66
|
+
}
|
|
67
|
+
async uploadFile(fileBuffer, filename, mime) {
|
|
68
|
+
if (!this.config.httpBaseUrl) {
|
|
69
|
+
throw new Error('httpBaseUrl is required for file uploads. Set it in ChannelConfig.');
|
|
70
|
+
}
|
|
71
|
+
const boundary = '----IMClawBoundary' + Date.now().toString(36);
|
|
72
|
+
const detectedMime = mime || 'application/octet-stream';
|
|
73
|
+
// Build multipart body manually to avoid extra dependencies
|
|
74
|
+
const header = Buffer.from(`--${boundary}\r\n` +
|
|
75
|
+
`Content-Disposition: form-data; name="file"; filename="${filename}"\r\n` +
|
|
76
|
+
`Content-Type: ${detectedMime}\r\n\r\n`);
|
|
77
|
+
const footer = Buffer.from(`\r\n--${boundary}--\r\n`);
|
|
78
|
+
const body = Buffer.concat([header, fileBuffer, footer]);
|
|
79
|
+
const basicAuth = Buffer.from(`${this.config.tinodeUsername}:${this.config.tinodePassword}`).toString('base64');
|
|
80
|
+
const url = `${this.config.httpBaseUrl}/api/files/upload`;
|
|
81
|
+
const resp = await fetch(url, {
|
|
82
|
+
method: 'POST',
|
|
83
|
+
headers: {
|
|
84
|
+
'Authorization': `Basic ${basicAuth}`,
|
|
85
|
+
'Content-Type': `multipart/form-data; boundary=${boundary}`,
|
|
86
|
+
},
|
|
87
|
+
body,
|
|
88
|
+
});
|
|
89
|
+
if (!resp.ok) {
|
|
90
|
+
const text = await resp.text();
|
|
91
|
+
throw new Error(`Upload failed (${resp.status}): ${text}`);
|
|
92
|
+
}
|
|
93
|
+
return resp.json();
|
|
94
|
+
}
|
|
95
|
+
async sendImage(topic, imageBuffer, filename, mime) {
|
|
96
|
+
const uploaded = await this.uploadFile(imageBuffer, filename, mime || 'image/png');
|
|
97
|
+
return this.sendMessage(topic, {
|
|
98
|
+
tp: 'image',
|
|
99
|
+
url: uploaded.url,
|
|
100
|
+
name: uploaded.name,
|
|
101
|
+
size: uploaded.size,
|
|
102
|
+
mime: uploaded.mime,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
async sendFile(topic, fileBuffer, filename, mime) {
|
|
106
|
+
const uploaded = await this.uploadFile(fileBuffer, filename, mime);
|
|
107
|
+
return this.sendMessage(topic, {
|
|
108
|
+
tp: 'file',
|
|
109
|
+
url: uploaded.url,
|
|
110
|
+
name: uploaded.name,
|
|
111
|
+
size: uploaded.size,
|
|
112
|
+
mime: uploaded.mime,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
getStore() {
|
|
116
|
+
return this.store;
|
|
117
|
+
}
|
|
118
|
+
getContactCache() {
|
|
119
|
+
return this.cache;
|
|
120
|
+
}
|
|
121
|
+
async stop() {
|
|
122
|
+
this.client.disconnect();
|
|
123
|
+
this.store.close();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=imclaw-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"imclaw-bridge.js","sourceRoot":"","sources":["../src/imclaw-bridge.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export { TinodeClient } from './tinode-client.js';
|
|
2
|
+
export type { TinodeMessage, TinodeClientOptions } from './tinode-client.js';
|
|
3
|
+
export { ImclawBridge } from './imclaw-bridge.js';
|
|
4
|
+
export type { ChannelConfig, InboundMessage, MessageHandler, UploadResult } from './imclaw-bridge.js';
|
|
5
|
+
export { MessageStore } from './message-store.js';
|
|
6
|
+
export type { StoredMessage } from './message-store.js';
|
|
7
|
+
export { ContactCache } from './contact-cache.js';
|
|
8
|
+
export { imclawPlugin } from './channel.js';
|
|
9
|
+
export { ImclawDaemon } from './daemon/daemon.js';
|
|
10
|
+
export type { DaemonConfig, ClawCredential } from './daemon/config.js';
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE7E,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEtG,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Library exports (for programmatic use)
|
|
2
|
+
export { TinodeClient } from './tinode-client.js';
|
|
3
|
+
export { ImclawBridge } from './imclaw-bridge.js';
|
|
4
|
+
export { MessageStore } from './message-store.js';
|
|
5
|
+
export { ContactCache } from './contact-cache.js';
|
|
6
|
+
// OpenClaw channel plugin
|
|
7
|
+
export { imclawPlugin } from './channel.js';
|
|
8
|
+
// Daemon exports (for programmatic daemon control)
|
|
9
|
+
export { ImclawDaemon } from './daemon/daemon.js';
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,0BAA0B;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,mDAAmD;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function getMediaDir(customDir?: string): string;
|
|
2
|
+
export declare function downloadMedia(url: string, originalName: string, seqId: number, customDir?: string): Promise<string | null>;
|
|
3
|
+
export declare function getMediaPath(filename: string, customDir?: string): string;
|
|
4
|
+
//# sourceMappingURL=media-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-store.d.ts","sourceRoot":"","sources":["../src/media-store.ts"],"names":[],"mappings":"AAMA,wBAAgB,WAAW,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAItD;AAED,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAmBxB;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAEzE"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
const DEFAULT_MEDIA_DIR = path.join(os.homedir(), '.openclaw', 'imclaw', 'media');
|
|
5
|
+
export function getMediaDir(customDir) {
|
|
6
|
+
const dir = customDir || DEFAULT_MEDIA_DIR;
|
|
7
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
8
|
+
return dir;
|
|
9
|
+
}
|
|
10
|
+
export async function downloadMedia(url, originalName, seqId, customDir) {
|
|
11
|
+
try {
|
|
12
|
+
const dir = getMediaDir(customDir);
|
|
13
|
+
const safeName = originalName.replace(/[^a-zA-Z0-9._-]/g, '_');
|
|
14
|
+
const filename = `${seqId}_${safeName}`;
|
|
15
|
+
const filePath = path.join(dir, filename);
|
|
16
|
+
// Skip if already downloaded
|
|
17
|
+
if (fs.existsSync(filePath))
|
|
18
|
+
return filename;
|
|
19
|
+
const resp = await fetch(url);
|
|
20
|
+
if (!resp.ok)
|
|
21
|
+
return null;
|
|
22
|
+
const buffer = Buffer.from(await resp.arrayBuffer());
|
|
23
|
+
fs.writeFileSync(filePath, buffer);
|
|
24
|
+
return filename;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export function getMediaPath(filename, customDir) {
|
|
31
|
+
return path.join(getMediaDir(customDir), filename);
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=media-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"media-store.js","sourceRoot":"","sources":["../src/media-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AAElF,MAAM,UAAU,WAAW,CAAC,SAAkB;IAC5C,MAAM,GAAG,GAAG,SAAS,IAAI,iBAAiB,CAAC;IAC3C,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACpD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAW,EACX,YAAoB,EACpB,KAAa,EACb,SAAkB;IAElB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;QAC/D,MAAM,QAAQ,GAAG,GAAG,KAAK,IAAI,QAAQ,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAE1C,6BAA6B;QAC7B,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,QAAQ,CAAC;QAE7C,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QAE1B,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QACrD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACnC,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,SAAkB;IAC/D,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface StoredMessage {
|
|
2
|
+
id: number;
|
|
3
|
+
topic: string;
|
|
4
|
+
from_user: string;
|
|
5
|
+
seq_id: number;
|
|
6
|
+
content: string;
|
|
7
|
+
timestamp: string;
|
|
8
|
+
synced: number;
|
|
9
|
+
owner_claw_id: string | null;
|
|
10
|
+
}
|
|
11
|
+
export declare class MessageStore {
|
|
12
|
+
private db;
|
|
13
|
+
constructor(dbPath?: string);
|
|
14
|
+
private migrate;
|
|
15
|
+
saveMessage(topic: string, fromUser: string, seqId: number, content: any, timestamp: Date, ownerClawId?: string): void;
|
|
16
|
+
getLastSeq(topic: string): number;
|
|
17
|
+
getMessages(topic: string, limit?: number, beforeSeq?: number): StoredMessage[];
|
|
18
|
+
getConversations(): {
|
|
19
|
+
topic: string;
|
|
20
|
+
last_seq: number;
|
|
21
|
+
last_message?: StoredMessage;
|
|
22
|
+
}[];
|
|
23
|
+
getMessageCount(topic: string): number;
|
|
24
|
+
getMessagesByOwner(ownerClawId: string, topic: string, limit?: number, beforeSeq?: number): StoredMessage[];
|
|
25
|
+
getConversationsByOwner(ownerClawId: string): {
|
|
26
|
+
topic: string;
|
|
27
|
+
last_seq: number;
|
|
28
|
+
last_message?: StoredMessage;
|
|
29
|
+
}[];
|
|
30
|
+
close(): void;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=message-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-store.d.ts","sourceRoot":"","sources":["../src/message-store.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,EAAE,CAAoB;gBAElB,MAAM,CAAC,EAAE,MAAM;IAe3B,OAAO,CAAC,OAAO;IA+Bf,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI;IActH,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAOjC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE;IAa3E,gBAAgB,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,aAAa,CAAA;KAAE,EAAE;IAavF,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAStC,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,SAAK,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE;IAavG,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,aAAa,CAAA;KAAE,EAAE;IAcjH,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import Database from 'better-sqlite3';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
import fs from 'fs';
|
|
5
|
+
export class MessageStore {
|
|
6
|
+
db;
|
|
7
|
+
constructor(dbPath) {
|
|
8
|
+
const defaultPath = path.join(os.homedir(), '.openclaw', 'imclaw');
|
|
9
|
+
const resolvedPath = dbPath || path.join(defaultPath, 'messages.db');
|
|
10
|
+
// Ensure directory exists with restrictive permissions
|
|
11
|
+
fs.mkdirSync(path.dirname(resolvedPath), { recursive: true, mode: 0o700 });
|
|
12
|
+
this.db = new Database(resolvedPath);
|
|
13
|
+
// Restrict database file permissions
|
|
14
|
+
try {
|
|
15
|
+
fs.chmodSync(resolvedPath, 0o600);
|
|
16
|
+
}
|
|
17
|
+
catch { /* new file, will be set on next open */ }
|
|
18
|
+
this.db.pragma('journal_mode = WAL');
|
|
19
|
+
this.migrate();
|
|
20
|
+
}
|
|
21
|
+
migrate() {
|
|
22
|
+
this.db.exec(`
|
|
23
|
+
CREATE TABLE IF NOT EXISTS messages (
|
|
24
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
25
|
+
topic TEXT NOT NULL,
|
|
26
|
+
from_user TEXT NOT NULL,
|
|
27
|
+
seq_id INTEGER NOT NULL,
|
|
28
|
+
content TEXT NOT NULL,
|
|
29
|
+
timestamp TEXT NOT NULL,
|
|
30
|
+
synced INTEGER DEFAULT 1,
|
|
31
|
+
UNIQUE(topic, seq_id)
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
CREATE INDEX IF NOT EXISTS idx_messages_topic_seq
|
|
35
|
+
ON messages(topic, seq_id);
|
|
36
|
+
|
|
37
|
+
CREATE TABLE IF NOT EXISTS sync_state (
|
|
38
|
+
topic TEXT PRIMARY KEY,
|
|
39
|
+
last_seq INTEGER NOT NULL DEFAULT 0
|
|
40
|
+
);
|
|
41
|
+
`);
|
|
42
|
+
// V2: Add owner_claw_id for per-claw message isolation
|
|
43
|
+
try {
|
|
44
|
+
this.db.exec(`ALTER TABLE messages ADD COLUMN owner_claw_id TEXT`);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// Column already exists — safe to ignore
|
|
48
|
+
}
|
|
49
|
+
this.db.exec(`CREATE INDEX IF NOT EXISTS idx_messages_owner ON messages(owner_claw_id, topic)`);
|
|
50
|
+
}
|
|
51
|
+
saveMessage(topic, fromUser, seqId, content, timestamp, ownerClawId) {
|
|
52
|
+
const contentStr = typeof content === 'string' ? content : JSON.stringify(content);
|
|
53
|
+
this.db.prepare(`INSERT OR IGNORE INTO messages (topic, from_user, seq_id, content, timestamp, owner_claw_id)
|
|
54
|
+
VALUES (?, ?, ?, ?, ?, ?)`).run(topic, fromUser, seqId, contentStr, timestamp.toISOString(), ownerClawId || null);
|
|
55
|
+
// Update sync state
|
|
56
|
+
this.db.prepare(`INSERT INTO sync_state (topic, last_seq) VALUES (?, ?)
|
|
57
|
+
ON CONFLICT(topic) DO UPDATE SET last_seq = MAX(last_seq, excluded.last_seq)`).run(topic, seqId);
|
|
58
|
+
}
|
|
59
|
+
getLastSeq(topic) {
|
|
60
|
+
const row = this.db.prepare('SELECT last_seq FROM sync_state WHERE topic = ?').get(topic);
|
|
61
|
+
return row?.last_seq || 0;
|
|
62
|
+
}
|
|
63
|
+
getMessages(topic, limit = 50, beforeSeq) {
|
|
64
|
+
if (beforeSeq) {
|
|
65
|
+
return this.db.prepare(`SELECT * FROM messages WHERE topic = ? AND seq_id < ?
|
|
66
|
+
ORDER BY seq_id DESC LIMIT ?`).all(topic, beforeSeq, limit);
|
|
67
|
+
}
|
|
68
|
+
return this.db.prepare(`SELECT * FROM messages WHERE topic = ?
|
|
69
|
+
ORDER BY seq_id DESC LIMIT ?`).all(topic, limit);
|
|
70
|
+
}
|
|
71
|
+
getConversations() {
|
|
72
|
+
const topics = this.db.prepare('SELECT topic, last_seq FROM sync_state ORDER BY last_seq DESC').all();
|
|
73
|
+
return topics.map((t) => {
|
|
74
|
+
const lastMsg = this.db.prepare('SELECT * FROM messages WHERE topic = ? ORDER BY seq_id DESC LIMIT 1').get(t.topic);
|
|
75
|
+
return { ...t, last_message: lastMsg };
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
getMessageCount(topic) {
|
|
79
|
+
const row = this.db.prepare('SELECT COUNT(*) as cnt FROM messages WHERE topic = ?').get(topic);
|
|
80
|
+
return row.cnt;
|
|
81
|
+
}
|
|
82
|
+
// ── Owner-scoped queries (agent sees only its own messages) ──
|
|
83
|
+
getMessagesByOwner(ownerClawId, topic, limit = 50, beforeSeq) {
|
|
84
|
+
if (beforeSeq) {
|
|
85
|
+
return this.db.prepare(`SELECT * FROM messages WHERE owner_claw_id = ? AND topic = ? AND seq_id < ?
|
|
86
|
+
ORDER BY seq_id DESC LIMIT ?`).all(ownerClawId, topic, beforeSeq, limit);
|
|
87
|
+
}
|
|
88
|
+
return this.db.prepare(`SELECT * FROM messages WHERE owner_claw_id = ? AND topic = ?
|
|
89
|
+
ORDER BY seq_id DESC LIMIT ?`).all(ownerClawId, topic, limit);
|
|
90
|
+
}
|
|
91
|
+
getConversationsByOwner(ownerClawId) {
|
|
92
|
+
const topics = this.db.prepare(`SELECT topic, MAX(seq_id) as last_seq FROM messages
|
|
93
|
+
WHERE owner_claw_id = ? GROUP BY topic ORDER BY last_seq DESC`).all(ownerClawId);
|
|
94
|
+
return topics.map((t) => {
|
|
95
|
+
const lastMsg = this.db.prepare('SELECT * FROM messages WHERE owner_claw_id = ? AND topic = ? ORDER BY seq_id DESC LIMIT 1').get(ownerClawId, t.topic);
|
|
96
|
+
return { ...t, last_message: lastMsg };
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
close() {
|
|
100
|
+
this.db.close();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=message-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-store.js","sourceRoot":"","sources":["../src/message-store.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,MAAM,IAAI,CAAC;AAapB,MAAM,OAAO,YAAY;IACf,EAAE,CAAoB;IAE9B,YAAY,MAAe;QACzB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;QACnE,MAAM,YAAY,GAAG,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;QAErE,uDAAuD;QACvD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAE3E,IAAI,CAAC,EAAE,GAAG,IAAI,QAAQ,CAAC,YAAY,CAAC,CAAC;QAErC,qCAAqC;QACrC,IAAI,CAAC;YAAC,EAAE,CAAC,SAAS,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,wCAAwC,CAAC,CAAC;QAC7F,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACrC,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAEO,OAAO;QACb,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;KAmBZ,CAAC,CAAC;QAEH,uDAAuD;QACvD,IAAI,CAAC;YACH,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;QACrE,CAAC;QAAC,MAAM,CAAC;YACP,yCAAyC;QAC3C,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,iFAAiF,CAAC,CAAC;IAClG,CAAC;IAED,WAAW,CAAC,KAAa,EAAE,QAAgB,EAAE,KAAa,EAAE,OAAY,EAAE,SAAe,EAAE,WAAoB;QAC7G,MAAM,UAAU,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACnF,IAAI,CAAC,EAAE,CAAC,OAAO,CACb;iCAC2B,CAC5B,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,CAAC,WAAW,EAAE,EAAE,WAAW,IAAI,IAAI,CAAC,CAAC;QAExF,oBAAoB;QACpB,IAAI,CAAC,EAAE,CAAC,OAAO,CACb;oFAC8E,CAC/E,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACtB,CAAC;IAED,UAAU,CAAC,KAAa;QACtB,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CACzB,iDAAiD,CAClD,CAAC,GAAG,CAAC,KAAK,CAAqC,CAAC;QACjD,OAAO,GAAG,EAAE,QAAQ,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,WAAW,CAAC,KAAa,EAAE,KAAK,GAAG,EAAE,EAAE,SAAkB;QACvD,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CACpB;sCAC8B,CAC/B,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,CAAoB,CAAC;QACpD,CAAC;QACD,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CACpB;oCAC8B,CAC/B,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAoB,CAAC;IACzC,CAAC;IAED,gBAAgB;QACd,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAC5B,+DAA+D,CAChE,CAAC,GAAG,EAA2C,CAAC;QAEjD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACtB,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAC7B,qEAAqE,CACtE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAA8B,CAAC;YAC5C,OAAO,EAAE,GAAG,CAAC,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,eAAe,CAAC,KAAa;QAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CACzB,sDAAsD,CACvD,CAAC,GAAG,CAAC,KAAK,CAAoB,CAAC;QAChC,OAAO,GAAG,CAAC,GAAG,CAAC;IACjB,CAAC;IAED,gEAAgE;IAEhE,kBAAkB,CAAC,WAAmB,EAAE,KAAa,EAAE,KAAK,GAAG,EAAE,EAAE,SAAkB;QACnF,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CACpB;sCAC8B,CAC/B,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAoB,CAAC;QACjE,CAAC;QACD,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CACpB;oCAC8B,CAC/B,CAAC,GAAG,CAAC,WAAW,EAAE,KAAK,EAAE,KAAK,CAAoB,CAAC;IACtD,CAAC;IAED,uBAAuB,CAAC,WAAmB;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAC5B;qEAC+D,CAChE,CAAC,GAAG,CAAC,WAAW,CAA0C,CAAC;QAE5D,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACtB,MAAM,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAC7B,2FAA2F,CAC5F,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,KAAK,CAA8B,CAAC;YACzD,OAAO,EAAE,GAAG,CAAC,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK;QACH,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-entry.d.ts","sourceRoot":"","sources":["../src/plugin-entry.ts"],"names":[],"mappings":"AAEA,wBAAgB,QAAQ,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAWvC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { imclawPlugin, setPluginConfig, setPluginRuntime } from './channel.js';
|
|
2
|
+
export function register(api) {
|
|
3
|
+
// Store plugin-level config so channel.ts can access serverUrl, apiKey, accounts, etc.
|
|
4
|
+
setPluginConfig(api.pluginConfig ?? {});
|
|
5
|
+
// Store the PluginRuntime — this is the correct runtime for dispatching messages to agents.
|
|
6
|
+
// It is NOT the same as the `runtime` param in startAccount().
|
|
7
|
+
if (api.runtime) {
|
|
8
|
+
setPluginRuntime(api.runtime);
|
|
9
|
+
}
|
|
10
|
+
api.registerChannel({ plugin: imclawPlugin });
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=plugin-entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin-entry.js","sourceRoot":"","sources":["../src/plugin-entry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAE/E,MAAM,UAAU,QAAQ,CAAC,GAAQ;IAC/B,uFAAuF;IACvF,eAAe,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IAExC,4FAA4F;IAC5F,+DAA+D;IAC/D,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QAChB,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,GAAG,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
export interface TinodeMessage {
|
|
3
|
+
topic: string;
|
|
4
|
+
from: string;
|
|
5
|
+
seqId: number;
|
|
6
|
+
content: any;
|
|
7
|
+
timestamp: Date;
|
|
8
|
+
}
|
|
9
|
+
export interface TinodeClientOptions {
|
|
10
|
+
serverUrl: string;
|
|
11
|
+
username: string;
|
|
12
|
+
password: string;
|
|
13
|
+
apiKey?: string;
|
|
14
|
+
userAgent?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare class TinodeClient extends EventEmitter {
|
|
17
|
+
private ws;
|
|
18
|
+
private options;
|
|
19
|
+
private msgId;
|
|
20
|
+
private reconnectDelay;
|
|
21
|
+
private maxReconnectDelay;
|
|
22
|
+
private token;
|
|
23
|
+
private shouldReconnect;
|
|
24
|
+
private heartbeatInterval;
|
|
25
|
+
private subscribedTopics;
|
|
26
|
+
private _selfUid;
|
|
27
|
+
constructor(options: TinodeClientOptions);
|
|
28
|
+
getSelfUid(): string | null;
|
|
29
|
+
connect(): Promise<void>;
|
|
30
|
+
disconnect(): void;
|
|
31
|
+
sendMessage(topicName: string, content: any): Promise<number>;
|
|
32
|
+
private subscribeTopic;
|
|
33
|
+
/** Subscribe to "me" topic to discover existing conversations and receive presence notifications. */
|
|
34
|
+
private subscribeMe;
|
|
35
|
+
private handleMessage;
|
|
36
|
+
private sendHi;
|
|
37
|
+
private loginBasic;
|
|
38
|
+
private send;
|
|
39
|
+
private startHeartbeat;
|
|
40
|
+
private stopHeartbeat;
|
|
41
|
+
private scheduleReconnect;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=tinode-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tinode-client.d.ts","sourceRoot":"","sources":["../src/tinode-client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,GAAG,CAAC;IACb,SAAS,EAAE,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,YAAa,SAAQ,YAAY;IAC5C,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,OAAO,CAAsB;IACrC,OAAO,CAAC,KAAK,CAAK;IAClB,OAAO,CAAC,cAAc,CAAQ;IAC9B,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,KAAK,CAAuB;IACpC,OAAO,CAAC,eAAe,CAAQ;IAC/B,OAAO,CAAC,iBAAiB,CAA+B;IACxD,OAAO,CAAC,gBAAgB,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAuB;gBAE3B,OAAO,EAAE,mBAAmB;IAKxC,UAAU,IAAI,MAAM,GAAG,IAAI;IAIrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA8C9B,UAAU,IAAI,IAAI;IAOZ,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC;YAyCrD,cAAc;IAgC5B,qGAAqG;IACrG,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,aAAa;IAoDrB,OAAO,CAAC,MAAM;IAUd,OAAO,CAAC,UAAU;IAclB,OAAO,CAAC,IAAI;IAMZ,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,iBAAiB;CAkB1B"}
|