@lifeaitools/clauth 1.5.47 → 1.5.49
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/cli/commands/serve.js +114 -12
- package/package.json +1 -1
package/cli/commands/serve.js
CHANGED
|
@@ -3382,6 +3382,90 @@ function createServer(initPassword, whitelist, port, tunnelHostnameInit = null,
|
|
|
3382
3382
|
});
|
|
3383
3383
|
}
|
|
3384
3384
|
|
|
3385
|
+
// GET /chitchat/<session_id>/stream — SSE push stream for Claude Code (inbox events)
|
|
3386
|
+
// Claude Code connects once; daemon pushes an event on every chitchat_send call
|
|
3387
|
+
const inboxStreamMatch = reqPath.match(/^\/chitchat\/([^/]+)\/stream$/);
|
|
3388
|
+
if (method === "GET" && inboxStreamMatch) {
|
|
3389
|
+
const session_id = inboxStreamMatch[1];
|
|
3390
|
+
const session = terminalSessions.get(session_id);
|
|
3391
|
+
if (!session || !session.is_chitchat) {
|
|
3392
|
+
res.writeHead(404, { "Content-Type": "application/json", ...CORS });
|
|
3393
|
+
return res.end(JSON.stringify({ error: "session not found" }));
|
|
3394
|
+
}
|
|
3395
|
+
|
|
3396
|
+
res.writeHead(200, {
|
|
3397
|
+
"Content-Type": "text/event-stream",
|
|
3398
|
+
"Cache-Control": "no-cache",
|
|
3399
|
+
"Connection": "keep-alive",
|
|
3400
|
+
...CORS,
|
|
3401
|
+
});
|
|
3402
|
+
|
|
3403
|
+
// Send any already-queued inbox messages immediately
|
|
3404
|
+
if (session.inbox.length) {
|
|
3405
|
+
for (const entry of session.inbox) {
|
|
3406
|
+
res.write(`event: message\ndata: ${JSON.stringify(entry)}\n\n`);
|
|
3407
|
+
}
|
|
3408
|
+
session.inbox = [];
|
|
3409
|
+
}
|
|
3410
|
+
|
|
3411
|
+
session.inboxStreams.push(res);
|
|
3412
|
+
console.log(`[ClaudeAItoCLI] session ${session_id} inbox stream connected (${session.inboxStreams.length} total)`);
|
|
3413
|
+
|
|
3414
|
+
const keepalive = setInterval(() => {
|
|
3415
|
+
try { res.write(": keepalive\n\n"); } catch {}
|
|
3416
|
+
}, 15_000);
|
|
3417
|
+
|
|
3418
|
+
req.on("close", () => {
|
|
3419
|
+
clearInterval(keepalive);
|
|
3420
|
+
session.inboxStreams = session.inboxStreams.filter(r => r !== res);
|
|
3421
|
+
console.log(`[ClaudeAItoCLI] session ${session_id} inbox stream disconnected`);
|
|
3422
|
+
});
|
|
3423
|
+
|
|
3424
|
+
return;
|
|
3425
|
+
}
|
|
3426
|
+
|
|
3427
|
+
// GET /chitchat/<session_id>/watch — SSE push stream for claude.ai (outbox events)
|
|
3428
|
+
// claude.ai connects once; daemon pushes an event on every chitchat_reply call
|
|
3429
|
+
const outboxStreamMatch = reqPath.match(/^\/chitchat\/([^/]+)\/watch$/);
|
|
3430
|
+
if (method === "GET" && outboxStreamMatch) {
|
|
3431
|
+
const session_id = outboxStreamMatch[1];
|
|
3432
|
+
const session = terminalSessions.get(session_id);
|
|
3433
|
+
if (!session || !session.is_chitchat) {
|
|
3434
|
+
res.writeHead(404, { "Content-Type": "application/json", ...CORS });
|
|
3435
|
+
return res.end(JSON.stringify({ error: "session not found" }));
|
|
3436
|
+
}
|
|
3437
|
+
|
|
3438
|
+
res.writeHead(200, {
|
|
3439
|
+
"Content-Type": "text/event-stream",
|
|
3440
|
+
"Cache-Control": "no-cache",
|
|
3441
|
+
"Connection": "keep-alive",
|
|
3442
|
+
...CORS,
|
|
3443
|
+
});
|
|
3444
|
+
|
|
3445
|
+
// Send any already-queued outbox messages immediately
|
|
3446
|
+
if (session.outbox.length) {
|
|
3447
|
+
for (const entry of session.outbox) {
|
|
3448
|
+
res.write(`event: message\ndata: ${JSON.stringify(entry)}\n\n`);
|
|
3449
|
+
}
|
|
3450
|
+
session.outbox = [];
|
|
3451
|
+
}
|
|
3452
|
+
|
|
3453
|
+
session.outboxStreams.push(res);
|
|
3454
|
+
console.log(`[ClaudeAItoCLI] session ${session_id} outbox stream connected (${session.outboxStreams.length} total)`);
|
|
3455
|
+
|
|
3456
|
+
const keepalive = setInterval(() => {
|
|
3457
|
+
try { res.write(": keepalive\n\n"); } catch {}
|
|
3458
|
+
}, 15_000);
|
|
3459
|
+
|
|
3460
|
+
req.on("close", () => {
|
|
3461
|
+
clearInterval(keepalive);
|
|
3462
|
+
session.outboxStreams = session.outboxStreams.filter(r => r !== res);
|
|
3463
|
+
console.log(`[ClaudeAItoCLI] session ${session_id} outbox stream disconnected`);
|
|
3464
|
+
});
|
|
3465
|
+
|
|
3466
|
+
return;
|
|
3467
|
+
}
|
|
3468
|
+
|
|
3385
3469
|
// GET /debug/sessions — live view of all terminal/chitchat sessions
|
|
3386
3470
|
if (method === "GET" && reqPath === "/debug/sessions") {
|
|
3387
3471
|
const now = Date.now();
|
|
@@ -5174,8 +5258,10 @@ async function startChitchatSession(name) {
|
|
|
5174
5258
|
started_at: new Date().toISOString(),
|
|
5175
5259
|
is_chitchat: true,
|
|
5176
5260
|
turn: 0,
|
|
5177
|
-
inbox: [],
|
|
5178
|
-
outbox: [],
|
|
5261
|
+
inbox: [], // claude.ai → Claude Code
|
|
5262
|
+
outbox: [], // Claude Code → claude.ai
|
|
5263
|
+
inboxStreams: [], // SSE listeners waiting on inbox (Claude Code side)
|
|
5264
|
+
outboxStreams: [], // SSE listeners waiting on outbox (claude.ai side)
|
|
5179
5265
|
};
|
|
5180
5266
|
terminalSessions.set(session_id, session);
|
|
5181
5267
|
|
|
@@ -5183,8 +5269,8 @@ async function startChitchatSession(name) {
|
|
|
5183
5269
|
const binary = findClaudeBinary();
|
|
5184
5270
|
if (binary) {
|
|
5185
5271
|
try {
|
|
5186
|
-
const
|
|
5187
|
-
|
|
5272
|
+
const child = spawnProc('wt.exe', ['new-tab', '--title', 'rdc:collab', 'cmd', '/k', `cd /d ${CHITCHAT_CWD} && ${binary} /rdc:collab --session ${session_id}`], { detached: true, stdio: 'ignore', shell: false });
|
|
5273
|
+
child.unref();
|
|
5188
5274
|
console.log(`[ClaudeAItoCLI] spawned terminal for session ${session_id}`);
|
|
5189
5275
|
} catch (err) {
|
|
5190
5276
|
console.warn(`[ClaudeAItoCLI] could not spawn terminal: ${err.message}`);
|
|
@@ -5204,7 +5290,7 @@ async function startChitchatSession(name) {
|
|
|
5204
5290
|
return { session_id, status: 'ready', name };
|
|
5205
5291
|
}
|
|
5206
5292
|
|
|
5207
|
-
// claude.ai → inbox
|
|
5293
|
+
// claude.ai → inbox — also pushes SSE event to any connected Claude Code stream listeners
|
|
5208
5294
|
function sendChitchatMessage(session_id, message) {
|
|
5209
5295
|
const session = terminalSessions.get(session_id);
|
|
5210
5296
|
if (!session) return { error: 'not_found', message: `Session ${session_id} not found` };
|
|
@@ -5213,12 +5299,20 @@ function sendChitchatMessage(session_id, message) {
|
|
|
5213
5299
|
|
|
5214
5300
|
session.turn = (session.turn || 0) + 1;
|
|
5215
5301
|
const turn = session.turn;
|
|
5216
|
-
|
|
5217
|
-
|
|
5302
|
+
const entry = { turn, message, sent_at: new Date().toISOString() };
|
|
5303
|
+
session.inbox.push(entry);
|
|
5304
|
+
|
|
5305
|
+
// Notify any connected Claude Code SSE listeners immediately
|
|
5306
|
+
const event = `event: message\ndata: ${JSON.stringify(entry)}\n\n`;
|
|
5307
|
+
session.inboxStreams = session.inboxStreams.filter(res => {
|
|
5308
|
+
try { res.write(event); return true; } catch { return false; }
|
|
5309
|
+
});
|
|
5310
|
+
|
|
5311
|
+
console.log(`[ClaudeAItoCLI] session ${session_id} turn=${turn} queued (${session.inboxStreams.length} stream(s) notified)`);
|
|
5218
5312
|
return { queued: true, session_id, turn };
|
|
5219
5313
|
}
|
|
5220
5314
|
|
|
5221
|
-
// claude.ai ← outbox
|
|
5315
|
+
// claude.ai ← outbox — drains all pending replies in one call
|
|
5222
5316
|
function recvChitchatResponse(session_id) {
|
|
5223
5317
|
const session = terminalSessions.get(session_id);
|
|
5224
5318
|
if (!session) return { error: 'not_found', message: `Session ${session_id} not found` };
|
|
@@ -5230,7 +5324,7 @@ function recvChitchatResponse(session_id) {
|
|
|
5230
5324
|
return { session_id, status: 'ready', count: messages.length, messages };
|
|
5231
5325
|
}
|
|
5232
5326
|
|
|
5233
|
-
// Claude Code reads all pending messages
|
|
5327
|
+
// Claude Code reads all pending inbox messages in one call (fallback when not using SSE stream)
|
|
5234
5328
|
function pollChitchatMessage(session_id) {
|
|
5235
5329
|
const session = terminalSessions.get(session_id);
|
|
5236
5330
|
if (!session) return { error: 'not_found', message: `Session ${session_id} not found` };
|
|
@@ -5242,14 +5336,22 @@ function pollChitchatMessage(session_id) {
|
|
|
5242
5336
|
return { session_id, status: 'ready', count: messages.length, messages };
|
|
5243
5337
|
}
|
|
5244
5338
|
|
|
5245
|
-
// Claude Code
|
|
5339
|
+
// Claude Code → outbox — also pushes SSE event to any connected claude.ai stream listeners
|
|
5246
5340
|
function replyChitchatMessage(session_id, message) {
|
|
5247
5341
|
const session = terminalSessions.get(session_id);
|
|
5248
5342
|
if (!session) return { error: 'not_found', message: `Session ${session_id} not found` };
|
|
5249
5343
|
if (!session.is_chitchat) return { error: 'wrong_type', message: 'Not a ClaudeAItoCLI session' };
|
|
5250
5344
|
|
|
5251
|
-
|
|
5252
|
-
|
|
5345
|
+
const entry = { turn: session.turn, message, sent_at: new Date().toISOString() };
|
|
5346
|
+
session.outbox.push(entry);
|
|
5347
|
+
|
|
5348
|
+
// Notify any connected claude.ai SSE listeners immediately
|
|
5349
|
+
const event = `event: message\ndata: ${JSON.stringify(entry)}\n\n`;
|
|
5350
|
+
session.outboxStreams = session.outboxStreams.filter(res => {
|
|
5351
|
+
try { res.write(event); return true; } catch { return false; }
|
|
5352
|
+
});
|
|
5353
|
+
|
|
5354
|
+
console.log(`[ClaudeAItoCLI] session ${session_id} reply queued turn=${session.turn} (${session.outboxStreams.length} stream(s) notified)`);
|
|
5253
5355
|
return { queued: true, session_id, turn: session.turn };
|
|
5254
5356
|
}
|
|
5255
5357
|
|