@dolusoft/claude-collab 0.1.0 → 0.1.1
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 +96 -7
- package/dist/cli.js.map +1 -1
- package/dist/hub-main.js +96 -7
- package/dist/hub-main.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1087,6 +1087,15 @@ function createErrorMessage(code, message, requestId) {
|
|
|
1087
1087
|
}
|
|
1088
1088
|
|
|
1089
1089
|
// src/infrastructure/websocket/hub-server.ts
|
|
1090
|
+
function log(level, message, data) {
|
|
1091
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
1092
|
+
const prefix = `[${timestamp}] [HUB-${level}]`;
|
|
1093
|
+
if (data) {
|
|
1094
|
+
console.log(`${prefix} ${message}`, JSON.stringify(data, null, 2));
|
|
1095
|
+
} else {
|
|
1096
|
+
console.log(`${prefix} ${message}`);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1090
1099
|
var HubServer = class {
|
|
1091
1100
|
constructor(options = {}) {
|
|
1092
1101
|
this.options = options;
|
|
@@ -1160,11 +1169,11 @@ var HubServer = class {
|
|
|
1160
1169
|
this.handleConnection(ws);
|
|
1161
1170
|
});
|
|
1162
1171
|
this.wss.on("error", (error) => {
|
|
1163
|
-
|
|
1172
|
+
log("ERROR", "Hub server error", { error: error.message, stack: error.stack });
|
|
1164
1173
|
reject(error);
|
|
1165
1174
|
});
|
|
1166
1175
|
this.wss.on("listening", () => {
|
|
1167
|
-
|
|
1176
|
+
log("INFO", `Hub server started successfully`, { host, port });
|
|
1168
1177
|
this.startHeartbeat();
|
|
1169
1178
|
this.startTimeoutCheck();
|
|
1170
1179
|
resolve();
|
|
@@ -1195,7 +1204,7 @@ var HubServer = class {
|
|
|
1195
1204
|
this.memberToWs.clear();
|
|
1196
1205
|
this.wss.close(() => {
|
|
1197
1206
|
this.wss = null;
|
|
1198
|
-
|
|
1207
|
+
log("INFO", "Hub server stopped gracefully");
|
|
1199
1208
|
resolve();
|
|
1200
1209
|
});
|
|
1201
1210
|
} else {
|
|
@@ -1209,6 +1218,7 @@ var HubServer = class {
|
|
|
1209
1218
|
lastPing: /* @__PURE__ */ new Date()
|
|
1210
1219
|
};
|
|
1211
1220
|
this.clients.set(ws, connection);
|
|
1221
|
+
log("INFO", "New client connected", { totalClients: this.clients.size });
|
|
1212
1222
|
ws.on("message", async (data) => {
|
|
1213
1223
|
await this.handleMessage(ws, data.toString());
|
|
1214
1224
|
});
|
|
@@ -1216,7 +1226,7 @@ var HubServer = class {
|
|
|
1216
1226
|
await this.handleDisconnect(ws);
|
|
1217
1227
|
});
|
|
1218
1228
|
ws.on("error", (error) => {
|
|
1219
|
-
|
|
1229
|
+
log("ERROR", "Client connection error", { error: error.message });
|
|
1220
1230
|
});
|
|
1221
1231
|
}
|
|
1222
1232
|
async handleMessage(ws, data) {
|
|
@@ -1225,6 +1235,10 @@ var HubServer = class {
|
|
|
1225
1235
|
try {
|
|
1226
1236
|
const message = parseClientMessage(data);
|
|
1227
1237
|
connection.lastPing = /* @__PURE__ */ new Date();
|
|
1238
|
+
log("DEBUG", `Received message from client`, {
|
|
1239
|
+
type: message.type,
|
|
1240
|
+
memberId: connection.memberId
|
|
1241
|
+
});
|
|
1228
1242
|
switch (message.type) {
|
|
1229
1243
|
case "JOIN":
|
|
1230
1244
|
await this.handleJoin(ws, connection, message.teamName, message.displayName);
|
|
@@ -1247,11 +1261,16 @@ var HubServer = class {
|
|
|
1247
1261
|
}
|
|
1248
1262
|
} catch (error) {
|
|
1249
1263
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
1264
|
+
log("ERROR", "Failed to handle message", {
|
|
1265
|
+
error: errorMessage,
|
|
1266
|
+
memberId: connection.memberId
|
|
1267
|
+
});
|
|
1250
1268
|
this.send(ws, createErrorMessage("INVALID_MESSAGE", errorMessage));
|
|
1251
1269
|
}
|
|
1252
1270
|
}
|
|
1253
1271
|
async handleJoin(ws, connection, teamName, displayName) {
|
|
1254
1272
|
try {
|
|
1273
|
+
log("INFO", "Member attempting to join", { teamName, displayName });
|
|
1255
1274
|
const result = await this.joinTeamUseCase.execute({ teamName, displayName });
|
|
1256
1275
|
connection.memberId = result.memberId;
|
|
1257
1276
|
connection.teamId = result.teamId;
|
|
@@ -1262,8 +1281,15 @@ var HubServer = class {
|
|
|
1262
1281
|
member: memberInfo,
|
|
1263
1282
|
memberCount: result.memberCount
|
|
1264
1283
|
});
|
|
1284
|
+
log("INFO", "Member joined successfully", {
|
|
1285
|
+
memberId: result.memberId,
|
|
1286
|
+
teamName,
|
|
1287
|
+
displayName,
|
|
1288
|
+
memberCount: result.memberCount
|
|
1289
|
+
});
|
|
1265
1290
|
} catch (error) {
|
|
1266
1291
|
const errorMessage = error instanceof Error ? error.message : "Join failed";
|
|
1292
|
+
log("ERROR", "Member join failed", { teamName, displayName, error: errorMessage });
|
|
1267
1293
|
this.send(ws, createErrorMessage("JOIN_FAILED", errorMessage));
|
|
1268
1294
|
}
|
|
1269
1295
|
}
|
|
@@ -1277,10 +1303,16 @@ var HubServer = class {
|
|
|
1277
1303
|
}
|
|
1278
1304
|
async handleAsk(ws, connection, message) {
|
|
1279
1305
|
if (!connection.memberId) {
|
|
1306
|
+
log("WARN", "ASK attempt without joining team", { toTeam: message.toTeam });
|
|
1280
1307
|
this.send(ws, createErrorMessage("NOT_JOINED", "Must join a team first", message.requestId));
|
|
1281
1308
|
return;
|
|
1282
1309
|
}
|
|
1283
1310
|
try {
|
|
1311
|
+
log("INFO", "Question asked", {
|
|
1312
|
+
fromMemberId: connection.memberId,
|
|
1313
|
+
toTeam: message.toTeam,
|
|
1314
|
+
contentPreview: message.content.substring(0, 50) + "..."
|
|
1315
|
+
});
|
|
1284
1316
|
const result = await this.askQuestionUseCase.execute({
|
|
1285
1317
|
fromMemberId: connection.memberId,
|
|
1286
1318
|
toTeamName: message.toTeam,
|
|
@@ -1294,25 +1326,50 @@ var HubServer = class {
|
|
|
1294
1326
|
status: result.status,
|
|
1295
1327
|
requestId: message.requestId
|
|
1296
1328
|
});
|
|
1329
|
+
log("INFO", "Question sent successfully", {
|
|
1330
|
+
questionId: result.questionId,
|
|
1331
|
+
fromMemberId: connection.memberId,
|
|
1332
|
+
toTeamId: result.toTeamId
|
|
1333
|
+
});
|
|
1297
1334
|
} catch (error) {
|
|
1298
1335
|
const errorMessage = error instanceof Error ? error.message : "Ask failed";
|
|
1336
|
+
log("ERROR", "Question failed", {
|
|
1337
|
+
fromMemberId: connection.memberId,
|
|
1338
|
+
toTeam: message.toTeam,
|
|
1339
|
+
error: errorMessage
|
|
1340
|
+
});
|
|
1299
1341
|
this.send(ws, createErrorMessage("ASK_FAILED", errorMessage, message.requestId));
|
|
1300
1342
|
}
|
|
1301
1343
|
}
|
|
1302
1344
|
async handleReply(ws, connection, message) {
|
|
1303
1345
|
if (!connection.memberId) {
|
|
1346
|
+
log("WARN", "REPLY attempt without joining team", { questionId: message.questionId });
|
|
1304
1347
|
this.send(ws, createErrorMessage("NOT_JOINED", "Must join a team first"));
|
|
1305
1348
|
return;
|
|
1306
1349
|
}
|
|
1307
1350
|
try {
|
|
1351
|
+
log("INFO", "Reply received", {
|
|
1352
|
+
fromMemberId: connection.memberId,
|
|
1353
|
+
questionId: message.questionId,
|
|
1354
|
+
contentPreview: message.content.substring(0, 50) + "..."
|
|
1355
|
+
});
|
|
1308
1356
|
await this.replyQuestionUseCase.execute({
|
|
1309
1357
|
fromMemberId: connection.memberId,
|
|
1310
1358
|
questionId: message.questionId,
|
|
1311
1359
|
content: message.content,
|
|
1312
1360
|
format: message.format
|
|
1313
1361
|
});
|
|
1362
|
+
log("INFO", "Reply delivered successfully", {
|
|
1363
|
+
fromMemberId: connection.memberId,
|
|
1364
|
+
questionId: message.questionId
|
|
1365
|
+
});
|
|
1314
1366
|
} catch (error) {
|
|
1315
1367
|
const errorMessage = error instanceof Error ? error.message : "Reply failed";
|
|
1368
|
+
log("ERROR", "Reply failed", {
|
|
1369
|
+
fromMemberId: connection.memberId,
|
|
1370
|
+
questionId: message.questionId,
|
|
1371
|
+
error: errorMessage
|
|
1372
|
+
});
|
|
1316
1373
|
this.send(ws, createErrorMessage("REPLY_FAILED", errorMessage));
|
|
1317
1374
|
}
|
|
1318
1375
|
}
|
|
@@ -1352,10 +1409,15 @@ var HubServer = class {
|
|
|
1352
1409
|
async handleDisconnect(ws) {
|
|
1353
1410
|
const connection = this.clients.get(ws);
|
|
1354
1411
|
if (connection?.memberId && connection.teamId) {
|
|
1412
|
+
log("INFO", "Client disconnecting", {
|
|
1413
|
+
memberId: connection.memberId,
|
|
1414
|
+
teamId: connection.teamId
|
|
1415
|
+
});
|
|
1355
1416
|
await this.removeMember(connection.memberId, connection.teamId);
|
|
1356
1417
|
this.memberToWs.delete(connection.memberId);
|
|
1357
1418
|
}
|
|
1358
1419
|
this.clients.delete(ws);
|
|
1420
|
+
log("INFO", "Client disconnected", { totalClients: this.clients.size });
|
|
1359
1421
|
}
|
|
1360
1422
|
async removeMember(memberId, teamId) {
|
|
1361
1423
|
const member = await this.memberRepository.findById(memberId);
|
|
@@ -1376,10 +1438,19 @@ var HubServer = class {
|
|
|
1376
1438
|
}
|
|
1377
1439
|
async deliverQuestion(question) {
|
|
1378
1440
|
const team = await this.teamRepository.findById(question.toTeamId);
|
|
1379
|
-
if (!team)
|
|
1441
|
+
if (!team) {
|
|
1442
|
+
log("WARN", "Cannot deliver question - team not found", { toTeamId: question.toTeamId });
|
|
1443
|
+
return;
|
|
1444
|
+
}
|
|
1380
1445
|
const fromMember = await this.memberRepository.findById(question.fromMemberId);
|
|
1381
|
-
if (!fromMember)
|
|
1446
|
+
if (!fromMember) {
|
|
1447
|
+
log("WARN", "Cannot deliver question - from member not found", {
|
|
1448
|
+
fromMemberId: question.fromMemberId
|
|
1449
|
+
});
|
|
1450
|
+
return;
|
|
1451
|
+
}
|
|
1382
1452
|
const memberInfo = await this.getMemberInfo(question.fromMemberId);
|
|
1453
|
+
let deliveredCount = 0;
|
|
1383
1454
|
for (const memberId of team.memberIds) {
|
|
1384
1455
|
const ws = this.memberToWs.get(memberId);
|
|
1385
1456
|
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
@@ -1391,12 +1462,25 @@ var HubServer = class {
|
|
|
1391
1462
|
format: question.content.format,
|
|
1392
1463
|
createdAt: question.createdAt.toISOString()
|
|
1393
1464
|
});
|
|
1465
|
+
deliveredCount++;
|
|
1394
1466
|
}
|
|
1395
1467
|
}
|
|
1468
|
+
log("INFO", "Question delivered to team", {
|
|
1469
|
+
questionId: question.id,
|
|
1470
|
+
toTeamId: question.toTeamId,
|
|
1471
|
+
teamSize: team.memberIds.size,
|
|
1472
|
+
deliveredCount
|
|
1473
|
+
});
|
|
1396
1474
|
}
|
|
1397
1475
|
async deliverAnswer(question, answer, answeredByMemberId) {
|
|
1398
1476
|
const ws = this.memberToWs.get(question.fromMemberId);
|
|
1399
|
-
if (!ws || ws.readyState !== WebSocket.OPEN)
|
|
1477
|
+
if (!ws || ws.readyState !== WebSocket.OPEN) {
|
|
1478
|
+
log("WARN", "Cannot deliver answer - questioner not connected", {
|
|
1479
|
+
questionId: question.id,
|
|
1480
|
+
fromMemberId: question.fromMemberId
|
|
1481
|
+
});
|
|
1482
|
+
return;
|
|
1483
|
+
}
|
|
1400
1484
|
const memberInfo = await this.getMemberInfo(answeredByMemberId);
|
|
1401
1485
|
this.send(ws, {
|
|
1402
1486
|
type: "ANSWER",
|
|
@@ -1406,6 +1490,11 @@ var HubServer = class {
|
|
|
1406
1490
|
format: answer.content.format,
|
|
1407
1491
|
answeredAt: answer.createdAt.toISOString()
|
|
1408
1492
|
});
|
|
1493
|
+
log("INFO", "Answer delivered", {
|
|
1494
|
+
questionId: question.id,
|
|
1495
|
+
answeredBy: answeredByMemberId,
|
|
1496
|
+
deliveredTo: question.fromMemberId
|
|
1497
|
+
});
|
|
1409
1498
|
}
|
|
1410
1499
|
async broadcastToTeam(teamId, excludeMemberId, message) {
|
|
1411
1500
|
const team = await this.teamRepository.findById(teamId);
|