@lifeaitools/clauth 1.5.44 → 1.5.45

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 +139 -53
  2. package/package.json +1 -1
@@ -5149,11 +5149,16 @@ 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.
5152
+ // ── Chitchat helpers — file-relay transport ───────────────────────────────
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.
5157
+ //
5158
+ // Session dirs: <root>/.rdc/relay/sessions/<session_id>/inbox/ + outbox/
5159
+ //
5160
+ // cwd is resolved from the vault's first fileserver mount at call time.
5161
+ // Falls back to C:/Dev/regen-root if vault is locked or no mount configured.
5157
5162
 
5158
5163
  const CHITCHAT_FALLBACK_CWD = 'C:/Dev/regen-root';
5159
5164
 
@@ -5165,34 +5170,52 @@ async function resolveChitchatRoot(vault) {
5165
5170
  return CHITCHAT_FALLBACK_CWD;
5166
5171
  }
5167
5172
 
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
- }
5173
+ function chitchatSessionDir(rootPath, session_id) {
5174
+ return path.join(rootPath, '.rdc', 'relay', 'sessions', session_id);
5175
5175
  }
5176
5176
 
5177
5177
  async function startChitchatSession(name, vault) {
5178
5178
  const rootPath = await resolveChitchatRoot(vault);
5179
- const corpus = await readBootstrapContext(rootPath);
5180
5179
  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.`;
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
+
5182
5195
  const session = {
5183
5196
  session_id,
5184
5197
  name,
5185
- knowledge_tier: 'corpus',
5186
- status: 'ready',
5198
+ status: 'waiting', // waiting = CLI not yet connected
5187
5199
  started_at: new Date().toISOString(),
5188
- context: preamble,
5189
- activeProc: null,
5190
5200
  is_chitchat: true,
5191
5201
  cwd: rootPath,
5202
+ sessionDir,
5203
+ turn: 0,
5204
+ lastResponse: undefined,
5205
+ lastResponseAt: undefined,
5192
5206
  };
5193
5207
  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 };
5208
+ console.log(`[chitchat] started session ${session_id} name=${name} dir=${sessionDir}`);
5209
+
5210
+ return {
5211
+ session_id,
5212
+ status: 'waiting',
5213
+ name,
5214
+ cwd: rootPath,
5215
+ next_step: `Open a terminal and run: /rdc:collab --session ${session_id}`,
5216
+ inbox: path.join(sessionDir, 'inbox'),
5217
+ outbox: path.join(sessionDir, 'outbox'),
5218
+ };
5196
5219
  }
5197
5220
 
5198
5221
  function sendChitchatMessage(session_id, message) {
@@ -5200,43 +5223,80 @@ function sendChitchatMessage(session_id, message) {
5200
5223
  if (!session) return { error: 'not_found', message: `Chitchat session ${session_id} not found` };
5201
5224
  if (!session.is_chitchat) return { error: 'wrong_type', message: 'Use terminal_send for non-chitchat sessions' };
5202
5225
  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
5226
 
5205
- const binary = findClaudeBinary();
5206
- if (!binary) return { error: 'binary_not_found', message: 'claude CLI not found in PATH or AppData/npm' };
5227
+ const ts = new Date().toISOString().replace(/[:.]/g, '-');
5228
+ session.turn = (session.turn || 0) + 1;
5229
+ const filename = `${ts}-turn${session.turn}.md`;
5230
+ const inboxPath = path.join(session.sessionDir, 'inbox', filename);
5231
+
5232
+ const content = [
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
+ }
5207
5250
 
5208
5251
  session.status = 'busy';
5209
- const fullPrompt = `${session.context}\n\n---\nFrom claude.ai: ${message}`;
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 };
5254
+ }
5210
5255
 
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;
5256
+ function recvChitchatResponse(session_id) {
5257
+ const session = terminalSessions.get(session_id);
5258
+ if (!session) return { error: 'not_found', message: `Chitchat session ${session_id} not found` };
5218
5259
 
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
- });
5260
+ const outboxDir = path.join(session.sessionDir, 'outbox');
5261
+ let files;
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
+ }
5238
5268
 
5239
- return { queued: true, session_id };
5269
+ if (files.length === 0) {
5270
+ return { session_id, status: 'busy', turn: session.turn || 0, response: null,
5271
+ message: session.status === 'waiting'
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
+ }
5275
+
5276
+ // Read the latest response file
5277
+ const latest = files[files.length - 1];
5278
+ const responsePath = path.join(outboxDir, latest);
5279
+ let raw;
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
+ }
5285
+
5286
+ // Strip frontmatter, return body
5287
+ const body = raw.replace(/^---[\s\S]*?---\n?/, '').trim();
5288
+ const respondedAt = new Date().toISOString();
5289
+
5290
+ // Archive the file so next recv doesn't return it again
5291
+ const archivePath = responsePath + '.processed';
5292
+ try { fs.renameSync(responsePath, archivePath); } catch {}
5293
+
5294
+ session.status = 'ready';
5295
+ session.lastResponse = body;
5296
+ session.lastResponseAt = respondedAt;
5297
+ console.log(`[chitchat] session ${session_id} response received from outbox file=${latest}`);
5298
+
5299
+ return { session_id, status: 'ready', turn: session.turn || 0, response: body, responded_at: respondedAt };
5240
5300
  }
5241
5301
 
5242
5302
  function listChitchatSessions() {
@@ -5256,6 +5316,32 @@ function listChitchatSessions() {
5256
5316
  return sessions;
5257
5317
  }
5258
5318
 
5319
+ function stopChitchatSession(session_id) {
5320
+ const session = terminalSessions.get(session_id);
5321
+ if (!session) return { error: 'not_found', message: `Session ${session_id} not found` };
5322
+
5323
+ // Write a stop signal to inbox so the running /rdc:collab loop knows to exit
5324
+ try {
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 {}
5339
+
5340
+ terminalSessions.delete(session_id);
5341
+ console.log(`[chitchat] stopped session ${session_id}`);
5342
+ return { stopped: true, session_id };
5343
+ }
5344
+
5259
5345
  const ENV_MAP = {
5260
5346
  "github": "GITHUB_TOKEN",
5261
5347
  "supabase-anon": "NEXT_PUBLIC_SUPABASE_ANON_KEY",
@@ -6323,7 +6409,7 @@ async function handleMcpTool(vault, name, args) {
6323
6409
  case "chitchat_recv": {
6324
6410
  const { session_id } = args;
6325
6411
  if (!session_id) return mcpError("session_id required");
6326
- const result = recvTerminalResponse(session_id);
6412
+ const result = recvChitchatResponse(session_id);
6327
6413
  if (result.error) return mcpError(`${result.error}: ${result.message}`);
6328
6414
  return mcpResult(JSON.stringify(result));
6329
6415
  }
@@ -6335,7 +6421,7 @@ async function handleMcpTool(vault, name, args) {
6335
6421
  case "chitchat_stop": {
6336
6422
  const { session_id } = args;
6337
6423
  if (!session_id) return mcpError("session_id required");
6338
- const result = stopTerminalSession(session_id);
6424
+ const result = stopChitchatSession(session_id);
6339
6425
  if (result.error) return mcpError(`${result.error}: ${result.message}`);
6340
6426
  return mcpResult(JSON.stringify(result));
6341
6427
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lifeaitools/clauth",
3
- "version": "1.5.44",
3
+ "version": "1.5.45",
4
4
  "description": "Hardware-bound credential vault for the LIFEAI infrastructure stack",
5
5
  "type": "module",
6
6
  "bin": {