@dolusoft/claude-collab 0.1.0 → 0.1.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/dist/cli.js +99 -9
- package/dist/cli.js.map +1 -1
- package/dist/hub-main.js +96 -7
- package/dist/hub-main.js.map +1 -1
- package/dist/mcp-main.js +3 -2
- package/dist/mcp-main.js.map +1 -1
- package/package.json +1 -1
package/dist/hub-main.js
CHANGED
|
@@ -1064,6 +1064,15 @@ function createErrorMessage(code, message, requestId) {
|
|
|
1064
1064
|
}
|
|
1065
1065
|
|
|
1066
1066
|
// src/infrastructure/websocket/hub-server.ts
|
|
1067
|
+
function log(level, message, data) {
|
|
1068
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
1069
|
+
const prefix = `[${timestamp}] [HUB-${level}]`;
|
|
1070
|
+
if (data) {
|
|
1071
|
+
console.log(`${prefix} ${message}`, JSON.stringify(data, null, 2));
|
|
1072
|
+
} else {
|
|
1073
|
+
console.log(`${prefix} ${message}`);
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1067
1076
|
var HubServer = class {
|
|
1068
1077
|
constructor(options = {}) {
|
|
1069
1078
|
this.options = options;
|
|
@@ -1137,11 +1146,11 @@ var HubServer = class {
|
|
|
1137
1146
|
this.handleConnection(ws);
|
|
1138
1147
|
});
|
|
1139
1148
|
this.wss.on("error", (error) => {
|
|
1140
|
-
|
|
1149
|
+
log("ERROR", "Hub server error", { error: error.message, stack: error.stack });
|
|
1141
1150
|
reject(error);
|
|
1142
1151
|
});
|
|
1143
1152
|
this.wss.on("listening", () => {
|
|
1144
|
-
|
|
1153
|
+
log("INFO", `Hub server started successfully`, { host, port });
|
|
1145
1154
|
this.startHeartbeat();
|
|
1146
1155
|
this.startTimeoutCheck();
|
|
1147
1156
|
resolve();
|
|
@@ -1172,7 +1181,7 @@ var HubServer = class {
|
|
|
1172
1181
|
this.memberToWs.clear();
|
|
1173
1182
|
this.wss.close(() => {
|
|
1174
1183
|
this.wss = null;
|
|
1175
|
-
|
|
1184
|
+
log("INFO", "Hub server stopped gracefully");
|
|
1176
1185
|
resolve();
|
|
1177
1186
|
});
|
|
1178
1187
|
} else {
|
|
@@ -1186,6 +1195,7 @@ var HubServer = class {
|
|
|
1186
1195
|
lastPing: /* @__PURE__ */ new Date()
|
|
1187
1196
|
};
|
|
1188
1197
|
this.clients.set(ws, connection);
|
|
1198
|
+
log("INFO", "New client connected", { totalClients: this.clients.size });
|
|
1189
1199
|
ws.on("message", async (data) => {
|
|
1190
1200
|
await this.handleMessage(ws, data.toString());
|
|
1191
1201
|
});
|
|
@@ -1193,7 +1203,7 @@ var HubServer = class {
|
|
|
1193
1203
|
await this.handleDisconnect(ws);
|
|
1194
1204
|
});
|
|
1195
1205
|
ws.on("error", (error) => {
|
|
1196
|
-
|
|
1206
|
+
log("ERROR", "Client connection error", { error: error.message });
|
|
1197
1207
|
});
|
|
1198
1208
|
}
|
|
1199
1209
|
async handleMessage(ws, data) {
|
|
@@ -1202,6 +1212,10 @@ var HubServer = class {
|
|
|
1202
1212
|
try {
|
|
1203
1213
|
const message = parseClientMessage(data);
|
|
1204
1214
|
connection.lastPing = /* @__PURE__ */ new Date();
|
|
1215
|
+
log("DEBUG", `Received message from client`, {
|
|
1216
|
+
type: message.type,
|
|
1217
|
+
memberId: connection.memberId
|
|
1218
|
+
});
|
|
1205
1219
|
switch (message.type) {
|
|
1206
1220
|
case "JOIN":
|
|
1207
1221
|
await this.handleJoin(ws, connection, message.teamName, message.displayName);
|
|
@@ -1224,11 +1238,16 @@ var HubServer = class {
|
|
|
1224
1238
|
}
|
|
1225
1239
|
} catch (error) {
|
|
1226
1240
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
1241
|
+
log("ERROR", "Failed to handle message", {
|
|
1242
|
+
error: errorMessage,
|
|
1243
|
+
memberId: connection.memberId
|
|
1244
|
+
});
|
|
1227
1245
|
this.send(ws, createErrorMessage("INVALID_MESSAGE", errorMessage));
|
|
1228
1246
|
}
|
|
1229
1247
|
}
|
|
1230
1248
|
async handleJoin(ws, connection, teamName, displayName) {
|
|
1231
1249
|
try {
|
|
1250
|
+
log("INFO", "Member attempting to join", { teamName, displayName });
|
|
1232
1251
|
const result = await this.joinTeamUseCase.execute({ teamName, displayName });
|
|
1233
1252
|
connection.memberId = result.memberId;
|
|
1234
1253
|
connection.teamId = result.teamId;
|
|
@@ -1239,8 +1258,15 @@ var HubServer = class {
|
|
|
1239
1258
|
member: memberInfo,
|
|
1240
1259
|
memberCount: result.memberCount
|
|
1241
1260
|
});
|
|
1261
|
+
log("INFO", "Member joined successfully", {
|
|
1262
|
+
memberId: result.memberId,
|
|
1263
|
+
teamName,
|
|
1264
|
+
displayName,
|
|
1265
|
+
memberCount: result.memberCount
|
|
1266
|
+
});
|
|
1242
1267
|
} catch (error) {
|
|
1243
1268
|
const errorMessage = error instanceof Error ? error.message : "Join failed";
|
|
1269
|
+
log("ERROR", "Member join failed", { teamName, displayName, error: errorMessage });
|
|
1244
1270
|
this.send(ws, createErrorMessage("JOIN_FAILED", errorMessage));
|
|
1245
1271
|
}
|
|
1246
1272
|
}
|
|
@@ -1254,10 +1280,16 @@ var HubServer = class {
|
|
|
1254
1280
|
}
|
|
1255
1281
|
async handleAsk(ws, connection, message) {
|
|
1256
1282
|
if (!connection.memberId) {
|
|
1283
|
+
log("WARN", "ASK attempt without joining team", { toTeam: message.toTeam });
|
|
1257
1284
|
this.send(ws, createErrorMessage("NOT_JOINED", "Must join a team first", message.requestId));
|
|
1258
1285
|
return;
|
|
1259
1286
|
}
|
|
1260
1287
|
try {
|
|
1288
|
+
log("INFO", "Question asked", {
|
|
1289
|
+
fromMemberId: connection.memberId,
|
|
1290
|
+
toTeam: message.toTeam,
|
|
1291
|
+
contentPreview: message.content.substring(0, 50) + "..."
|
|
1292
|
+
});
|
|
1261
1293
|
const result = await this.askQuestionUseCase.execute({
|
|
1262
1294
|
fromMemberId: connection.memberId,
|
|
1263
1295
|
toTeamName: message.toTeam,
|
|
@@ -1271,25 +1303,50 @@ var HubServer = class {
|
|
|
1271
1303
|
status: result.status,
|
|
1272
1304
|
requestId: message.requestId
|
|
1273
1305
|
});
|
|
1306
|
+
log("INFO", "Question sent successfully", {
|
|
1307
|
+
questionId: result.questionId,
|
|
1308
|
+
fromMemberId: connection.memberId,
|
|
1309
|
+
toTeamId: result.toTeamId
|
|
1310
|
+
});
|
|
1274
1311
|
} catch (error) {
|
|
1275
1312
|
const errorMessage = error instanceof Error ? error.message : "Ask failed";
|
|
1313
|
+
log("ERROR", "Question failed", {
|
|
1314
|
+
fromMemberId: connection.memberId,
|
|
1315
|
+
toTeam: message.toTeam,
|
|
1316
|
+
error: errorMessage
|
|
1317
|
+
});
|
|
1276
1318
|
this.send(ws, createErrorMessage("ASK_FAILED", errorMessage, message.requestId));
|
|
1277
1319
|
}
|
|
1278
1320
|
}
|
|
1279
1321
|
async handleReply(ws, connection, message) {
|
|
1280
1322
|
if (!connection.memberId) {
|
|
1323
|
+
log("WARN", "REPLY attempt without joining team", { questionId: message.questionId });
|
|
1281
1324
|
this.send(ws, createErrorMessage("NOT_JOINED", "Must join a team first"));
|
|
1282
1325
|
return;
|
|
1283
1326
|
}
|
|
1284
1327
|
try {
|
|
1328
|
+
log("INFO", "Reply received", {
|
|
1329
|
+
fromMemberId: connection.memberId,
|
|
1330
|
+
questionId: message.questionId,
|
|
1331
|
+
contentPreview: message.content.substring(0, 50) + "..."
|
|
1332
|
+
});
|
|
1285
1333
|
await this.replyQuestionUseCase.execute({
|
|
1286
1334
|
fromMemberId: connection.memberId,
|
|
1287
1335
|
questionId: message.questionId,
|
|
1288
1336
|
content: message.content,
|
|
1289
1337
|
format: message.format
|
|
1290
1338
|
});
|
|
1339
|
+
log("INFO", "Reply delivered successfully", {
|
|
1340
|
+
fromMemberId: connection.memberId,
|
|
1341
|
+
questionId: message.questionId
|
|
1342
|
+
});
|
|
1291
1343
|
} catch (error) {
|
|
1292
1344
|
const errorMessage = error instanceof Error ? error.message : "Reply failed";
|
|
1345
|
+
log("ERROR", "Reply failed", {
|
|
1346
|
+
fromMemberId: connection.memberId,
|
|
1347
|
+
questionId: message.questionId,
|
|
1348
|
+
error: errorMessage
|
|
1349
|
+
});
|
|
1293
1350
|
this.send(ws, createErrorMessage("REPLY_FAILED", errorMessage));
|
|
1294
1351
|
}
|
|
1295
1352
|
}
|
|
@@ -1329,10 +1386,15 @@ var HubServer = class {
|
|
|
1329
1386
|
async handleDisconnect(ws) {
|
|
1330
1387
|
const connection = this.clients.get(ws);
|
|
1331
1388
|
if (connection?.memberId && connection.teamId) {
|
|
1389
|
+
log("INFO", "Client disconnecting", {
|
|
1390
|
+
memberId: connection.memberId,
|
|
1391
|
+
teamId: connection.teamId
|
|
1392
|
+
});
|
|
1332
1393
|
await this.removeMember(connection.memberId, connection.teamId);
|
|
1333
1394
|
this.memberToWs.delete(connection.memberId);
|
|
1334
1395
|
}
|
|
1335
1396
|
this.clients.delete(ws);
|
|
1397
|
+
log("INFO", "Client disconnected", { totalClients: this.clients.size });
|
|
1336
1398
|
}
|
|
1337
1399
|
async removeMember(memberId, teamId) {
|
|
1338
1400
|
const member = await this.memberRepository.findById(memberId);
|
|
@@ -1353,10 +1415,19 @@ var HubServer = class {
|
|
|
1353
1415
|
}
|
|
1354
1416
|
async deliverQuestion(question) {
|
|
1355
1417
|
const team = await this.teamRepository.findById(question.toTeamId);
|
|
1356
|
-
if (!team)
|
|
1418
|
+
if (!team) {
|
|
1419
|
+
log("WARN", "Cannot deliver question - team not found", { toTeamId: question.toTeamId });
|
|
1420
|
+
return;
|
|
1421
|
+
}
|
|
1357
1422
|
const fromMember = await this.memberRepository.findById(question.fromMemberId);
|
|
1358
|
-
if (!fromMember)
|
|
1423
|
+
if (!fromMember) {
|
|
1424
|
+
log("WARN", "Cannot deliver question - from member not found", {
|
|
1425
|
+
fromMemberId: question.fromMemberId
|
|
1426
|
+
});
|
|
1427
|
+
return;
|
|
1428
|
+
}
|
|
1359
1429
|
const memberInfo = await this.getMemberInfo(question.fromMemberId);
|
|
1430
|
+
let deliveredCount = 0;
|
|
1360
1431
|
for (const memberId of team.memberIds) {
|
|
1361
1432
|
const ws = this.memberToWs.get(memberId);
|
|
1362
1433
|
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
@@ -1368,12 +1439,25 @@ var HubServer = class {
|
|
|
1368
1439
|
format: question.content.format,
|
|
1369
1440
|
createdAt: question.createdAt.toISOString()
|
|
1370
1441
|
});
|
|
1442
|
+
deliveredCount++;
|
|
1371
1443
|
}
|
|
1372
1444
|
}
|
|
1445
|
+
log("INFO", "Question delivered to team", {
|
|
1446
|
+
questionId: question.id,
|
|
1447
|
+
toTeamId: question.toTeamId,
|
|
1448
|
+
teamSize: team.memberIds.size,
|
|
1449
|
+
deliveredCount
|
|
1450
|
+
});
|
|
1373
1451
|
}
|
|
1374
1452
|
async deliverAnswer(question, answer, answeredByMemberId) {
|
|
1375
1453
|
const ws = this.memberToWs.get(question.fromMemberId);
|
|
1376
|
-
if (!ws || ws.readyState !== WebSocket.OPEN)
|
|
1454
|
+
if (!ws || ws.readyState !== WebSocket.OPEN) {
|
|
1455
|
+
log("WARN", "Cannot deliver answer - questioner not connected", {
|
|
1456
|
+
questionId: question.id,
|
|
1457
|
+
fromMemberId: question.fromMemberId
|
|
1458
|
+
});
|
|
1459
|
+
return;
|
|
1460
|
+
}
|
|
1377
1461
|
const memberInfo = await this.getMemberInfo(answeredByMemberId);
|
|
1378
1462
|
this.send(ws, {
|
|
1379
1463
|
type: "ANSWER",
|
|
@@ -1383,6 +1467,11 @@ var HubServer = class {
|
|
|
1383
1467
|
format: answer.content.format,
|
|
1384
1468
|
answeredAt: answer.createdAt.toISOString()
|
|
1385
1469
|
});
|
|
1470
|
+
log("INFO", "Answer delivered", {
|
|
1471
|
+
questionId: question.id,
|
|
1472
|
+
answeredBy: answeredByMemberId,
|
|
1473
|
+
deliveredTo: question.fromMemberId
|
|
1474
|
+
});
|
|
1386
1475
|
}
|
|
1387
1476
|
async broadcastToTeam(teamId, excludeMemberId, message) {
|
|
1388
1477
|
const team = await this.teamRepository.findById(teamId);
|