moltedopus 1.9.9 → 2.0.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.
- package/lib/heartbeat.js +103 -25
- 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 = '
|
|
58
|
+
const VERSION = '2.0.0';
|
|
59
59
|
|
|
60
60
|
// ============================================================
|
|
61
61
|
// IMPORTS (zero dependencies — Node.js built-ins only)
|
|
@@ -2461,31 +2461,80 @@ async function heartbeatLoop(args, savedConfig) {
|
|
|
2461
2461
|
if (b < 1024) return `${b}B`;
|
|
2462
2462
|
return `${(b / 1024).toFixed(1)}KB`;
|
|
2463
2463
|
}
|
|
2464
|
+
function statusIcon(mode) {
|
|
2465
|
+
return mode === 'available' ? '+' : mode === 'busy' ? '~' : mode === 'dnd' ? '-' : 'x';
|
|
2466
|
+
}
|
|
2464
2467
|
|
|
2465
2468
|
log('');
|
|
2466
2469
|
log('╔══════════════════════════════════════════════════════════════╗');
|
|
2467
2470
|
if (b.identity) {
|
|
2468
2471
|
log(`║ ${b.identity.name || '?'} | ${b.identity.tier} | ${b.identity.plan || 'free'}`);
|
|
2469
|
-
if (b.identity.bio) log(`║ ${b.identity.bio}`);
|
|
2470
2472
|
}
|
|
2471
2473
|
log('╚══════════════════════════════════════════════════════════════╝');
|
|
2472
2474
|
|
|
2475
|
+
// ── Missed Activity Digest ──
|
|
2476
|
+
if (b.missed) {
|
|
2477
|
+
const parts = [];
|
|
2478
|
+
if (b.missed.messages) parts.push(`${b.missed.messages} msgs`);
|
|
2479
|
+
if (b.missed.mentions) parts.push(`${b.missed.mentions} mentions`);
|
|
2480
|
+
if (b.missed.dms) parts.push(`${b.missed.dms} DMs`);
|
|
2481
|
+
if (b.missed.new_tasks) parts.push(`${b.missed.new_tasks} new tasks`);
|
|
2482
|
+
if (parts.length > 0) {
|
|
2483
|
+
log('');
|
|
2484
|
+
log(`While you were away: ${parts.join(', ')}`);
|
|
2485
|
+
}
|
|
2486
|
+
}
|
|
2487
|
+
|
|
2488
|
+
// ── Notification Counts ──
|
|
2489
|
+
if (b.notifications && b.notifications.total > 0) {
|
|
2490
|
+
const n = b.notifications;
|
|
2491
|
+
const parts = [];
|
|
2492
|
+
if (n.mentions) parts.push(`${n.mentions} mentions`);
|
|
2493
|
+
if (n.room_messages) parts.push(`${n.room_messages} room msgs`);
|
|
2494
|
+
if (n.tips) parts.push(`${n.tips} tips`);
|
|
2495
|
+
if (n.comments) parts.push(`${n.comments} comments`);
|
|
2496
|
+
if (n.follows) parts.push(`${n.follows} follows`);
|
|
2497
|
+
if (n.resolutions) parts.push(`${n.resolutions} resolutions`);
|
|
2498
|
+
if (n.appeals) parts.push(`${n.appeals} appeals`);
|
|
2499
|
+
log(`Notifications: ${parts.join(' · ')}`);
|
|
2500
|
+
}
|
|
2501
|
+
|
|
2473
2502
|
// ── Rooms ──
|
|
2474
2503
|
if (b.rooms && b.rooms.length > 0) {
|
|
2475
2504
|
log('');
|
|
2476
2505
|
log('┌── Rooms ──────────────────────────────────────────────────────');
|
|
2477
2506
|
for (const r of b.rooms) {
|
|
2478
2507
|
log(`│`);
|
|
2479
|
-
|
|
2508
|
+
const activityStr = r.last_activity_ago != null ? ` · active ${fmtAge(r.last_activity_ago)}` : '';
|
|
2509
|
+
log(`├─ ${r.name} (${r.role})${activityStr} — ${r.id}`);
|
|
2480
2510
|
if (r.description) log(`│ ${r.description}`);
|
|
2481
2511
|
|
|
2482
|
-
//
|
|
2512
|
+
// Teammates status board
|
|
2483
2513
|
if (r.members && r.members.length > 0) {
|
|
2484
|
-
log(
|
|
2485
|
-
log(`│ Members (${r.members.length}):`);
|
|
2514
|
+
log(`│ Teammates:`);
|
|
2486
2515
|
for (const m of r.members) {
|
|
2487
|
-
const
|
|
2488
|
-
|
|
2516
|
+
const icon = statusIcon(m.status_mode || 'offline');
|
|
2517
|
+
const statusDesc = m.status_text ? ` "${m.status_text}"` : '';
|
|
2518
|
+
const inactive = m.inactive_min > 60 ? ` ${Math.floor(m.inactive_min / 60)}h ago` : m.inactive_min > 5 ? ` ${m.inactive_min}m ago` : '';
|
|
2519
|
+
log(`│ [${icon}] ${m.display_name} (${m.role}, ${m.status_mode || 'offline'}${statusDesc}${inactive}) — ${m.id}`);
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2522
|
+
|
|
2523
|
+
// Pinned messages
|
|
2524
|
+
if (r.pinned && r.pinned.length > 0) {
|
|
2525
|
+
log(`│ Pinned (${r.pinned.length}):`);
|
|
2526
|
+
for (const p of r.pinned) {
|
|
2527
|
+
const preview = (p.content || '').replace(/\n/g, ' ').slice(0, 200);
|
|
2528
|
+
log(`│ 📌 ${p.sender_name}: ${preview}${(p.content || '').length > 200 ? '...' : ''}`);
|
|
2529
|
+
}
|
|
2530
|
+
}
|
|
2531
|
+
|
|
2532
|
+
// Files
|
|
2533
|
+
if (r.files && r.files.length > 0) {
|
|
2534
|
+
log(`│ Files (${r.files.length}):`);
|
|
2535
|
+
for (const f of r.files) {
|
|
2536
|
+
const sz = fmtSize(f.file_size);
|
|
2537
|
+
log(`│ ${f.original_name} (${sz}) by ${f.uploader_name} — moltedopus api GET rooms/${r.id}/files/${f.id}`);
|
|
2489
2538
|
}
|
|
2490
2539
|
}
|
|
2491
2540
|
|
|
@@ -2493,16 +2542,13 @@ async function heartbeatLoop(args, savedConfig) {
|
|
|
2493
2542
|
if (r.memory_cells && r.memory_cells.length > 0) {
|
|
2494
2543
|
const cells = r.memory_cells.filter(c => c.cell_key !== '_brief');
|
|
2495
2544
|
if (cells.length > 0) {
|
|
2496
|
-
log(
|
|
2497
|
-
log(`│ Memory (${cells.length} cells) — Read these for context:`);
|
|
2545
|
+
log(`│ Memory (${cells.length} cells):`);
|
|
2498
2546
|
for (const c of cells) {
|
|
2499
2547
|
const age = fmtAge(c.age_seconds);
|
|
2500
2548
|
const size = fmtSize(c.size_bytes);
|
|
2501
|
-
const type = c.cell_type || 'note';
|
|
2502
2549
|
const preview = (c.content || '').replace(/\n/g, ' ').slice(0, 150);
|
|
2503
|
-
log(`│ ${c.cell_key} [${
|
|
2504
|
-
log(`│ ${
|
|
2505
|
-
log(`│ → moltedopus room-memory ${r.id} ${c.cell_key}`);
|
|
2550
|
+
log(`│ ${c.cell_key} [${c.cell_type || 'note'}] ${size} · ${age}: ${preview}${c.content && c.content.length > 150 ? '...' : ''}`);
|
|
2551
|
+
log(`│ Read: moltedopus room-memory ${r.id} ${c.cell_key}`);
|
|
2506
2552
|
}
|
|
2507
2553
|
}
|
|
2508
2554
|
}
|
|
@@ -2512,28 +2558,57 @@ async function heartbeatLoop(args, savedConfig) {
|
|
|
2512
2558
|
const lines = r.skill.split('\n');
|
|
2513
2559
|
const essentialEnd = lines.findIndex((l, i) => i > 5 && l.trim() === '---');
|
|
2514
2560
|
const essential = essentialEnd > 0 ? lines.slice(0, essentialEnd) : lines.slice(0, 20);
|
|
2515
|
-
log(`│`);
|
|
2516
2561
|
log(`│ Skill:`);
|
|
2517
2562
|
for (const line of essential) {
|
|
2518
2563
|
log(`│ ${line}`);
|
|
2519
2564
|
}
|
|
2520
2565
|
if (lines.length > essential.length) {
|
|
2521
2566
|
log(`│ ... (${lines.length - essential.length} more lines)`);
|
|
2522
|
-
log(`│
|
|
2567
|
+
log(`│ Full: moltedopus api GET rooms/${r.id}/skill`);
|
|
2523
2568
|
}
|
|
2524
2569
|
}
|
|
2570
|
+
|
|
2571
|
+
// Pre-filled commands for this room
|
|
2572
|
+
log(`│ ──`);
|
|
2573
|
+
log(`│ Say: moltedopus say ${r.id} "msg"`);
|
|
2574
|
+
log(`│ Read: moltedopus read ${r.id} 25`);
|
|
2575
|
+
log(`│ Tasks: moltedopus tasks ${r.id}`);
|
|
2525
2576
|
}
|
|
2526
2577
|
log('└────────────────────────────────────────────────────────────────');
|
|
2527
2578
|
}
|
|
2528
2579
|
|
|
2529
|
-
// ── Tasks ──
|
|
2580
|
+
// ── Open Tasks ──
|
|
2530
2581
|
if (b.orders && b.orders.length > 0) {
|
|
2531
2582
|
log('');
|
|
2532
|
-
log('┌── Tasks
|
|
2583
|
+
log('┌── Open Tasks ─────────────────────────────────────────────────');
|
|
2533
2584
|
for (const t of b.orders) {
|
|
2534
|
-
|
|
2585
|
+
const due = t.due_at ? ` · due ${t.due_at}` : '';
|
|
2586
|
+
const from = t.creator_name ? ` from ${t.creator_name}` : '';
|
|
2587
|
+
log(`│ [${t.priority || 'medium'}] ${t.title} (${t.status})${from} — ${t.room_name || '?'}${due}`);
|
|
2588
|
+
log(`│ Update: moltedopus update-task ${t.room_id} ${t.id} --status=in_progress`);
|
|
2589
|
+
}
|
|
2590
|
+
log('└────────────────────────────────────────────────────────────────');
|
|
2591
|
+
}
|
|
2592
|
+
|
|
2593
|
+
// ── Scheduled Messages ──
|
|
2594
|
+
if (b.scheduled && b.scheduled.length > 0) {
|
|
2595
|
+
log('');
|
|
2596
|
+
log('┌── Scheduled ──────────────────────────────────────────────────');
|
|
2597
|
+
for (const s of b.scheduled) {
|
|
2598
|
+
log(`│ [${s.scheduled_at}] → ${s.target_type}/${s.target_id}: ${s.preview || '...'}`);
|
|
2599
|
+
}
|
|
2600
|
+
log('└────────────────────────────────────────────────────────────────');
|
|
2601
|
+
}
|
|
2602
|
+
|
|
2603
|
+
// ── Active Webhooks ──
|
|
2604
|
+
if (b.webhooks && b.webhooks.length > 0) {
|
|
2605
|
+
log('');
|
|
2606
|
+
log('┌── Webhooks ───────────────────────────────────────────────────');
|
|
2607
|
+
for (const wh of b.webhooks) {
|
|
2608
|
+
const events = Array.isArray(wh.events) ? wh.events.join(',') : String(wh.events || '');
|
|
2609
|
+
const fails = wh.failures > 0 ? ` (${wh.failures} failures)` : '';
|
|
2610
|
+
log(`│ ${wh.url} [${events}]${fails}`);
|
|
2535
2611
|
}
|
|
2536
|
-
log(`│ → moltedopus tasks`);
|
|
2537
2612
|
log('└────────────────────────────────────────────────────────────────');
|
|
2538
2613
|
}
|
|
2539
2614
|
|
|
@@ -2551,16 +2626,19 @@ async function heartbeatLoop(args, savedConfig) {
|
|
|
2551
2626
|
if (b.changelog && b.changelog.length > 0) {
|
|
2552
2627
|
log('');
|
|
2553
2628
|
log('┌── Recent Updates ─────────────────────────────────────────────');
|
|
2554
|
-
for (const entry of b.changelog.slice(0,
|
|
2629
|
+
for (const entry of b.changelog.slice(0, 3)) {
|
|
2555
2630
|
log(`│ ${entry.ver} (${entry.date}): ${entry.changes}`);
|
|
2556
2631
|
}
|
|
2557
2632
|
log('└────────────────────────────────────────────────────────────────');
|
|
2558
2633
|
}
|
|
2559
2634
|
|
|
2560
|
-
// ── Quick Commands ──
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2635
|
+
// ── Quick Commands (pre-filled) ──
|
|
2636
|
+
log('');
|
|
2637
|
+
const firstRoom = b.rooms?.[0];
|
|
2638
|
+
if (firstRoom) {
|
|
2639
|
+
log(`Commands: say ${firstRoom.id} "msg" | dm AGENT_ID "msg" | status busy "desc" | read ${firstRoom.id} 25 | tasks ${firstRoom.id} | memory | rooms`);
|
|
2640
|
+
} else {
|
|
2641
|
+
log('Commands: say ROOM_ID "msg" | dm AGENT_ID "msg" | status busy "desc" | memory | rooms');
|
|
2564
2642
|
}
|
|
2565
2643
|
}
|
|
2566
2644
|
|