instar 0.24.13 → 0.24.15

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 (82) hide show
  1. package/dashboard/index.html +341 -0
  2. package/dist/cli.js +18 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/server.d.ts.map +1 -1
  5. package/dist/commands/server.js +188 -1
  6. package/dist/commands/server.js.map +1 -1
  7. package/dist/commands/slack-cli.d.ts +16 -0
  8. package/dist/commands/slack-cli.d.ts.map +1 -0
  9. package/dist/commands/slack-cli.js +198 -0
  10. package/dist/commands/slack-cli.js.map +1 -0
  11. package/dist/core/AgentRegistry.d.ts.map +1 -1
  12. package/dist/core/AgentRegistry.js +24 -6
  13. package/dist/core/AgentRegistry.js.map +1 -1
  14. package/dist/core/SleepWakeDetector.d.ts +11 -0
  15. package/dist/core/SleepWakeDetector.d.ts.map +1 -1
  16. package/dist/core/SleepWakeDetector.js +16 -1
  17. package/dist/core/SleepWakeDetector.js.map +1 -1
  18. package/dist/lifeline/ServerSupervisor.d.ts +13 -0
  19. package/dist/lifeline/ServerSupervisor.d.ts.map +1 -1
  20. package/dist/lifeline/ServerSupervisor.js +129 -0
  21. package/dist/lifeline/ServerSupervisor.js.map +1 -1
  22. package/dist/messaging/SessionSummarySentinel.js +1 -1
  23. package/dist/messaging/TelegramAdapter.d.ts +1 -0
  24. package/dist/messaging/TelegramAdapter.d.ts.map +1 -1
  25. package/dist/messaging/TelegramAdapter.js +4 -1
  26. package/dist/messaging/TelegramAdapter.js.map +1 -1
  27. package/dist/messaging/slack/ChannelManager.d.ts +36 -0
  28. package/dist/messaging/slack/ChannelManager.d.ts.map +1 -0
  29. package/dist/messaging/slack/ChannelManager.js +100 -0
  30. package/dist/messaging/slack/ChannelManager.js.map +1 -0
  31. package/dist/messaging/slack/FileHandler.d.ts +30 -0
  32. package/dist/messaging/slack/FileHandler.d.ts.map +1 -0
  33. package/dist/messaging/slack/FileHandler.js +87 -0
  34. package/dist/messaging/slack/FileHandler.js.map +1 -0
  35. package/dist/messaging/slack/RingBuffer.d.ts +22 -0
  36. package/dist/messaging/slack/RingBuffer.d.ts.map +1 -0
  37. package/dist/messaging/slack/RingBuffer.js +48 -0
  38. package/dist/messaging/slack/RingBuffer.js.map +1 -0
  39. package/dist/messaging/slack/SlackAdapter.d.ts +136 -0
  40. package/dist/messaging/slack/SlackAdapter.d.ts.map +1 -0
  41. package/dist/messaging/slack/SlackAdapter.js +572 -0
  42. package/dist/messaging/slack/SlackAdapter.js.map +1 -0
  43. package/dist/messaging/slack/SlackApiClient.d.ts +51 -0
  44. package/dist/messaging/slack/SlackApiClient.d.ts.map +1 -0
  45. package/dist/messaging/slack/SlackApiClient.js +94 -0
  46. package/dist/messaging/slack/SlackApiClient.js.map +1 -0
  47. package/dist/messaging/slack/SocketModeClient.d.ts +44 -0
  48. package/dist/messaging/slack/SocketModeClient.d.ts.map +1 -0
  49. package/dist/messaging/slack/SocketModeClient.js +209 -0
  50. package/dist/messaging/slack/SocketModeClient.js.map +1 -0
  51. package/dist/messaging/slack/index.d.ts +12 -0
  52. package/dist/messaging/slack/index.d.ts.map +1 -0
  53. package/dist/messaging/slack/index.js +15 -0
  54. package/dist/messaging/slack/index.js.map +1 -0
  55. package/dist/messaging/slack/sanitize.d.ts +39 -0
  56. package/dist/messaging/slack/sanitize.d.ts.map +1 -0
  57. package/dist/messaging/slack/sanitize.js +71 -0
  58. package/dist/messaging/slack/sanitize.js.map +1 -0
  59. package/dist/messaging/slack/types.d.ts +155 -0
  60. package/dist/messaging/slack/types.d.ts.map +1 -0
  61. package/dist/messaging/slack/types.js +54 -0
  62. package/dist/messaging/slack/types.js.map +1 -0
  63. package/dist/monitoring/PresenceProxy.d.ts +157 -0
  64. package/dist/monitoring/PresenceProxy.d.ts.map +1 -0
  65. package/dist/monitoring/PresenceProxy.js +891 -0
  66. package/dist/monitoring/PresenceProxy.js.map +1 -0
  67. package/dist/monitoring/SessionWatchdog.d.ts.map +1 -1
  68. package/dist/monitoring/SessionWatchdog.js +2 -0
  69. package/dist/monitoring/SessionWatchdog.js.map +1 -1
  70. package/dist/server/AgentServer.d.ts +1 -0
  71. package/dist/server/AgentServer.d.ts.map +1 -1
  72. package/dist/server/AgentServer.js +49 -47
  73. package/dist/server/AgentServer.js.map +1 -1
  74. package/dist/server/routes.d.ts +1 -0
  75. package/dist/server/routes.d.ts.map +1 -1
  76. package/dist/server/routes.js +213 -4
  77. package/dist/server/routes.js.map +1 -1
  78. package/package.json +1 -1
  79. package/src/data/builtin-manifest.json +93 -77
  80. package/src/templates/hooks/slack-channel-context.sh +98 -0
  81. package/src/templates/scripts/slack-reply.sh +64 -0
  82. package/upgrades/0.24.15.md +49 -0
@@ -1916,6 +1916,212 @@
1916
1916
  .spark.s-skipped { background: #333; }
1917
1917
 
1918
1918
  /* ── Discovery Tab ──────────────────────────────────────── */
1919
+ /* Systems Tab */
1920
+ .systems-container {
1921
+ grid-column: 1 / -1;
1922
+ overflow-y: auto;
1923
+ background: var(--bg);
1924
+ padding: 20px;
1925
+ }
1926
+
1927
+ .systems-main {
1928
+ max-width: 900px;
1929
+ margin: 0 auto;
1930
+ }
1931
+
1932
+ .systems-header {
1933
+ display: flex;
1934
+ align-items: center;
1935
+ justify-content: space-between;
1936
+ margin-bottom: 20px;
1937
+ }
1938
+
1939
+ .systems-header h2 {
1940
+ font-size: 16px;
1941
+ font-weight: 600;
1942
+ color: var(--text-bright);
1943
+ }
1944
+
1945
+ .systems-refresh {
1946
+ font-size: 11px;
1947
+ padding: 4px 12px;
1948
+ border-radius: 4px;
1949
+ border: 1px solid var(--border);
1950
+ background: transparent;
1951
+ color: var(--text-dim);
1952
+ cursor: pointer;
1953
+ }
1954
+
1955
+ .systems-refresh:hover {
1956
+ border-color: var(--text-dim);
1957
+ color: var(--text);
1958
+ }
1959
+
1960
+ .systems-summary {
1961
+ display: flex;
1962
+ gap: 16px;
1963
+ margin-bottom: 24px;
1964
+ flex-wrap: wrap;
1965
+ }
1966
+
1967
+ .systems-summary-card {
1968
+ flex: 1;
1969
+ min-width: 140px;
1970
+ padding: 14px 18px;
1971
+ background: var(--bg-panel);
1972
+ border: 1px solid var(--border);
1973
+ border-radius: 8px;
1974
+ text-align: center;
1975
+ }
1976
+
1977
+ .systems-summary-card .summary-value {
1978
+ font-size: 22px;
1979
+ font-weight: 700;
1980
+ color: var(--text-bright);
1981
+ }
1982
+
1983
+ .systems-summary-card .summary-label {
1984
+ font-size: 11px;
1985
+ color: var(--text-dim);
1986
+ margin-top: 4px;
1987
+ }
1988
+
1989
+ .systems-section {
1990
+ margin-bottom: 24px;
1991
+ }
1992
+
1993
+ .systems-section h3 {
1994
+ font-size: 13px;
1995
+ font-weight: 600;
1996
+ color: var(--text-bright);
1997
+ margin-bottom: 12px;
1998
+ }
1999
+
2000
+ .systems-category {
2001
+ background: var(--bg-panel);
2002
+ border: 1px solid var(--border);
2003
+ border-radius: 8px;
2004
+ margin-bottom: 8px;
2005
+ overflow: hidden;
2006
+ }
2007
+
2008
+ .systems-category-header {
2009
+ display: flex;
2010
+ align-items: center;
2011
+ gap: 10px;
2012
+ padding: 12px 16px;
2013
+ cursor: pointer;
2014
+ user-select: none;
2015
+ transition: background 0.15s;
2016
+ }
2017
+
2018
+ .systems-category-header:hover {
2019
+ background: var(--bg-hover);
2020
+ }
2021
+
2022
+ .systems-category-arrow {
2023
+ font-size: 10px;
2024
+ color: var(--text-dim);
2025
+ transition: transform 0.2s;
2026
+ width: 12px;
2027
+ }
2028
+
2029
+ .systems-category.expanded .systems-category-arrow {
2030
+ transform: rotate(90deg);
2031
+ }
2032
+
2033
+ .systems-category-dot {
2034
+ width: 8px;
2035
+ height: 8px;
2036
+ border-radius: 50%;
2037
+ flex-shrink: 0;
2038
+ }
2039
+
2040
+ .systems-category-name {
2041
+ font-size: 13px;
2042
+ font-weight: 500;
2043
+ color: var(--text-bright);
2044
+ flex: 1;
2045
+ }
2046
+
2047
+ .systems-category-count {
2048
+ font-size: 11px;
2049
+ color: var(--text-dim);
2050
+ }
2051
+
2052
+ .systems-category-body {
2053
+ display: none;
2054
+ padding: 0 16px 12px;
2055
+ gap: 8px;
2056
+ }
2057
+
2058
+ .systems-category.expanded .systems-category-body {
2059
+ display: flex;
2060
+ flex-wrap: wrap;
2061
+ }
2062
+
2063
+ .systems-process-card {
2064
+ display: flex;
2065
+ align-items: center;
2066
+ gap: 8px;
2067
+ padding: 8px 12px;
2068
+ background: var(--bg);
2069
+ border: 1px solid var(--border);
2070
+ border-radius: 6px;
2071
+ min-width: 200px;
2072
+ }
2073
+
2074
+ .systems-process-dot {
2075
+ width: 6px;
2076
+ height: 6px;
2077
+ border-radius: 50%;
2078
+ flex-shrink: 0;
2079
+ }
2080
+
2081
+ .systems-process-name {
2082
+ font-size: 12px;
2083
+ color: var(--text);
2084
+ }
2085
+
2086
+ .systems-process-status {
2087
+ font-size: 10px;
2088
+ color: var(--text-dim);
2089
+ margin-left: auto;
2090
+ }
2091
+
2092
+ .systems-events {
2093
+ background: var(--bg-panel);
2094
+ border: 1px solid var(--border);
2095
+ border-radius: 8px;
2096
+ max-height: 300px;
2097
+ overflow-y: auto;
2098
+ }
2099
+
2100
+ .systems-event-row {
2101
+ display: flex;
2102
+ align-items: center;
2103
+ gap: 10px;
2104
+ padding: 8px 14px;
2105
+ border-bottom: 1px solid var(--border);
2106
+ font-size: 12px;
2107
+ }
2108
+
2109
+ .systems-event-row:last-child {
2110
+ border-bottom: none;
2111
+ }
2112
+
2113
+ .systems-event-time {
2114
+ color: var(--text-dim);
2115
+ white-space: nowrap;
2116
+ font-size: 11px;
2117
+ min-width: 60px;
2118
+ }
2119
+
2120
+ .systems-event-text {
2121
+ color: var(--text);
2122
+ flex: 1;
2123
+ }
2124
+
1919
2125
  .discovery-container {
1920
2126
  grid-column: 1 / -1;
1921
2127
  overflow-y: auto;
@@ -2433,6 +2639,7 @@
2433
2639
  <button class="tab" data-tab="dropzone" onclick="switchTab('dropzone')">Drop Zone</button>
2434
2640
  <button class="tab" data-tab="jobs" onclick="switchTab('jobs')">Jobs <span class="tab-count" id="tabJobCount">0</span></button>
2435
2641
  <button class="tab" data-tab="discovery" onclick="switchTab('discovery')">Discovery</button>
2642
+ <button class="tab" data-tab="systems" onclick="switchTab('systems')">Systems</button>
2436
2643
  </nav>
2437
2644
  </div>
2438
2645
  <div class="vital-signs" id="vitalSigns">
@@ -2653,6 +2860,26 @@
2653
2860
  </div>
2654
2861
  </div>
2655
2862
 
2863
+ <!-- Systems Tab -->
2864
+ <div class="systems-container" id="systemsTab" style="display:none">
2865
+ <div class="systems-main">
2866
+ <div class="systems-header">
2867
+ <h2>Systems Status</h2>
2868
+ <button class="systems-refresh" onclick="loadSystems()">Refresh</button>
2869
+ </div>
2870
+ <div class="systems-summary" id="systemsSummary">
2871
+ <div style="padding:20px;color:var(--text-dim);text-align:center">Loading...</div>
2872
+ </div>
2873
+ <div class="systems-categories" id="systemsCategories"></div>
2874
+ <div class="systems-section">
2875
+ <h3>Recent Degradation Events</h3>
2876
+ <div class="systems-events" id="systemsEvents">
2877
+ <div style="padding:12px;color:var(--text-dim);text-align:center">No events</div>
2878
+ </div>
2879
+ </div>
2880
+ </div>
2881
+ </div>
2882
+
2656
2883
  <!-- Discovery Tab -->
2657
2884
  <div class="discovery-container" id="discoveryTab" style="display:none">
2658
2885
  <div class="discovery-main">
@@ -3614,6 +3841,12 @@
3614
3841
  display: ['flex'],
3615
3842
  onActivate: () => { if (!discoveryLoaded) loadDiscovery(); },
3616
3843
  },
3844
+ {
3845
+ id: 'systems',
3846
+ panels: ['systemsTab'],
3847
+ display: ['flex'],
3848
+ onActivate: () => { loadSystems(); },
3849
+ },
3617
3850
  ];
3618
3851
 
3619
3852
  function switchTab(tabName) {
@@ -5235,6 +5468,114 @@
5235
5468
  }).join('');
5236
5469
  }
5237
5470
 
5471
+ // ── Systems Tab ──────────────────────────────────────────────
5472
+ let systemsData = null;
5473
+
5474
+ async function loadSystems() {
5475
+ try {
5476
+ systemsData = await apiFetch('/systems/status');
5477
+ renderSystems();
5478
+ } catch (e) {
5479
+ document.getElementById('systemsSummary').innerHTML =
5480
+ '<div style="padding:20px;color:var(--red);text-align:center">Failed to load systems status</div>';
5481
+ }
5482
+ }
5483
+
5484
+ function renderSystems() {
5485
+ if (!systemsData) return;
5486
+ const { uptime, categories, recentEvents } = systemsData;
5487
+
5488
+ // Summary
5489
+ let totalProcesses = 0;
5490
+ let healthyProcesses = 0;
5491
+ let errorProcesses = 0;
5492
+ for (const cat of categories) {
5493
+ for (const p of cat.processes) {
5494
+ totalProcesses++;
5495
+ if (p.status === 'running') healthyProcesses++;
5496
+ if (p.status === 'error') errorProcesses++;
5497
+ }
5498
+ }
5499
+ const uptimeStr = formatUptimeClient(uptime);
5500
+
5501
+ document.getElementById('systemsSummary').innerHTML = `
5502
+ <div class="systems-summary-card">
5503
+ <div class="summary-value" style="color:var(--accent)">${healthyProcesses}/${totalProcesses}</div>
5504
+ <div class="summary-label">Processes Healthy</div>
5505
+ </div>
5506
+ <div class="systems-summary-card">
5507
+ <div class="summary-value" style="color:${errorProcesses > 0 ? 'var(--red)' : 'var(--text-dim)'}">${errorProcesses}</div>
5508
+ <div class="summary-label">Errors</div>
5509
+ </div>
5510
+ <div class="systems-summary-card">
5511
+ <div class="summary-value">${esc(uptimeStr)}</div>
5512
+ <div class="summary-label">Uptime</div>
5513
+ </div>
5514
+ <div class="systems-summary-card">
5515
+ <div class="summary-value">${recentEvents.length}</div>
5516
+ <div class="summary-label">Recent Events</div>
5517
+ </div>`;
5518
+
5519
+ // Categories
5520
+ const catEl = document.getElementById('systemsCategories');
5521
+ catEl.innerHTML = categories.map(cat => {
5522
+ const running = cat.processes.filter(p => p.status === 'running').length;
5523
+ const hasError = cat.processes.some(p => p.status === 'error');
5524
+ const hasDisabled = cat.processes.some(p => p.status === 'not tracked' || p.status === 'disabled');
5525
+ const dotColor = hasError ? 'var(--red)' : (running === 0 ? 'var(--text-dim)' : (hasDisabled ? 'var(--orange)' : 'var(--accent)'));
5526
+
5527
+ const processCards = cat.processes.map(p => {
5528
+ const pDotColor = p.status === 'running' ? 'var(--accent)' :
5529
+ p.status === 'error' ? 'var(--red)' :
5530
+ p.status === 'disabled' ? 'var(--orange)' : 'var(--text-dim)';
5531
+ return `<div class="systems-process-card">
5532
+ <span class="systems-process-dot" style="background:${pDotColor}"></span>
5533
+ <span class="systems-process-name">${esc(p.name)}</span>
5534
+ <span class="systems-process-status">${esc(p.status)}</span>
5535
+ </div>`;
5536
+ }).join('');
5537
+
5538
+ return `<div class="systems-category" data-cat="${esc(cat.id)}">
5539
+ <div class="systems-category-header" onclick="toggleSystemsCategory(this)">
5540
+ <span class="systems-category-arrow">&#9654;</span>
5541
+ <span class="systems-category-dot" style="background:${dotColor}"></span>
5542
+ <span class="systems-category-name">${esc(cat.name)}</span>
5543
+ <span class="systems-category-count">${running}/${cat.processes.length} active</span>
5544
+ </div>
5545
+ <div class="systems-category-body">${processCards}</div>
5546
+ </div>`;
5547
+ }).join('');
5548
+
5549
+ // Events
5550
+ const eventsEl = document.getElementById('systemsEvents');
5551
+ if (recentEvents.length === 0) {
5552
+ eventsEl.innerHTML = '<div style="padding:12px;color:var(--text-dim);text-align:center">No degradation events</div>';
5553
+ } else {
5554
+ eventsEl.innerHTML = recentEvents.map(e => {
5555
+ const time = e.timestamp ? new Date(e.timestamp).toLocaleString([], { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }) : '';
5556
+ return `<div class="systems-event-row">
5557
+ <span class="systems-event-time">${esc(time)}</span>
5558
+ <span class="systems-event-text">${esc(e.narrative || e.subsystem || 'Unknown event')}</span>
5559
+ </div>`;
5560
+ }).join('');
5561
+ }
5562
+ }
5563
+
5564
+ function toggleSystemsCategory(headerEl) {
5565
+ const cat = headerEl.closest('.systems-category');
5566
+ cat.classList.toggle('expanded');
5567
+ }
5568
+
5569
+ function formatUptimeClient(ms) {
5570
+ const s = Math.floor(ms / 1000);
5571
+ const d = Math.floor(s / 86400);
5572
+ const h = Math.floor((s % 86400) / 3600);
5573
+ const m = Math.floor((s % 3600) / 60);
5574
+ if (d > 0) return d + 'd ' + h + 'h';
5575
+ if (h > 0) return h + 'h ' + m + 'm';
5576
+ return m + 'm';
5577
+ }
5578
+
5238
5579
  // Handle tab visibility — close SSE when tab is backgrounded
5239
5580
  document.addEventListener('visibilitychange', () => {
5240
5581
  if (document.hidden) {
package/dist/cli.js CHANGED
@@ -339,6 +339,13 @@ addCmd
339
339
  const { addWhatsApp } = await import('./commands/whatsapp.js');
340
340
  return addWhatsApp(opts);
341
341
  });
342
+ addCmd
343
+ .command('slack')
344
+ .description('Add Slack messaging adapter (tokens entered interactively)')
345
+ .action(async () => {
346
+ const { addSlack } = await import('./commands/slack-cli.js');
347
+ return addSlack();
348
+ });
342
349
  addCmd
343
350
  .command('sentry')
344
351
  .description('Add Sentry error monitoring')
@@ -349,6 +356,17 @@ addCmd
349
356
  .description('Add Claude API quota tracking')
350
357
  .option('--state-file <path>', 'Path to quota state file (default: .instar/state/quota.json)')
351
358
  .action((opts) => addQuota(opts));
359
+ // ── Remove ──────────────────────────────────────────────────────
360
+ const removeAdapterCmd = program
361
+ .command('remove')
362
+ .description('Remove capabilities from the agent');
363
+ removeAdapterCmd
364
+ .command('slack')
365
+ .description('Remove Slack messaging adapter and purge associated data')
366
+ .action(async () => {
367
+ const { removeSlack } = await import('./commands/slack-cli.js');
368
+ return removeSlack();
369
+ });
352
370
  // ── Backup ───────────────────────────────────────────────────────
353
371
  const backupCmd = program
354
372
  .command('backup')