claude-remote-agent 0.1.2 → 0.2.0

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/agent.js +53 -3
  2. package/package.json +1 -1
package/agent.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const crypto = require('crypto');
2
2
  const os = require('os');
3
3
  const WebSocket = require('ws');
4
- const { spawn } = require('child_process');
4
+ const { spawn, execSync } = require('child_process');
5
5
  const fs = require('fs');
6
6
  const readline = require('readline');
7
7
  const path = require('path');
@@ -213,6 +213,9 @@ async function handleRequest(msg) {
213
213
  let data;
214
214
  if (action === 'list-conversations') data = await listConversations();
215
215
  else if (action === 'get-conversation') data = await getConversation(params.file);
216
+ else if (action === 'delete-conversation') data = deleteConversation(params.file);
217
+ else if (action === 'get-settings') data = getSettings();
218
+ else if (action === 'set-model') data = setModel(params.model);
216
219
  else { sendResponse(reqId, null, 'Unknown action'); return; }
217
220
  sendResponse(reqId, data);
218
221
  } catch (err) {
@@ -352,6 +355,44 @@ async function getConversation(file) {
352
355
  return { title: aiTitle, messages };
353
356
  }
354
357
 
358
+ function deleteConversation(file) {
359
+ const filePath = path.join(CLAUDE_PROJECTS, file);
360
+ if (!filePath.startsWith(CLAUDE_PROJECTS)) throw new Error('Invalid path');
361
+ if (!fs.existsSync(filePath)) throw new Error('Not found');
362
+ fs.unlinkSync(filePath);
363
+ return { ok: true };
364
+ }
365
+
366
+ // ── Settings ──
367
+
368
+ const CLAUDE_SETTINGS = path.join(process.env.HOME, '.claude', 'settings.json');
369
+ const AVAILABLE_MODELS = [
370
+ { id: 'sonnet', name: 'Claude Sonnet', description: 'Fast and capable' },
371
+ { id: 'opus', name: 'Claude Opus', description: 'Most intelligent' },
372
+ { id: 'haiku', name: 'Claude Haiku', description: 'Fastest, lightweight' },
373
+ ];
374
+
375
+ function getSettings() {
376
+ let settings = {};
377
+ try { settings = JSON.parse(fs.readFileSync(CLAUDE_SETTINGS, 'utf-8')); } catch {}
378
+ let version = '';
379
+ try { version = execSync('claude --version', { encoding: 'utf-8', timeout: 5000 }).trim(); } catch {}
380
+ return {
381
+ model: settings.model || 'sonnet',
382
+ version,
383
+ availableModels: AVAILABLE_MODELS,
384
+ };
385
+ }
386
+
387
+ function setModel(model) {
388
+ if (!AVAILABLE_MODELS.some(m => m.id === model)) throw new Error('Invalid model');
389
+ let settings = {};
390
+ try { settings = JSON.parse(fs.readFileSync(CLAUDE_SETTINGS, 'utf-8')); } catch {}
391
+ settings.model = model;
392
+ fs.writeFileSync(CLAUDE_SETTINGS, JSON.stringify(settings, null, 2) + '\n');
393
+ return { ok: true, model };
394
+ }
395
+
355
396
  // ── Chat sessions (structured JSON mode) ──
356
397
 
357
398
  const chatSessions = new Map();
@@ -407,6 +448,8 @@ function handleChatMessage(sessionId, text, images) {
407
448
  });
408
449
 
409
450
  let buffer = '';
451
+ let lastTextLen = 0;
452
+ let sentToolIds = new Set();
410
453
 
411
454
  proc.stdout.on('data', (chunk) => {
412
455
  buffer += chunk.toString();
@@ -421,13 +464,20 @@ function handleChatMessage(sessionId, text, images) {
421
464
  session.claudeSessionId = obj.session_id;
422
465
  console.log(`[${ts()}] Chat ${sessionId.slice(0, 8)} got claude session: ${obj.session_id.slice(0, 8)}`);
423
466
  }
467
+ let fullText = '';
424
468
  for (const block of obj.message.content) {
425
469
  if (block.type === 'text') {
426
- send({ type: 'chat-text', sessionId, text: block.text, done: false });
427
- } else if (block.type === 'tool_use') {
470
+ fullText += block.text;
471
+ } else if (block.type === 'tool_use' && !sentToolIds.has(block.id)) {
472
+ sentToolIds.add(block.id);
428
473
  send({ type: 'chat-tool', sessionId, tool: block.name, input: block.input });
429
474
  }
430
475
  }
476
+ if (fullText.length > lastTextLen) {
477
+ const delta = fullText.slice(lastTextLen);
478
+ lastTextLen = fullText.length;
479
+ send({ type: 'chat-text', sessionId, text: delta, done: false });
480
+ }
431
481
  } else if (obj.type === 'result') {
432
482
  if (obj.session_id && !session.claudeSessionId) {
433
483
  session.claudeSessionId = obj.session_id;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-remote-agent",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Agent for Claude Remote — connects your machine to the relay server",
5
5
  "bin": {
6
6
  "claude-remote-agent": "./cli.js"