@lifeaitools/clauth 1.5.45 → 1.5.47
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 -133
- package/package.json +1 -1
package/cli/commands/serve.js
CHANGED
|
@@ -5149,154 +5149,108 @@ function stopTerminalSession(session_id) {
|
|
|
5149
5149
|
return { stopped: true, session_id };
|
|
5150
5150
|
}
|
|
5151
5151
|
|
|
5152
|
-
// ──
|
|
5153
|
-
// claude.ai sends messages by writing to inbox files. A running /rdc:collab
|
|
5154
|
-
// CLI session watches inbox, acts, writes responses to outbox. clauth reads
|
|
5155
|
-
// outbox and returns them to claude.ai via chitchat_recv. Dave can watch the
|
|
5156
|
-
// terminal, interject, and see exactly what Claude Code is doing.
|
|
5152
|
+
// ── ClaudeAItoCLI — realtime collab between claude.ai and a running Claude Code terminal ──
|
|
5157
5153
|
//
|
|
5158
|
-
//
|
|
5154
|
+
// Flow:
|
|
5155
|
+
// claude.ai calls chitchat_start(name)
|
|
5156
|
+
// → clauth creates session, spawns a visible Windows Terminal running:
|
|
5157
|
+
// claude /rdc:collab --session <id>
|
|
5158
|
+
// → clauth queues a greeting to outbox so claude.ai gets an immediate reply
|
|
5159
|
+
// claude.ai calls chitchat_send(id, msg) → pushes to in-memory inbox queue
|
|
5160
|
+
// Claude Code calls chitchat_poll(id) → shifts from inbox queue
|
|
5161
|
+
// Claude Code calls chitchat_reply(id, msg) → pushes to in-memory outbox queue
|
|
5162
|
+
// claude.ai calls chitchat_recv(id) → shifts from outbox queue
|
|
5159
5163
|
//
|
|
5160
|
-
//
|
|
5161
|
-
// Falls back to C:/Dev/regen-root if vault is locked or no mount configured.
|
|
5164
|
+
// Pure in-memory. No files. No CLI spawning on send/recv.
|
|
5162
5165
|
|
|
5163
|
-
const
|
|
5166
|
+
const CHITCHAT_CWD = 'C:/Dev/regen-root';
|
|
5164
5167
|
|
|
5165
|
-
async function
|
|
5166
|
-
try {
|
|
5167
|
-
const { mounts } = await getFileserverMounts(vault);
|
|
5168
|
-
if (mounts && mounts.length > 0) return mounts[0].path;
|
|
5169
|
-
} catch {}
|
|
5170
|
-
return CHITCHAT_FALLBACK_CWD;
|
|
5171
|
-
}
|
|
5172
|
-
|
|
5173
|
-
function chitchatSessionDir(rootPath, session_id) {
|
|
5174
|
-
return path.join(rootPath, '.rdc', 'relay', 'sessions', session_id);
|
|
5175
|
-
}
|
|
5176
|
-
|
|
5177
|
-
async function startChitchatSession(name, vault) {
|
|
5178
|
-
const rootPath = await resolveChitchatRoot(vault);
|
|
5168
|
+
async function startChitchatSession(name) {
|
|
5179
5169
|
const session_id = generateSessionId();
|
|
5180
|
-
const sessionDir = chitchatSessionDir(rootPath, session_id);
|
|
5181
|
-
|
|
5182
|
-
// Create inbox + outbox dirs
|
|
5183
|
-
fs.mkdirSync(path.join(sessionDir, 'inbox'), { recursive: true });
|
|
5184
|
-
fs.mkdirSync(path.join(sessionDir, 'outbox'), { recursive: true });
|
|
5185
|
-
|
|
5186
|
-
// Write session metadata
|
|
5187
|
-
fs.writeFileSync(path.join(sessionDir, 'status.json'), JSON.stringify({
|
|
5188
|
-
session_id,
|
|
5189
|
-
name,
|
|
5190
|
-
status: 'waiting',
|
|
5191
|
-
started_at: new Date().toISOString(),
|
|
5192
|
-
cwd: rootPath,
|
|
5193
|
-
}, null, 2));
|
|
5194
|
-
|
|
5195
5170
|
const session = {
|
|
5196
5171
|
session_id,
|
|
5197
5172
|
name,
|
|
5198
|
-
status: '
|
|
5173
|
+
status: 'ready',
|
|
5199
5174
|
started_at: new Date().toISOString(),
|
|
5200
5175
|
is_chitchat: true,
|
|
5201
|
-
cwd: rootPath,
|
|
5202
|
-
sessionDir,
|
|
5203
5176
|
turn: 0,
|
|
5204
|
-
|
|
5205
|
-
|
|
5177
|
+
inbox: [], // claude.ai → Claude Code
|
|
5178
|
+
outbox: [], // Claude Code → claude.ai
|
|
5206
5179
|
};
|
|
5207
5180
|
terminalSessions.set(session_id, session);
|
|
5208
|
-
console.log(`[chitchat] started session ${session_id} name=${name} dir=${sessionDir}`);
|
|
5209
5181
|
|
|
5210
|
-
|
|
5211
|
-
|
|
5212
|
-
|
|
5213
|
-
|
|
5214
|
-
|
|
5215
|
-
|
|
5216
|
-
|
|
5217
|
-
|
|
5218
|
-
|
|
5182
|
+
// Spawn a visible Windows Terminal running /rdc:collab --session <id>
|
|
5183
|
+
const binary = findClaudeBinary();
|
|
5184
|
+
if (binary) {
|
|
5185
|
+
try {
|
|
5186
|
+
const cmd = `start cmd /k "cd /d ${CHITCHAT_CWD} && ${binary} /rdc:collab --session ${session_id}"`;
|
|
5187
|
+
require('child_process').exec(cmd, { shell: true });
|
|
5188
|
+
console.log(`[ClaudeAItoCLI] spawned terminal for session ${session_id}`);
|
|
5189
|
+
} catch (err) {
|
|
5190
|
+
console.warn(`[ClaudeAItoCLI] could not spawn terminal: ${err.message}`);
|
|
5191
|
+
}
|
|
5192
|
+
} else {
|
|
5193
|
+
console.warn(`[ClaudeAItoCLI] claude CLI not found — terminal not spawned. Run /rdc:collab --session ${session_id} manually.`);
|
|
5194
|
+
}
|
|
5195
|
+
|
|
5196
|
+
// Queue greeting so claude.ai gets an immediate response on first chitchat_recv
|
|
5197
|
+
session.outbox.push({
|
|
5198
|
+
turn: 0,
|
|
5199
|
+
message: `Hey! Claude Code is live — session ${session_id} ready. What's up?`,
|
|
5200
|
+
sent_at: new Date().toISOString(),
|
|
5201
|
+
});
|
|
5202
|
+
|
|
5203
|
+
console.log(`[ClaudeAItoCLI] started session ${session_id} name=${name}`);
|
|
5204
|
+
return { session_id, status: 'ready', name };
|
|
5219
5205
|
}
|
|
5220
5206
|
|
|
5207
|
+
// claude.ai → inbox (Claude Code reads via chitchat_poll)
|
|
5221
5208
|
function sendChitchatMessage(session_id, message) {
|
|
5222
5209
|
const session = terminalSessions.get(session_id);
|
|
5223
|
-
if (!session) return { error: 'not_found', message: `
|
|
5224
|
-
if (!session.is_chitchat) return { error: 'wrong_type', message: '
|
|
5210
|
+
if (!session) return { error: 'not_found', message: `Session ${session_id} not found` };
|
|
5211
|
+
if (!session.is_chitchat) return { error: 'wrong_type', message: 'Not a ClaudeAItoCLI session' };
|
|
5225
5212
|
if (session.status === 'stopped') return { error: 'stopped', message: 'Session is stopped' };
|
|
5226
5213
|
|
|
5227
|
-
const ts = new Date().toISOString().replace(/[:.]/g, '-');
|
|
5228
5214
|
session.turn = (session.turn || 0) + 1;
|
|
5229
|
-
const
|
|
5230
|
-
|
|
5231
|
-
|
|
5232
|
-
|
|
5233
|
-
'---',
|
|
5234
|
-
`from: claude-ai`,
|
|
5235
|
-
`to: claude-code`,
|
|
5236
|
-
`session_id: ${session_id}`,
|
|
5237
|
-
`turn: ${session.turn}`,
|
|
5238
|
-
`sent_at: ${new Date().toISOString()}`,
|
|
5239
|
-
`status: pending`,
|
|
5240
|
-
'---',
|
|
5241
|
-
'',
|
|
5242
|
-
message,
|
|
5243
|
-
].join('\n');
|
|
5244
|
-
|
|
5245
|
-
try {
|
|
5246
|
-
fs.writeFileSync(inboxPath, content, 'utf-8');
|
|
5247
|
-
} catch (err) {
|
|
5248
|
-
return { error: 'write_failed', message: `Could not write to inbox: ${err.message}` };
|
|
5249
|
-
}
|
|
5250
|
-
|
|
5251
|
-
session.status = 'busy';
|
|
5252
|
-
console.log(`[chitchat] session ${session_id} turn=${session.turn} message written to inbox`);
|
|
5253
|
-
return { queued: true, session_id, turn: session.turn, inbox_file: filename };
|
|
5215
|
+
const turn = session.turn;
|
|
5216
|
+
session.inbox.push({ turn, message, sent_at: new Date().toISOString() });
|
|
5217
|
+
console.log(`[ClaudeAItoCLI] session ${session_id} turn=${turn} message queued`);
|
|
5218
|
+
return { queued: true, session_id, turn };
|
|
5254
5219
|
}
|
|
5255
5220
|
|
|
5221
|
+
// claude.ai ← outbox (drains all pending replies in one call)
|
|
5256
5222
|
function recvChitchatResponse(session_id) {
|
|
5257
5223
|
const session = terminalSessions.get(session_id);
|
|
5258
|
-
if (!session) return { error: 'not_found', message: `
|
|
5224
|
+
if (!session) return { error: 'not_found', message: `Session ${session_id} not found` };
|
|
5259
5225
|
|
|
5260
|
-
const
|
|
5261
|
-
|
|
5262
|
-
try {
|
|
5263
|
-
files = fs.readdirSync(outboxDir).filter(f => f.endsWith('.md')).sort();
|
|
5264
|
-
} catch {
|
|
5265
|
-
return { session_id, status: session.status, turn: session.turn || 0, response: null,
|
|
5266
|
-
message: 'Outbox not readable — is /rdc:collab running?' };
|
|
5267
|
-
}
|
|
5226
|
+
const messages = session.outbox.splice(0);
|
|
5227
|
+
if (!messages.length) return { session_id, status: 'busy', count: 0, messages: [] };
|
|
5268
5228
|
|
|
5269
|
-
|
|
5270
|
-
|
|
5271
|
-
|
|
5272
|
-
? 'Waiting for /rdc:collab to connect — open your terminal and run it'
|
|
5273
|
-
: 'Claude Code is working — poll again in a few seconds' };
|
|
5274
|
-
}
|
|
5229
|
+
console.log(`[ClaudeAItoCLI] session ${session_id} dequeued ${messages.length} response(s)`);
|
|
5230
|
+
return { session_id, status: 'ready', count: messages.length, messages };
|
|
5231
|
+
}
|
|
5275
5232
|
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
const
|
|
5279
|
-
|
|
5280
|
-
try {
|
|
5281
|
-
raw = fs.readFileSync(responsePath, 'utf-8');
|
|
5282
|
-
} catch (err) {
|
|
5283
|
-
return { error: 'read_failed', message: `Could not read outbox: ${err.message}` };
|
|
5284
|
-
}
|
|
5233
|
+
// Claude Code reads all pending messages from claude.ai in one call
|
|
5234
|
+
function pollChitchatMessage(session_id) {
|
|
5235
|
+
const session = terminalSessions.get(session_id);
|
|
5236
|
+
if (!session) return { error: 'not_found', message: `Session ${session_id} not found` };
|
|
5285
5237
|
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
const respondedAt = new Date().toISOString();
|
|
5238
|
+
const messages = session.inbox.splice(0);
|
|
5239
|
+
if (!messages.length) return { session_id, status: 'idle', count: 0, messages: [] };
|
|
5289
5240
|
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5241
|
+
console.log(`[ClaudeAItoCLI] session ${session_id} dequeued ${messages.length} message(s)`);
|
|
5242
|
+
return { session_id, status: 'ready', count: messages.length, messages };
|
|
5243
|
+
}
|
|
5293
5244
|
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
session
|
|
5297
|
-
|
|
5245
|
+
// Claude Code sends response back to claude.ai
|
|
5246
|
+
function replyChitchatMessage(session_id, message) {
|
|
5247
|
+
const session = terminalSessions.get(session_id);
|
|
5248
|
+
if (!session) return { error: 'not_found', message: `Session ${session_id} not found` };
|
|
5249
|
+
if (!session.is_chitchat) return { error: 'wrong_type', message: 'Not a ClaudeAItoCLI session' };
|
|
5298
5250
|
|
|
5299
|
-
|
|
5251
|
+
session.outbox.push({ turn: session.turn, message, sent_at: new Date().toISOString() });
|
|
5252
|
+
console.log(`[ClaudeAItoCLI] session ${session_id} reply queued turn=${session.turn}`);
|
|
5253
|
+
return { queued: true, session_id, turn: session.turn };
|
|
5300
5254
|
}
|
|
5301
5255
|
|
|
5302
5256
|
function listChitchatSessions() {
|
|
@@ -5320,25 +5274,11 @@ function stopChitchatSession(session_id) {
|
|
|
5320
5274
|
const session = terminalSessions.get(session_id);
|
|
5321
5275
|
if (!session) return { error: 'not_found', message: `Session ${session_id} not found` };
|
|
5322
5276
|
|
|
5323
|
-
//
|
|
5324
|
-
|
|
5325
|
-
const ts = new Date().toISOString().replace(/[:.]/g, '-');
|
|
5326
|
-
const stopFile = path.join(session.sessionDir, 'inbox', `${ts}-stop.md`);
|
|
5327
|
-
fs.writeFileSync(stopFile, [
|
|
5328
|
-
'---',
|
|
5329
|
-
'from: claude-ai',
|
|
5330
|
-
'to: claude-code',
|
|
5331
|
-
`session_id: ${session_id}`,
|
|
5332
|
-
'type: stop',
|
|
5333
|
-
`sent_at: ${new Date().toISOString()}`,
|
|
5334
|
-
'---',
|
|
5335
|
-
'',
|
|
5336
|
-
'Session ended by claude.ai. Write final summary and exit.',
|
|
5337
|
-
].join('\n'));
|
|
5338
|
-
} catch {}
|
|
5277
|
+
// Push a stop signal into the inbox so the running /rdc:collab loop knows to exit on its next poll
|
|
5278
|
+
session.inbox.push({ turn: session.turn, type: 'stop', message: 'Session ended by claude.ai.', sent_at: new Date().toISOString() });
|
|
5339
5279
|
|
|
5340
5280
|
terminalSessions.delete(session_id);
|
|
5341
|
-
console.log(`[
|
|
5281
|
+
console.log(`[ClaudeAItoCLI] stopped session ${session_id}`);
|
|
5342
5282
|
return { stopped: true, session_id };
|
|
5343
5283
|
}
|
|
5344
5284
|
|
|
@@ -5635,6 +5575,31 @@ const MCP_TOOLS = [
|
|
|
5635
5575
|
additionalProperties: false,
|
|
5636
5576
|
},
|
|
5637
5577
|
},
|
|
5578
|
+
{
|
|
5579
|
+
name: "chitchat_poll",
|
|
5580
|
+
description: "Claude Code calls this to read the next pending message from claude.ai. Returns { status: 'idle' } if nothing queued, { status: 'ready', message: '...' } when a message is waiting.",
|
|
5581
|
+
inputSchema: {
|
|
5582
|
+
type: "object",
|
|
5583
|
+
properties: {
|
|
5584
|
+
session_id: { type: "string", description: "Session ID from chitchat_start" },
|
|
5585
|
+
},
|
|
5586
|
+
required: ["session_id"],
|
|
5587
|
+
additionalProperties: false,
|
|
5588
|
+
},
|
|
5589
|
+
},
|
|
5590
|
+
{
|
|
5591
|
+
name: "chitchat_reply",
|
|
5592
|
+
description: "Claude Code calls this to send its response back to claude.ai. claude.ai retrieves it via chitchat_recv.",
|
|
5593
|
+
inputSchema: {
|
|
5594
|
+
type: "object",
|
|
5595
|
+
properties: {
|
|
5596
|
+
session_id: { type: "string", description: "Session ID from chitchat_start" },
|
|
5597
|
+
message: { type: "string", description: "Response text from Claude Code" },
|
|
5598
|
+
},
|
|
5599
|
+
required: ["session_id", "message"],
|
|
5600
|
+
additionalProperties: false,
|
|
5601
|
+
},
|
|
5602
|
+
},
|
|
5638
5603
|
|
|
5639
5604
|
// ── Google Workspace (gws CLI) ──────────────────────────────────────────
|
|
5640
5605
|
{
|
|
@@ -6426,6 +6391,22 @@ async function handleMcpTool(vault, name, args) {
|
|
|
6426
6391
|
return mcpResult(JSON.stringify(result));
|
|
6427
6392
|
}
|
|
6428
6393
|
|
|
6394
|
+
case "chitchat_poll": {
|
|
6395
|
+
const { session_id } = args;
|
|
6396
|
+
if (!session_id) return mcpError("session_id required");
|
|
6397
|
+
const result = pollChitchatMessage(session_id);
|
|
6398
|
+
if (result.error) return mcpError(`${result.error}: ${result.message}`);
|
|
6399
|
+
return mcpResult(JSON.stringify(result));
|
|
6400
|
+
}
|
|
6401
|
+
|
|
6402
|
+
case "chitchat_reply": {
|
|
6403
|
+
const { session_id, message } = args;
|
|
6404
|
+
if (!session_id || !message) return mcpError("session_id and message required");
|
|
6405
|
+
const result = replyChitchatMessage(session_id, message);
|
|
6406
|
+
if (result.error) return mcpError(`${result.error}: ${result.message}`);
|
|
6407
|
+
return mcpResult(JSON.stringify(result));
|
|
6408
|
+
}
|
|
6409
|
+
|
|
6429
6410
|
default:
|
|
6430
6411
|
return mcpError(`Unknown tool: ${name}`);
|
|
6431
6412
|
}
|