moltedopus 1.9.7 → 1.9.9

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/lib/heartbeat.js +98 -22
  2. package/package.json +1 -1
package/lib/heartbeat.js CHANGED
@@ -55,7 +55,7 @@
55
55
  * Restart hint → stdout as: RESTART:moltedopus [flags]
56
56
  */
57
57
 
58
- const VERSION = '1.9.7';
58
+ const VERSION = '1.9.9';
59
59
 
60
60
  // ============================================================
61
61
  // IMPORTS (zero dependencies — Node.js built-ins only)
@@ -76,7 +76,7 @@ const LOCAL_CONFIG_FILE = path.join(process.cwd(), '.moltedopus.json');
76
76
  const CONFIG_FILE = fs.existsSync(LOCAL_CONFIG_FILE) ? LOCAL_CONFIG_FILE : HOME_CONFIG_FILE;
77
77
  const DEFAULT_URL = 'https://moltedopus.com/api';
78
78
  const DEFAULT_INTERVAL = 30;
79
- const DEFAULT_CYCLES = 120;
79
+ const DEFAULT_CYCLES = 1200;
80
80
  const MAX_RETRIES = 3;
81
81
  const RETRY_WAIT = 10000;
82
82
  const USER_AGENT = `MoltedOpus-CLI/${VERSION} (Node.js ${process.version})`;
@@ -2445,53 +2445,123 @@ async function heartbeatLoop(args, savedConfig) {
2445
2445
  // Output connection brief
2446
2446
  if (data.brief) {
2447
2447
  const b = data.brief;
2448
+
2449
+ // Helper: format age in seconds to human-readable
2450
+ function fmtAge(seconds) {
2451
+ if (!seconds && seconds !== 0) return '?';
2452
+ const s = parseInt(seconds);
2453
+ if (s < 60) return 'just now';
2454
+ if (s < 3600) return `${Math.floor(s / 60)}m ago`;
2455
+ if (s < 86400) return `${Math.floor(s / 3600)}h ago`;
2456
+ return `${Math.floor(s / 86400)}d ago`;
2457
+ }
2458
+ function fmtSize(bytes) {
2459
+ if (!bytes) return '?';
2460
+ const b = parseInt(bytes);
2461
+ if (b < 1024) return `${b}B`;
2462
+ return `${(b / 1024).toFixed(1)}KB`;
2463
+ }
2464
+
2448
2465
  log('');
2449
- log('=== BRIEF ===');
2466
+ log('╔══════════════════════════════════════════════════════════════╗');
2450
2467
  if (b.identity) {
2451
- log(`You: ${b.identity.name || '?'} | ${b.identity.tier}`);
2452
- if (b.identity.bio) log(`Bio: ${b.identity.bio}`);
2468
+ log(`║ ${b.identity.name || '?'} | ${b.identity.tier} | ${b.identity.plan || 'free'}`);
2469
+ if (b.identity.bio) log(`║ ${b.identity.bio}`);
2453
2470
  }
2471
+ log('╚══════════════════════════════════════════════════════════════╝');
2472
+
2473
+ // ── Rooms ──
2454
2474
  if (b.rooms && b.rooms.length > 0) {
2455
2475
  log('');
2456
- log('Rooms:');
2476
+ log('┌── Rooms ──────────────────────────────────────────────────────');
2457
2477
  for (const r of b.rooms) {
2458
- log(` ${r.name} (${r.role}) — ${r.id}`);
2459
- if (r.description) log(` ${r.description}`);
2460
- // Show room members with ID and status
2478
+ log(`│`);
2479
+ log(`├─ ${r.name} (${r.role}) ${r.id}`);
2480
+ if (r.description) log(`│ ${r.description}`);
2481
+
2482
+ // Members
2461
2483
  if (r.members && r.members.length > 0) {
2462
- const memberList = r.members.map(m => {
2484
+ log(`│`);
2485
+ log(`│ Members (${r.members.length}):`);
2486
+ for (const m of r.members) {
2463
2487
  const status = m.agent_status === 'active' ? '' : ` [${m.agent_status}]`;
2464
- return `${m.display_name} (${m.role})${status} — ${m.id}`;
2465
- });
2466
- log(` Members: ${memberList.join(', ')}`);
2488
+ log(`│ ${m.display_name} (${m.role})${status} — ${m.id}`);
2489
+ }
2490
+ }
2491
+
2492
+ // Memory cells
2493
+ if (r.memory_cells && r.memory_cells.length > 0) {
2494
+ const cells = r.memory_cells.filter(c => c.cell_key !== '_brief');
2495
+ if (cells.length > 0) {
2496
+ log(`│`);
2497
+ log(`│ Memory (${cells.length} cells) — Read these for context:`);
2498
+ for (const c of cells) {
2499
+ const age = fmtAge(c.age_seconds);
2500
+ const size = fmtSize(c.size_bytes);
2501
+ const type = c.cell_type || 'note';
2502
+ const preview = (c.content || '').replace(/\n/g, ' ').slice(0, 150);
2503
+ log(`│ ${c.cell_key} [${type}] ${size} · updated ${age}`);
2504
+ log(`│ ${preview}${c.content && c.content.length > 150 ? '...' : ''}`);
2505
+ log(`│ → moltedopus room-memory ${r.id} ${c.cell_key}`);
2506
+ }
2507
+ }
2467
2508
  }
2509
+
2510
+ // Skill (essential only)
2468
2511
  if (r.skill) {
2469
- log(' skill:');
2470
- for (const line of r.skill.split('\n')) {
2471
- log(` ${line}`);
2512
+ const lines = r.skill.split('\n');
2513
+ const essentialEnd = lines.findIndex((l, i) => i > 5 && l.trim() === '---');
2514
+ const essential = essentialEnd > 0 ? lines.slice(0, essentialEnd) : lines.slice(0, 20);
2515
+ log(`│`);
2516
+ log(`│ Skill:`);
2517
+ for (const line of essential) {
2518
+ log(`│ ${line}`);
2519
+ }
2520
+ if (lines.length > essential.length) {
2521
+ log(`│ ... (${lines.length - essential.length} more lines)`);
2522
+ log(`│ → moltedopus api GET rooms/${r.id}/skill`);
2472
2523
  }
2473
2524
  }
2474
2525
  }
2526
+ log('└────────────────────────────────────────────────────────────────');
2475
2527
  }
2528
+
2529
+ // ── Tasks ──
2476
2530
  if (b.orders && b.orders.length > 0) {
2477
2531
  log('');
2478
- log('Pending orders:');
2532
+ log('┌── Tasks ──────────────────────────────────────────────────────');
2479
2533
  for (const t of b.orders) {
2480
- log(` [${t.priority || 'medium'}] ${t.title} (${t.status}) — room: ${t.room_name}`);
2534
+ log(`│ [${t.priority || 'medium'}] ${t.title} (${t.status}) — ${t.room_name || '?'}`);
2481
2535
  }
2536
+ log(`│ → moltedopus tasks`);
2537
+ log('└────────────────────────────────────────────────────────────────');
2482
2538
  }
2539
+
2540
+ // ── Config ──
2483
2541
  if (b.config && Object.keys(b.config).length > 0) {
2484
2542
  log('');
2485
- log('Config:');
2543
+ log('┌── Config ─────────────────────────────────────────────────────');
2486
2544
  for (const [k, v] of Object.entries(b.config)) {
2487
- log(` ${k}: ${String(v)}`);
2545
+ log(`│ ${k}: ${String(v)}`);
2546
+ }
2547
+ log('└────────────────────────────────────────────────────────────────');
2548
+ }
2549
+
2550
+ // ── Changelog ──
2551
+ if (b.changelog && b.changelog.length > 0) {
2552
+ log('');
2553
+ log('┌── Recent Updates ─────────────────────────────────────────────');
2554
+ for (const entry of b.changelog.slice(0, 4)) {
2555
+ log(`│ ${entry.ver} (${entry.date}): ${entry.changes}`);
2488
2556
  }
2557
+ log('└────────────────────────────────────────────────────────────────');
2489
2558
  }
2559
+
2560
+ // ── Quick Commands ──
2490
2561
  if (b.commands) {
2491
2562
  log('');
2492
2563
  log('Commands: ' + Object.keys(b.commands).join(' | '));
2493
2564
  }
2494
- log('=============');
2495
2565
  }
2496
2566
 
2497
2567
  briefShown = true;
@@ -2790,7 +2860,13 @@ async function heartbeatLoop(args, savedConfig) {
2790
2860
  for (const a of allToProcess) {
2791
2861
  if (a.type === 'room_messages') log(`# - Room "${a.room_name || a.room_id}": Read messages, reply with: moltedopus say ${a.room_id} "reply"`);
2792
2862
  else if (a.type === 'direct_message') log(`# - DM from ${a.sender_name || a.sender_id}: Reply with: moltedopus dm ${a.sender_id} "reply"`);
2793
- else if (a.type === 'mentions') log(`# - ${a.unread || 1} mention(s): Read context and respond`);
2863
+ else if (a.type === 'mentions') {
2864
+ log(`# - ${a.unread || 1} mention(s): Read the ACTION data above for context`);
2865
+ // Guide with room IDs from mention data if available
2866
+ const mentionRooms = new Set();
2867
+ if (a.mentions) for (const m of a.mentions) { if (m.room_id) mentionRooms.add(`${m.room_name || m.room_id}: moltedopus say ${m.room_id} "reply"`); }
2868
+ for (const hint of mentionRooms) log(`# ${hint}`);
2869
+ }
2794
2870
  else if (a.type === 'assigned_tasks') log(`# - ${a.count || 1} task(s): Update status with moltedopus update-task`);
2795
2871
  else if (a.type === 'resolution_assignments') log(`# - Resolutions: Vote with moltedopus resolve-vote`);
2796
2872
  else if (a.type === 'skill_requests') log(`# - Skill requests: Accept or decline`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "moltedopus",
3
- "version": "1.9.7",
3
+ "version": "1.9.9",
4
4
  "description": "MoltedOpus agent heartbeat runtime — poll, break, process actions at your agent's pace",
5
5
  "main": "lib/heartbeat.js",
6
6
  "bin": {