@studiomopoke/crosschat 1.8.2 → 2.0.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 +48 -118
- package/bin/cli.cjs +37 -57
- package/crosschat.md +73 -104
- package/dashboard/dist/assets/index-BY-IQhma.js +49 -0
- package/dashboard/dist/assets/index-CI8v9PKQ.css +1 -0
- package/dashboard/dist/index.html +2 -2
- package/dist/hub/_hub-section-1-infra.d.ts +8 -0
- package/dist/hub/_hub-section-1-infra.d.ts.map +1 -0
- package/dist/hub/_hub-section-1-infra.js +152 -0
- package/dist/hub/_hub-section-1-infra.js.map +1 -0
- package/dist/hub/_hub-section-2-handlers.d.ts +2 -0
- package/dist/hub/_hub-section-2-handlers.d.ts.map +1 -0
- package/dist/hub/_hub-section-2-handlers.js +514 -0
- package/dist/hub/_hub-section-2-handlers.js.map +1 -0
- package/dist/hub/_hub-section-3-rest.d.ts +2 -0
- package/dist/hub/_hub-section-3-rest.d.ts.map +1 -0
- package/dist/hub/_hub-section-3-rest.js +418 -0
- package/dist/hub/_hub-section-3-rest.js.map +1 -0
- package/dist/hub/_hub-section-4-ws.d.ts +2 -0
- package/dist/hub/_hub-section-4-ws.d.ts.map +1 -0
- package/dist/hub/_hub-section-4-ws.js +367 -0
- package/dist/hub/_hub-section-4-ws.js.map +1 -0
- package/dist/hub/agent-connection.d.ts +38 -62
- package/dist/hub/agent-connection.d.ts.map +1 -1
- package/dist/hub/agent-connection.js +146 -229
- package/dist/hub/agent-connection.js.map +1 -1
- package/dist/hub/hub-server.d.ts +1 -1
- package/dist/hub/hub-server.d.ts.map +1 -1
- package/dist/hub/hub-server.js +389 -685
- package/dist/hub/hub-server.js.map +1 -1
- package/dist/hub/message-manager.d.ts +158 -0
- package/dist/hub/message-manager.d.ts.map +1 -0
- package/dist/hub/message-manager.js +443 -0
- package/dist/hub/message-manager.js.map +1 -0
- package/dist/hub/protocol.d.ts +73 -131
- package/dist/hub/protocol.d.ts.map +1 -1
- package/dist/hub/protocol.js +3 -0
- package/dist/hub/protocol.js.map +1 -1
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/lifecycle.js +15 -89
- package/dist/lifecycle.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +22 -33
- package/dist/server.js.map +1 -1
- package/dist/tools/add-badge.d.ts +4 -0
- package/dist/tools/add-badge.d.ts.map +1 -0
- package/dist/tools/add-badge.js +29 -0
- package/dist/tools/add-badge.js.map +1 -0
- package/dist/tools/claim-task.js +5 -5
- package/dist/tools/claim-task.js.map +1 -1
- package/dist/tools/clear-session.d.ts +1 -2
- package/dist/tools/clear-session.d.ts.map +1 -1
- package/dist/tools/clear-session.js +7 -22
- package/dist/tools/clear-session.js.map +1 -1
- package/dist/tools/flag-as-task.d.ts +4 -0
- package/dist/tools/flag-as-task.d.ts.map +1 -0
- package/dist/tools/flag-as-task.js +31 -0
- package/dist/tools/flag-as-task.js.map +1 -0
- package/dist/tools/get-messages.d.ts +2 -1
- package/dist/tools/get-messages.d.ts.map +1 -1
- package/dist/tools/get-messages.js +19 -6
- package/dist/tools/get-messages.js.map +1 -1
- package/dist/tools/list-peers.d.ts.map +1 -1
- package/dist/tools/list-peers.js +1 -4
- package/dist/tools/list-peers.js.map +1 -1
- package/dist/tools/resolve-task.d.ts +4 -0
- package/dist/tools/resolve-task.d.ts.map +1 -0
- package/dist/tools/resolve-task.js +29 -0
- package/dist/tools/resolve-task.js.map +1 -0
- package/dist/tools/send-message.d.ts.map +1 -1
- package/dist/tools/send-message.js +6 -5
- package/dist/tools/send-message.js.map +1 -1
- package/dist/tools/set-status.js +3 -3
- package/dist/tools/set-status.js.map +1 -1
- package/dist/tools/wait-for-messages.js +1 -1
- package/dist/tools/wait-for-messages.js.map +1 -1
- package/dist/types.d.ts +4 -3
- package/dist/types.d.ts.map +1 -1
- package/hooks/permission-hook.sh +19 -18
- package/package.json +1 -1
- package/dashboard/dist/assets/index-BR-2rRm6.css +0 -1
- package/dashboard/dist/assets/index-Ci2ihChN.js +0 -49
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified messaging data model for CrossChat.
|
|
3
|
+
*
|
|
4
|
+
* Messages are the atomic unit. Threads are reply chains on any message.
|
|
5
|
+
* Tasks are a workflow flag (badge) on a message. Badges provide extensible
|
|
6
|
+
* metadata that is both machine-readable (agents parse like frontmatter)
|
|
7
|
+
* and human-readable (rendered as visual badges in the dashboard).
|
|
8
|
+
*/
|
|
9
|
+
// ── Badge system ─────────────────────────────────────────────────
|
|
10
|
+
/** Well-known badge types. New types can be added without code changes. */
|
|
11
|
+
export const BADGE_TYPES = {
|
|
12
|
+
TASK: 'task',
|
|
13
|
+
IMPORTANCE: 'importance',
|
|
14
|
+
QUESTION: 'question',
|
|
15
|
+
GIT_COMMIT: 'git-commit',
|
|
16
|
+
PROJECT: 'project',
|
|
17
|
+
PERMISSION: 'permission',
|
|
18
|
+
COMPLETION: 'completion',
|
|
19
|
+
};
|
|
20
|
+
// ── MessageManager ───────────────────────────────────────────────
|
|
21
|
+
import fs from 'node:fs/promises';
|
|
22
|
+
import path from 'node:path';
|
|
23
|
+
import os from 'node:os';
|
|
24
|
+
import { log, logError } from '../util/logger.js';
|
|
25
|
+
const MESSAGES_DIR = path.join(os.homedir(), '.crosschat', 'messages');
|
|
26
|
+
const THREADS_DIR = path.join(MESSAGES_DIR, 'threads');
|
|
27
|
+
const TASKS_DIR = path.join(MESSAGES_DIR, 'tasks');
|
|
28
|
+
const CHANNEL_MESSAGE_CAP = 200;
|
|
29
|
+
const THREAD_MESSAGE_CAP = 500;
|
|
30
|
+
/**
|
|
31
|
+
* Persistent message storage with thread isolation and badge support.
|
|
32
|
+
*
|
|
33
|
+
* Channel messages stored in: ~/.crosschat/messages/{channelId}.jsonl
|
|
34
|
+
* Thread messages stored in: ~/.crosschat/messages/threads/{threadId}.jsonl
|
|
35
|
+
* Task metadata stored in: ~/.crosschat/messages/tasks/{messageId}.json
|
|
36
|
+
*/
|
|
37
|
+
export class MessageManager {
|
|
38
|
+
/** In-memory cache of channel messages (capped at CHANNEL_MESSAGE_CAP). */
|
|
39
|
+
channelMessages = new Map();
|
|
40
|
+
/** In-memory cache of thread messages (keyed by root messageId). */
|
|
41
|
+
threadMessages = new Map();
|
|
42
|
+
/** In-memory index of all messages by ID (for badge operations). */
|
|
43
|
+
messageIndex = new Map();
|
|
44
|
+
/** Task metadata for flagged messages. */
|
|
45
|
+
taskMetas = new Map();
|
|
46
|
+
/** Listeners notified on new messages. */
|
|
47
|
+
messageListeners = [];
|
|
48
|
+
/** Listeners notified on badge changes. */
|
|
49
|
+
badgeListeners = [];
|
|
50
|
+
// ── Initialization ──────────────────────────────────────────────
|
|
51
|
+
async init() {
|
|
52
|
+
await fs.mkdir(MESSAGES_DIR, { recursive: true });
|
|
53
|
+
await fs.mkdir(THREADS_DIR, { recursive: true });
|
|
54
|
+
await fs.mkdir(TASKS_DIR, { recursive: true });
|
|
55
|
+
await this.loadFromDisk();
|
|
56
|
+
const msgCount = this.messageIndex.size;
|
|
57
|
+
const threadCount = this.threadMessages.size;
|
|
58
|
+
const taskCount = this.taskMetas.size;
|
|
59
|
+
log(`MessageManager initialized: ${msgCount} messages, ${threadCount} threads, ${taskCount} tasks`);
|
|
60
|
+
}
|
|
61
|
+
// ── Message operations ──────────────────────────────────────────
|
|
62
|
+
/** Add a message to the channel or a thread. Persists to disk. */
|
|
63
|
+
async addMessage(message) {
|
|
64
|
+
this.messageIndex.set(message.messageId, message);
|
|
65
|
+
if (message.threadId) {
|
|
66
|
+
// Thread reply
|
|
67
|
+
const thread = this.threadMessages.get(message.threadId) ?? [];
|
|
68
|
+
thread.push(message);
|
|
69
|
+
this.threadMessages.set(message.threadId, thread);
|
|
70
|
+
await this.appendToFile(path.join(THREADS_DIR, `${message.threadId}.jsonl`), message);
|
|
71
|
+
// Enforce thread cap — evict oldest from memory (disk retains full history)
|
|
72
|
+
if (thread.length > THREAD_MESSAGE_CAP) {
|
|
73
|
+
const overflow = thread.length - THREAD_MESSAGE_CAP;
|
|
74
|
+
const evicted = thread.splice(0, overflow);
|
|
75
|
+
for (const msg of evicted) {
|
|
76
|
+
this.messageIndex.delete(msg.messageId);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
// Channel message
|
|
82
|
+
const channel = this.channelMessages.get(message.channelId) ?? [];
|
|
83
|
+
channel.push(message);
|
|
84
|
+
this.channelMessages.set(message.channelId, channel);
|
|
85
|
+
await this.appendToFile(path.join(MESSAGES_DIR, `${message.channelId}.jsonl`), message);
|
|
86
|
+
// Enforce cap — keep only the most recent messages in memory
|
|
87
|
+
if (channel.length > CHANNEL_MESSAGE_CAP) {
|
|
88
|
+
const overflow = channel.length - CHANNEL_MESSAGE_CAP;
|
|
89
|
+
const evicted = channel.splice(0, overflow);
|
|
90
|
+
for (const msg of evicted) {
|
|
91
|
+
this.messageIndex.delete(msg.messageId);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Notify listeners
|
|
96
|
+
for (const cb of this.messageListeners) {
|
|
97
|
+
try {
|
|
98
|
+
cb(message);
|
|
99
|
+
}
|
|
100
|
+
catch { /* swallow */ }
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/** Get a message by ID. */
|
|
104
|
+
getMessage(messageId) {
|
|
105
|
+
return this.messageIndex.get(messageId);
|
|
106
|
+
}
|
|
107
|
+
/** Get channel messages (from in-memory cache). */
|
|
108
|
+
getChannelMessages(channelId, opts) {
|
|
109
|
+
let messages = this.channelMessages.get(channelId) ?? [];
|
|
110
|
+
if (opts?.afterMessageId) {
|
|
111
|
+
const idx = messages.findIndex((m) => m.messageId === opts.afterMessageId);
|
|
112
|
+
if (idx !== -1) {
|
|
113
|
+
messages = messages.slice(idx + 1);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (opts?.limit && opts.limit > 0) {
|
|
117
|
+
messages = messages.slice(-opts.limit);
|
|
118
|
+
}
|
|
119
|
+
return [...messages];
|
|
120
|
+
}
|
|
121
|
+
/** Get thread messages for a given root message. */
|
|
122
|
+
getThreadMessages(threadId) {
|
|
123
|
+
return [...(this.threadMessages.get(threadId) ?? [])];
|
|
124
|
+
}
|
|
125
|
+
/** Get the number of replies in a thread. */
|
|
126
|
+
getThreadReplyCount(threadId) {
|
|
127
|
+
return this.threadMessages.get(threadId)?.length ?? 0;
|
|
128
|
+
}
|
|
129
|
+
/** Clear channel messages (in-memory only — disk retains history). */
|
|
130
|
+
clearChannel(channelId) {
|
|
131
|
+
const messages = this.channelMessages.get(channelId);
|
|
132
|
+
if (!messages)
|
|
133
|
+
return 0;
|
|
134
|
+
const count = messages.length;
|
|
135
|
+
for (const msg of messages) {
|
|
136
|
+
this.messageIndex.delete(msg.messageId);
|
|
137
|
+
}
|
|
138
|
+
this.channelMessages.set(channelId, []);
|
|
139
|
+
return count;
|
|
140
|
+
}
|
|
141
|
+
// ── Badge operations ────────────────────────────────────────────
|
|
142
|
+
/** Add a badge to a message. Updates in-memory and persists badge state. */
|
|
143
|
+
async addBadge(messageId, badge) {
|
|
144
|
+
const message = this.messageIndex.get(messageId);
|
|
145
|
+
if (!message)
|
|
146
|
+
return null;
|
|
147
|
+
// Replace existing badge of same type, or append
|
|
148
|
+
const existingIdx = message.badges.findIndex((b) => b.type === badge.type);
|
|
149
|
+
if (existingIdx >= 0) {
|
|
150
|
+
message.badges[existingIdx] = badge;
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
message.badges.push(badge);
|
|
154
|
+
}
|
|
155
|
+
// Persist the badge change by rewriting the message's badges to a sidecar
|
|
156
|
+
await this.persistBadges(messageId, message.badges);
|
|
157
|
+
// Notify listeners
|
|
158
|
+
for (const cb of this.badgeListeners) {
|
|
159
|
+
try {
|
|
160
|
+
cb(messageId, badge);
|
|
161
|
+
}
|
|
162
|
+
catch { /* swallow */ }
|
|
163
|
+
}
|
|
164
|
+
return message;
|
|
165
|
+
}
|
|
166
|
+
/** Remove a badge by type from a message. */
|
|
167
|
+
async removeBadge(messageId, badgeType) {
|
|
168
|
+
const message = this.messageIndex.get(messageId);
|
|
169
|
+
if (!message)
|
|
170
|
+
return null;
|
|
171
|
+
message.badges = message.badges.filter((b) => b.type !== badgeType);
|
|
172
|
+
await this.persistBadges(messageId, message.badges);
|
|
173
|
+
return message;
|
|
174
|
+
}
|
|
175
|
+
/** Get all badges on a message. */
|
|
176
|
+
getBadges(messageId) {
|
|
177
|
+
return this.messageIndex.get(messageId)?.badges ?? [];
|
|
178
|
+
}
|
|
179
|
+
// ── Task operations ─────────────────────────────────────────────
|
|
180
|
+
/** Flag a message as a task. Adds a task badge and creates TaskMeta. */
|
|
181
|
+
async flagAsTask(messageId, addedBy, filter) {
|
|
182
|
+
const message = this.messageIndex.get(messageId);
|
|
183
|
+
if (!message)
|
|
184
|
+
return null;
|
|
185
|
+
// Check if already flagged
|
|
186
|
+
if (message.badges.some((b) => b.type === BADGE_TYPES.TASK)) {
|
|
187
|
+
return this.taskMetas.get(messageId) ?? null;
|
|
188
|
+
}
|
|
189
|
+
const badge = {
|
|
190
|
+
type: BADGE_TYPES.TASK,
|
|
191
|
+
value: 'open',
|
|
192
|
+
label: 'Task',
|
|
193
|
+
addedBy,
|
|
194
|
+
addedAt: new Date().toISOString(),
|
|
195
|
+
};
|
|
196
|
+
await this.addBadge(messageId, badge);
|
|
197
|
+
const meta = {
|
|
198
|
+
messageId,
|
|
199
|
+
filter,
|
|
200
|
+
};
|
|
201
|
+
this.taskMetas.set(messageId, meta);
|
|
202
|
+
await this.persistTaskMeta(meta);
|
|
203
|
+
log(`Message ${messageId} flagged as task by ${addedBy}`);
|
|
204
|
+
return meta;
|
|
205
|
+
}
|
|
206
|
+
/** Claim a task. First-come-first-served. */
|
|
207
|
+
async claimTask(messageId, claimantId, claimantName) {
|
|
208
|
+
const meta = this.taskMetas.get(messageId);
|
|
209
|
+
if (!meta)
|
|
210
|
+
throw new Error(`No task on message ${messageId}`);
|
|
211
|
+
const message = this.messageIndex.get(messageId);
|
|
212
|
+
const taskBadge = message?.badges.find((b) => b.type === BADGE_TYPES.TASK);
|
|
213
|
+
if (!taskBadge || taskBadge.value !== 'open') {
|
|
214
|
+
throw new Error(`Task on message ${messageId} is not open (status: ${taskBadge?.value ?? 'none'})`);
|
|
215
|
+
}
|
|
216
|
+
if (message?.fromPeerId === claimantId) {
|
|
217
|
+
throw new Error('Cannot claim your own task');
|
|
218
|
+
}
|
|
219
|
+
// Update badge
|
|
220
|
+
taskBadge.value = 'claimed';
|
|
221
|
+
await this.persistBadges(messageId, message.badges);
|
|
222
|
+
// Update meta
|
|
223
|
+
meta.claimantId = claimantId;
|
|
224
|
+
meta.claimantName = claimantName;
|
|
225
|
+
meta.claimedAt = new Date().toISOString();
|
|
226
|
+
await this.persistTaskMeta(meta);
|
|
227
|
+
log(`Task ${messageId} claimed by ${claimantName}`);
|
|
228
|
+
return meta;
|
|
229
|
+
}
|
|
230
|
+
/** Resolve (complete or fail) a task. */
|
|
231
|
+
async resolveTask(messageId, resolverId, status, result, error) {
|
|
232
|
+
const meta = this.taskMetas.get(messageId);
|
|
233
|
+
if (!meta)
|
|
234
|
+
throw new Error(`No task on message ${messageId}`);
|
|
235
|
+
const message = this.messageIndex.get(messageId);
|
|
236
|
+
const taskBadge = message?.badges.find((b) => b.type === BADGE_TYPES.TASK);
|
|
237
|
+
if (!taskBadge)
|
|
238
|
+
throw new Error(`No task badge on message ${messageId}`);
|
|
239
|
+
if (taskBadge.value !== 'claimed' && taskBadge.value !== 'in_progress') {
|
|
240
|
+
throw new Error(`Task ${messageId} cannot be resolved (status: ${taskBadge.value})`);
|
|
241
|
+
}
|
|
242
|
+
if (meta.claimantId !== resolverId) {
|
|
243
|
+
throw new Error('Only the claimant can resolve a task');
|
|
244
|
+
}
|
|
245
|
+
// Update badge
|
|
246
|
+
taskBadge.value = status;
|
|
247
|
+
await this.persistBadges(messageId, message.badges);
|
|
248
|
+
// Update meta
|
|
249
|
+
meta.result = result;
|
|
250
|
+
if (error)
|
|
251
|
+
meta.error = error;
|
|
252
|
+
meta.resolvedAt = new Date().toISOString();
|
|
253
|
+
await this.persistTaskMeta(meta);
|
|
254
|
+
log(`Task ${messageId} resolved as ${status} by ${resolverId}`);
|
|
255
|
+
return meta;
|
|
256
|
+
}
|
|
257
|
+
/** Get task metadata for a flagged message. */
|
|
258
|
+
getTaskMeta(messageId) {
|
|
259
|
+
return this.taskMetas.get(messageId);
|
|
260
|
+
}
|
|
261
|
+
/** List all tasks, optionally filtered. */
|
|
262
|
+
listTasks(filter) {
|
|
263
|
+
const results = [];
|
|
264
|
+
for (const [messageId, meta] of this.taskMetas) {
|
|
265
|
+
const message = this.messageIndex.get(messageId);
|
|
266
|
+
if (!message)
|
|
267
|
+
continue;
|
|
268
|
+
const taskBadge = message.badges.find((b) => b.type === BADGE_TYPES.TASK);
|
|
269
|
+
if (!taskBadge)
|
|
270
|
+
continue;
|
|
271
|
+
if (filter?.status && taskBadge.value !== filter.status)
|
|
272
|
+
continue;
|
|
273
|
+
if (filter?.channelId && message.channelId !== filter.channelId)
|
|
274
|
+
continue;
|
|
275
|
+
if (filter?.claimantId && meta.claimantId !== filter.claimantId)
|
|
276
|
+
continue;
|
|
277
|
+
results.push({ message, task: meta });
|
|
278
|
+
}
|
|
279
|
+
return results;
|
|
280
|
+
}
|
|
281
|
+
// ── Event registration ──────────────────────────────────────────
|
|
282
|
+
onMessage(callback) {
|
|
283
|
+
this.messageListeners.push(callback);
|
|
284
|
+
return () => {
|
|
285
|
+
const idx = this.messageListeners.indexOf(callback);
|
|
286
|
+
if (idx !== -1)
|
|
287
|
+
this.messageListeners.splice(idx, 1);
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
onBadge(callback) {
|
|
291
|
+
this.badgeListeners.push(callback);
|
|
292
|
+
return () => {
|
|
293
|
+
const idx = this.badgeListeners.indexOf(callback);
|
|
294
|
+
if (idx !== -1)
|
|
295
|
+
this.badgeListeners.splice(idx, 1);
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
// ── Persistence ─────────────────────────────────────────────────
|
|
299
|
+
async appendToFile(filePath, message) {
|
|
300
|
+
try {
|
|
301
|
+
await fs.appendFile(filePath, JSON.stringify(message) + '\n', 'utf-8');
|
|
302
|
+
}
|
|
303
|
+
catch (err) {
|
|
304
|
+
logError(`Failed to append message to ${filePath}`, err);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
async persistBadges(messageId, badges) {
|
|
308
|
+
const filePath = path.join(MESSAGES_DIR, 'badges', `${messageId}.json`);
|
|
309
|
+
try {
|
|
310
|
+
await fs.mkdir(path.join(MESSAGES_DIR, 'badges'), { recursive: true });
|
|
311
|
+
const tmpPath = `${filePath}.tmp`;
|
|
312
|
+
await fs.writeFile(tmpPath, JSON.stringify(badges, null, 2), 'utf-8');
|
|
313
|
+
await fs.rename(tmpPath, filePath);
|
|
314
|
+
}
|
|
315
|
+
catch (err) {
|
|
316
|
+
logError(`Failed to persist badges for ${messageId}`, err);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
async persistTaskMeta(meta) {
|
|
320
|
+
const filePath = path.join(TASKS_DIR, `${meta.messageId}.json`);
|
|
321
|
+
try {
|
|
322
|
+
const tmpPath = `${filePath}.tmp`;
|
|
323
|
+
await fs.writeFile(tmpPath, JSON.stringify(meta, null, 2), 'utf-8');
|
|
324
|
+
await fs.rename(tmpPath, filePath);
|
|
325
|
+
}
|
|
326
|
+
catch (err) {
|
|
327
|
+
logError(`Failed to persist task meta for ${meta.messageId}`, err);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
async loadFromDisk() {
|
|
331
|
+
// Load channel messages
|
|
332
|
+
await this.loadChannelMessages();
|
|
333
|
+
// Load thread messages
|
|
334
|
+
await this.loadThreadMessages();
|
|
335
|
+
// Load badge overrides
|
|
336
|
+
await this.loadBadges();
|
|
337
|
+
// Load task metadata
|
|
338
|
+
await this.loadTaskMetas();
|
|
339
|
+
}
|
|
340
|
+
async loadChannelMessages() {
|
|
341
|
+
let entries;
|
|
342
|
+
try {
|
|
343
|
+
entries = (await fs.readdir(MESSAGES_DIR)).filter((e) => e.endsWith('.jsonl'));
|
|
344
|
+
}
|
|
345
|
+
catch {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
for (const entry of entries) {
|
|
349
|
+
const channelId = entry.replace('.jsonl', '');
|
|
350
|
+
const filePath = path.join(MESSAGES_DIR, entry);
|
|
351
|
+
const messages = await this.readJsonlFile(filePath);
|
|
352
|
+
// Keep only the last CHANNEL_MESSAGE_CAP in memory
|
|
353
|
+
const recent = messages.slice(-CHANNEL_MESSAGE_CAP);
|
|
354
|
+
this.channelMessages.set(channelId, recent);
|
|
355
|
+
for (const msg of recent) {
|
|
356
|
+
this.messageIndex.set(msg.messageId, msg);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
async loadThreadMessages() {
|
|
361
|
+
let entries;
|
|
362
|
+
try {
|
|
363
|
+
entries = (await fs.readdir(THREADS_DIR)).filter((e) => e.endsWith('.jsonl'));
|
|
364
|
+
}
|
|
365
|
+
catch {
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
for (const entry of entries) {
|
|
369
|
+
const threadId = entry.replace('.jsonl', '');
|
|
370
|
+
const filePath = path.join(THREADS_DIR, entry);
|
|
371
|
+
const messages = await this.readJsonlFile(filePath);
|
|
372
|
+
this.threadMessages.set(threadId, messages);
|
|
373
|
+
for (const msg of messages) {
|
|
374
|
+
this.messageIndex.set(msg.messageId, msg);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
async loadBadges() {
|
|
379
|
+
const badgesDir = path.join(MESSAGES_DIR, 'badges');
|
|
380
|
+
let entries;
|
|
381
|
+
try {
|
|
382
|
+
entries = (await fs.readdir(badgesDir)).filter((e) => e.endsWith('.json'));
|
|
383
|
+
}
|
|
384
|
+
catch {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
for (const entry of entries) {
|
|
388
|
+
const messageId = entry.replace('.json', '');
|
|
389
|
+
const message = this.messageIndex.get(messageId);
|
|
390
|
+
if (!message)
|
|
391
|
+
continue;
|
|
392
|
+
try {
|
|
393
|
+
const content = await fs.readFile(path.join(badgesDir, entry), 'utf-8');
|
|
394
|
+
message.badges = JSON.parse(content);
|
|
395
|
+
}
|
|
396
|
+
catch {
|
|
397
|
+
// Ignore corrupt badge files
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
async loadTaskMetas() {
|
|
402
|
+
let entries;
|
|
403
|
+
try {
|
|
404
|
+
entries = (await fs.readdir(TASKS_DIR)).filter((e) => e.endsWith('.json'));
|
|
405
|
+
}
|
|
406
|
+
catch {
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
for (const entry of entries) {
|
|
410
|
+
try {
|
|
411
|
+
const content = await fs.readFile(path.join(TASKS_DIR, entry), 'utf-8');
|
|
412
|
+
const meta = JSON.parse(content);
|
|
413
|
+
if (meta.messageId) {
|
|
414
|
+
this.taskMetas.set(meta.messageId, meta);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
catch {
|
|
418
|
+
// Ignore corrupt task files
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
async readJsonlFile(filePath) {
|
|
423
|
+
try {
|
|
424
|
+
const content = await fs.readFile(filePath, 'utf-8');
|
|
425
|
+
const messages = [];
|
|
426
|
+
for (const line of content.split('\n')) {
|
|
427
|
+
if (!line.trim())
|
|
428
|
+
continue;
|
|
429
|
+
try {
|
|
430
|
+
messages.push(JSON.parse(line));
|
|
431
|
+
}
|
|
432
|
+
catch {
|
|
433
|
+
// Skip malformed lines
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
return messages;
|
|
437
|
+
}
|
|
438
|
+
catch {
|
|
439
|
+
return [];
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
//# sourceMappingURL=message-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-manager.js","sourceRoot":"","sources":["../../src/hub/message-manager.ts"],"names":[],"mappings":"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"}
|