@lifeaitools/clauth 1.5.44 → 1.5.46

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.
Files changed (2) hide show
  1. package/cli/commands/serve.js +138 -71
  2. package/package.json +1 -1
@@ -5149,94 +5149,108 @@ function stopTerminalSession(session_id) {
5149
5149
  return { stopped: true, session_id };
5150
5150
  }
5151
5151
 
5152
- // ── Chitchat helpers ──────────────────────────────────────────────────────
5153
- // Wrappers around terminal session logic, pre-configured for regen-root collab.
5154
- // cwd + bootstrap path are read from the vault's first fileserver mount at
5155
- // call time — no hardcoded paths. Falls back to C:/Dev/regen-root if vault
5156
- // is locked or no fileserver mount is configured.
5157
-
5158
- const CHITCHAT_FALLBACK_CWD = 'C:/Dev/regen-root';
5159
-
5160
- async function resolveChitchatRoot(vault) {
5161
- try {
5162
- const { mounts } = await getFileserverMounts(vault);
5163
- if (mounts && mounts.length > 0) return mounts[0].path;
5164
- } catch {}
5165
- return CHITCHAT_FALLBACK_CWD;
5166
- }
5167
-
5168
- async function readBootstrapContext(rootPath) {
5169
- const bootstrapPath = path.join(rootPath, '.rdc', 'guides', 'agent-bootstrap.md');
5170
- try {
5171
- return fs.readFileSync(bootstrapPath, 'utf-8');
5172
- } catch {
5173
- return `# agent-bootstrap.md not found at ${bootstrapPath} — proceeding without corpus context\n`;
5174
- }
5175
- }
5176
-
5177
- async function startChitchatSession(name, vault) {
5178
- const rootPath = await resolveChitchatRoot(vault);
5179
- const corpus = await readBootstrapContext(rootPath);
5152
+ // ── ClaudeAItoCLI realtime collab between claude.ai and a running Claude Code terminal ──
5153
+ //
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
5163
+ //
5164
+ // Pure in-memory. No files. No CLI spawning on send/recv.
5165
+
5166
+ const CHITCHAT_CWD = 'C:/Dev/regen-root';
5167
+
5168
+ async function startChitchatSession(name) {
5180
5169
  const session_id = generateSessionId();
5181
- const preamble = `${corpus}\n\n---\nCollab session: ${name} | cwd: ${rootPath}\nRead the bootstrap above. Ready to receive tasks from claude.ai.`;
5182
5170
  const session = {
5183
5171
  session_id,
5184
5172
  name,
5185
- knowledge_tier: 'corpus',
5186
5173
  status: 'ready',
5187
5174
  started_at: new Date().toISOString(),
5188
- context: preamble,
5189
- activeProc: null,
5190
5175
  is_chitchat: true,
5191
- cwd: rootPath,
5176
+ turn: 0,
5177
+ inbox: [], // claude.ai → Claude Code
5178
+ outbox: [], // Claude Code → claude.ai
5192
5179
  };
5193
5180
  terminalSessions.set(session_id, session);
5194
- console.log(`[chitchat] started session ${session_id} name=${name} cwd=${rootPath}`);
5195
- return { session_id, status: 'ready', name, cwd: rootPath };
5181
+
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 };
5196
5205
  }
5197
5206
 
5207
+ // claude.ai → inbox (Claude Code reads via chitchat_poll)
5198
5208
  function sendChitchatMessage(session_id, message) {
5199
5209
  const session = terminalSessions.get(session_id);
5200
- if (!session) return { error: 'not_found', message: `Chitchat session ${session_id} not found` };
5201
- if (!session.is_chitchat) return { error: 'wrong_type', message: 'Use terminal_send for non-chitchat sessions' };
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' };
5202
5212
  if (session.status === 'stopped') return { error: 'stopped', message: 'Session is stopped' };
5203
- if (session.status === 'busy') return { error: 'session_busy', message: 'Session is busy — try again shortly' };
5204
5213
 
5205
- const binary = findClaudeBinary();
5206
- if (!binary) return { error: 'binary_not_found', message: 'claude CLI not found in PATH or AppData/npm' };
5214
+ session.turn = (session.turn || 0) + 1;
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 };
5219
+ }
5207
5220
 
5208
- session.status = 'busy';
5209
- const fullPrompt = `${session.context}\n\n---\nFrom claude.ai: ${message}`;
5221
+ // claude.ai outbox (Claude Code writes via chitchat_reply)
5222
+ function recvChitchatResponse(session_id) {
5223
+ const session = terminalSessions.get(session_id);
5224
+ if (!session) return { error: 'not_found', message: `Session ${session_id} not found` };
5210
5225
 
5211
- const proc = spawnProc(binary, ['-p', fullPrompt, '--dangerously-skip-permissions'], {
5212
- cwd: session.cwd,
5213
- env: process.env,
5214
- stdio: ['ignore', 'pipe', 'pipe'],
5215
- shell: true,
5216
- });
5217
- session.activeProc = proc;
5226
+ const msg = session.outbox.shift();
5227
+ if (!msg) return { session_id, status: 'busy', turn: session.turn || 0, response: null, message: 'Claude Code is working — poll again shortly' };
5218
5228
 
5219
- let stdout = '';
5220
- let stderr = '';
5221
- proc.stdout.on('data', d => { stdout += d; });
5222
- proc.stderr.on('data', d => { stderr += d; });
5223
- proc.on('close', (code) => {
5224
- if (terminalSessions.has(session_id)) {
5225
- const s = terminalSessions.get(session_id);
5226
- const response = stdout.trim() || stderr.trim() || '(no output)';
5227
- const turn = `\n\nFrom claude.ai: ${message}\nClaude Code: ${response}`;
5228
- const combined = s.context + turn;
5229
- s.context = combined.length > 8000 ? combined.slice(combined.length - 8000) : combined;
5230
- s.lastResponse = response;
5231
- s.lastResponseAt = new Date().toISOString();
5232
- s.turn = (s.turn || 0) + 1;
5233
- s.status = 'ready';
5234
- s.activeProc = null;
5235
- console.log(`[chitchat] session ${session_id} turn=${s.turn} complete code=${code}`);
5236
- }
5237
- });
5229
+ console.log(`[ClaudeAItoCLI] session ${session_id} response dequeued turn=${msg.turn}`);
5230
+ return { session_id, status: 'ready', turn: msg.turn, response: msg.message, responded_at: msg.sent_at };
5231
+ }
5238
5232
 
5239
- return { queued: true, session_id };
5233
+ // Claude Code reads next message from claude.ai
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` };
5237
+
5238
+ const msg = session.inbox.shift();
5239
+ if (!msg) return { session_id, status: 'idle', turn: session.turn || 0, message: null };
5240
+
5241
+ console.log(`[ClaudeAItoCLI] session ${session_id} message dequeued turn=${msg.turn}`);
5242
+ return { session_id, status: 'ready', turn: msg.turn, message: msg.message, sent_at: msg.sent_at };
5243
+ }
5244
+
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' };
5250
+
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 };
5240
5254
  }
5241
5255
 
5242
5256
  function listChitchatSessions() {
@@ -5256,6 +5270,18 @@ function listChitchatSessions() {
5256
5270
  return sessions;
5257
5271
  }
5258
5272
 
5273
+ function stopChitchatSession(session_id) {
5274
+ const session = terminalSessions.get(session_id);
5275
+ if (!session) return { error: 'not_found', message: `Session ${session_id} not found` };
5276
+
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() });
5279
+
5280
+ terminalSessions.delete(session_id);
5281
+ console.log(`[ClaudeAItoCLI] stopped session ${session_id}`);
5282
+ return { stopped: true, session_id };
5283
+ }
5284
+
5259
5285
  const ENV_MAP = {
5260
5286
  "github": "GITHUB_TOKEN",
5261
5287
  "supabase-anon": "NEXT_PUBLIC_SUPABASE_ANON_KEY",
@@ -5549,6 +5575,31 @@ const MCP_TOOLS = [
5549
5575
  additionalProperties: false,
5550
5576
  },
5551
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
+ },
5552
5603
 
5553
5604
  // ── Google Workspace (gws CLI) ──────────────────────────────────────────
5554
5605
  {
@@ -6323,7 +6374,7 @@ async function handleMcpTool(vault, name, args) {
6323
6374
  case "chitchat_recv": {
6324
6375
  const { session_id } = args;
6325
6376
  if (!session_id) return mcpError("session_id required");
6326
- const result = recvTerminalResponse(session_id);
6377
+ const result = recvChitchatResponse(session_id);
6327
6378
  if (result.error) return mcpError(`${result.error}: ${result.message}`);
6328
6379
  return mcpResult(JSON.stringify(result));
6329
6380
  }
@@ -6335,7 +6386,23 @@ async function handleMcpTool(vault, name, args) {
6335
6386
  case "chitchat_stop": {
6336
6387
  const { session_id } = args;
6337
6388
  if (!session_id) return mcpError("session_id required");
6338
- const result = stopTerminalSession(session_id);
6389
+ const result = stopChitchatSession(session_id);
6390
+ if (result.error) return mcpError(`${result.error}: ${result.message}`);
6391
+ return mcpResult(JSON.stringify(result));
6392
+ }
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);
6339
6406
  if (result.error) return mcpError(`${result.error}: ${result.message}`);
6340
6407
  return mcpResult(JSON.stringify(result));
6341
6408
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifeaitools/clauth",
3
- "version": "1.5.44",
3
+ "version": "1.5.46",
4
4
  "description": "Hardware-bound credential vault for the LIFEAI infrastructure stack",
5
5
  "type": "module",
6
6
  "bin": {