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.
- package/dashboard/index.html +341 -0
- package/dist/cli.js +18 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +188 -1
- package/dist/commands/server.js.map +1 -1
- package/dist/commands/slack-cli.d.ts +16 -0
- package/dist/commands/slack-cli.d.ts.map +1 -0
- package/dist/commands/slack-cli.js +198 -0
- package/dist/commands/slack-cli.js.map +1 -0
- package/dist/core/AgentRegistry.d.ts.map +1 -1
- package/dist/core/AgentRegistry.js +24 -6
- package/dist/core/AgentRegistry.js.map +1 -1
- package/dist/core/SleepWakeDetector.d.ts +11 -0
- package/dist/core/SleepWakeDetector.d.ts.map +1 -1
- package/dist/core/SleepWakeDetector.js +16 -1
- package/dist/core/SleepWakeDetector.js.map +1 -1
- package/dist/lifeline/ServerSupervisor.d.ts +13 -0
- package/dist/lifeline/ServerSupervisor.d.ts.map +1 -1
- package/dist/lifeline/ServerSupervisor.js +129 -0
- package/dist/lifeline/ServerSupervisor.js.map +1 -1
- package/dist/messaging/SessionSummarySentinel.js +1 -1
- package/dist/messaging/TelegramAdapter.d.ts +1 -0
- package/dist/messaging/TelegramAdapter.d.ts.map +1 -1
- package/dist/messaging/TelegramAdapter.js +4 -1
- package/dist/messaging/TelegramAdapter.js.map +1 -1
- package/dist/messaging/slack/ChannelManager.d.ts +36 -0
- package/dist/messaging/slack/ChannelManager.d.ts.map +1 -0
- package/dist/messaging/slack/ChannelManager.js +100 -0
- package/dist/messaging/slack/ChannelManager.js.map +1 -0
- package/dist/messaging/slack/FileHandler.d.ts +30 -0
- package/dist/messaging/slack/FileHandler.d.ts.map +1 -0
- package/dist/messaging/slack/FileHandler.js +87 -0
- package/dist/messaging/slack/FileHandler.js.map +1 -0
- package/dist/messaging/slack/RingBuffer.d.ts +22 -0
- package/dist/messaging/slack/RingBuffer.d.ts.map +1 -0
- package/dist/messaging/slack/RingBuffer.js +48 -0
- package/dist/messaging/slack/RingBuffer.js.map +1 -0
- package/dist/messaging/slack/SlackAdapter.d.ts +136 -0
- package/dist/messaging/slack/SlackAdapter.d.ts.map +1 -0
- package/dist/messaging/slack/SlackAdapter.js +572 -0
- package/dist/messaging/slack/SlackAdapter.js.map +1 -0
- package/dist/messaging/slack/SlackApiClient.d.ts +51 -0
- package/dist/messaging/slack/SlackApiClient.d.ts.map +1 -0
- package/dist/messaging/slack/SlackApiClient.js +94 -0
- package/dist/messaging/slack/SlackApiClient.js.map +1 -0
- package/dist/messaging/slack/SocketModeClient.d.ts +44 -0
- package/dist/messaging/slack/SocketModeClient.d.ts.map +1 -0
- package/dist/messaging/slack/SocketModeClient.js +209 -0
- package/dist/messaging/slack/SocketModeClient.js.map +1 -0
- package/dist/messaging/slack/index.d.ts +12 -0
- package/dist/messaging/slack/index.d.ts.map +1 -0
- package/dist/messaging/slack/index.js +15 -0
- package/dist/messaging/slack/index.js.map +1 -0
- package/dist/messaging/slack/sanitize.d.ts +39 -0
- package/dist/messaging/slack/sanitize.d.ts.map +1 -0
- package/dist/messaging/slack/sanitize.js +71 -0
- package/dist/messaging/slack/sanitize.js.map +1 -0
- package/dist/messaging/slack/types.d.ts +155 -0
- package/dist/messaging/slack/types.d.ts.map +1 -0
- package/dist/messaging/slack/types.js +54 -0
- package/dist/messaging/slack/types.js.map +1 -0
- package/dist/monitoring/PresenceProxy.d.ts +157 -0
- package/dist/monitoring/PresenceProxy.d.ts.map +1 -0
- package/dist/monitoring/PresenceProxy.js +891 -0
- package/dist/monitoring/PresenceProxy.js.map +1 -0
- package/dist/monitoring/SessionWatchdog.d.ts.map +1 -1
- package/dist/monitoring/SessionWatchdog.js +2 -0
- package/dist/monitoring/SessionWatchdog.js.map +1 -1
- package/dist/server/AgentServer.d.ts +1 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +49 -47
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/routes.d.ts +1 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +213 -4
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +93 -77
- package/src/templates/hooks/slack-channel-context.sh +98 -0
- package/src/templates/scripts/slack-reply.sh +64 -0
- package/upgrades/0.24.15.md +49 -0
package/dashboard/index.html
CHANGED
|
@@ -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">▶</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')
|