4runr-os 2.9.125 → 2.9.127
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.
|
@@ -1291,19 +1291,27 @@ const start = async () => {
|
|
|
1291
1291
|
const shutdown = async () => {
|
|
1292
1292
|
baseLogger.info('Shutting down gateway...');
|
|
1293
1293
|
try {
|
|
1294
|
-
//
|
|
1294
|
+
// Close Fastify server first to stop accepting new connections
|
|
1295
|
+
baseLogger.info('Closing Fastify server...');
|
|
1296
|
+
await fastify.close();
|
|
1297
|
+
|
|
1298
|
+
// Shutdown queue system (let jobs complete)
|
|
1295
1299
|
if (queueInitialized) {
|
|
1300
|
+
baseLogger.info('Shutting down queue...');
|
|
1296
1301
|
await shutdownQueue();
|
|
1297
1302
|
}
|
|
1298
1303
|
|
|
1299
1304
|
// Shutdown Sentinel
|
|
1300
1305
|
if (sentinel) {
|
|
1306
|
+
baseLogger.info('Shutting down Sentinel...');
|
|
1301
1307
|
sentinel.shutdown();
|
|
1302
1308
|
}
|
|
1303
1309
|
|
|
1304
|
-
|
|
1310
|
+
// Disconnect databases
|
|
1311
|
+
baseLogger.info('Disconnecting databases...');
|
|
1305
1312
|
await disconnectPrisma();
|
|
1306
1313
|
await disconnectRedis();
|
|
1314
|
+
|
|
1307
1315
|
baseLogger.info('Gateway shut down successfully');
|
|
1308
1316
|
process.exit(0);
|
|
1309
1317
|
} catch (err) {
|
|
@@ -1312,6 +1320,17 @@ const shutdown = async () => {
|
|
|
1312
1320
|
}
|
|
1313
1321
|
};
|
|
1314
1322
|
|
|
1323
|
+
// Handle uncaught errors
|
|
1324
|
+
process.on('uncaughtException', (err) => {
|
|
1325
|
+
baseLogger.error('Uncaught exception:', err);
|
|
1326
|
+
shutdown();
|
|
1327
|
+
});
|
|
1328
|
+
|
|
1329
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
1330
|
+
baseLogger.error('Unhandled rejection at:', promise, 'reason:', reason);
|
|
1331
|
+
shutdown();
|
|
1332
|
+
});
|
|
1333
|
+
|
|
1315
1334
|
process.on('SIGTERM', shutdown);
|
|
1316
1335
|
process.on('SIGINT', shutdown);
|
|
1317
1336
|
|
package/mk3-tui/src/app.rs
CHANGED
|
@@ -11,6 +11,18 @@ use serde::{Deserialize, Serialize};
|
|
|
11
11
|
use std::collections::VecDeque;
|
|
12
12
|
use std::time::{Duration, Instant};
|
|
13
13
|
|
|
14
|
+
/// `HH:MM:SS` for Connection Portal activity log (UTC clock; avoids pulling in `chrono`).
|
|
15
|
+
fn wall_clock_hms() -> String {
|
|
16
|
+
let secs = std::time::SystemTime::now()
|
|
17
|
+
.duration_since(std::time::UNIX_EPOCH)
|
|
18
|
+
.map(|d| d.as_secs())
|
|
19
|
+
.unwrap_or(0);
|
|
20
|
+
let h = (secs / 3600) % 24;
|
|
21
|
+
let m = (secs / 60) % 60;
|
|
22
|
+
let s = secs % 60;
|
|
23
|
+
format!("{h:02}:{m:02}:{s:02}")
|
|
24
|
+
}
|
|
25
|
+
|
|
14
26
|
mod render_scheduler;
|
|
15
27
|
pub use render_scheduler::{RenderScheduler, RunMode};
|
|
16
28
|
|
|
@@ -2141,35 +2153,44 @@ impl App {
|
|
|
2141
2153
|
self.state.connection_portal.connecting = false;
|
|
2142
2154
|
|
|
2143
2155
|
if let Some(ref det) = self.state.setup_portal.detection_result {
|
|
2156
|
+
let now = wall_clock_hms();
|
|
2144
2157
|
match self.state.setup_portal.selected_option {
|
|
2145
2158
|
LocalBundle if !det.local_bundle.available => {
|
|
2146
|
-
self.state.connection_portal.
|
|
2147
|
-
|
|
2148
|
-
|
|
2159
|
+
self.state.connection_portal.add_log_entry(
|
|
2160
|
+
now,
|
|
2161
|
+
LogLevel::Warning,
|
|
2162
|
+
"Setup did not find a vendored local Gateway. Install 4runr-os globally, run from the repo, or set your Gateway URL manually.".to_string()
|
|
2149
2163
|
);
|
|
2150
2164
|
}
|
|
2151
2165
|
LocalBundle if det.local_bundle.available && !det.local_bundle.running => {
|
|
2152
|
-
self.state.connection_portal.
|
|
2153
|
-
|
|
2154
|
-
|
|
2166
|
+
self.state.connection_portal.add_log_entry(
|
|
2167
|
+
now,
|
|
2168
|
+
LogLevel::Info,
|
|
2169
|
+
"Local Gateway bundle detected. Start the Gateway (cd apps/gateway && npm start), then press Enter to connect.".to_string()
|
|
2155
2170
|
);
|
|
2156
2171
|
}
|
|
2157
2172
|
CloudServer if !det.cloud_server.available => {
|
|
2158
|
-
self.state.connection_portal.
|
|
2159
|
-
|
|
2160
|
-
|
|
2173
|
+
self.state.connection_portal.add_log_entry(
|
|
2174
|
+
now,
|
|
2175
|
+
LogLevel::Warning,
|
|
2176
|
+
"4Runr Cloud is not available in this build (Coming soon). Use Local Bundle or enter a Custom / self-hosted Gateway URL.".to_string()
|
|
2161
2177
|
);
|
|
2162
2178
|
}
|
|
2163
2179
|
CustomUrl if url.is_empty() => {
|
|
2164
|
-
self.state.connection_portal.
|
|
2165
|
-
|
|
2180
|
+
self.state.connection_portal.add_log_entry(
|
|
2181
|
+
now,
|
|
2182
|
+
LogLevel::Info,
|
|
2183
|
+
"Type your Gateway URL (https://…), then press Enter to connect.".to_string()
|
|
2166
2184
|
);
|
|
2167
2185
|
}
|
|
2168
2186
|
_ => {}
|
|
2169
2187
|
}
|
|
2170
2188
|
} else if matches!(self.state.setup_portal.selected_option, CustomUrl) && url.is_empty() {
|
|
2171
|
-
|
|
2172
|
-
|
|
2189
|
+
let now = wall_clock_hms();
|
|
2190
|
+
self.state.connection_portal.add_log_entry(
|
|
2191
|
+
now,
|
|
2192
|
+
LogLevel::Info,
|
|
2193
|
+
"Type your Gateway URL, then press Enter to connect.".to_string()
|
|
2173
2194
|
);
|
|
2174
2195
|
}
|
|
2175
2196
|
|
package/mk3-tui/src/main.rs
CHANGED
|
@@ -85,7 +85,7 @@ fn main() -> Result<()> {
|
|
|
85
85
|
|
|
86
86
|
// Track previous screen to detect portal navigation
|
|
87
87
|
let mut previous_screen: Option<crate::screens::Screen> = None;
|
|
88
|
-
|
|
88
|
+
// Last terminal size while Connection or Setup portal is visible (windowed hosts: sync buffer + clear on dimension drift).
|
|
89
89
|
let mut standalone_portal_last_terminal_dims: Option<(u16, u16)> = None;
|
|
90
90
|
|
|
91
91
|
// Force initial render
|
|
@@ -387,6 +387,9 @@ fn render_content_area(f: &mut Frame, area: Rect, state: &AppState) {
|
|
|
387
387
|
render_success(f, area, state);
|
|
388
388
|
} else if portal.connecting {
|
|
389
389
|
render_connecting(f, area, state);
|
|
390
|
+
} else if !portal.activity_log.is_empty() {
|
|
391
|
+
// Show activity log with instructions when there's no error
|
|
392
|
+
render_activity_log(f, area, state);
|
|
390
393
|
} else {
|
|
391
394
|
// Empty state - show instructions
|
|
392
395
|
render_instructions(f, area);
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "4runr-os",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.127",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "4Runr AI Agent OS - Secure terminal interface for AI agents. v2.9.
|
|
5
|
+
"description": "4Runr AI Agent OS - Secure terminal interface for AI agents. v2.9.127: mk3-tui build fix (no chrono dep — activity log timestamps use std). Prior: Portal hints in activity log, Gateway shutdown order, npm auto-update list parsing. ⚠️ Pre-MVP / Development Phase",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"4runr": "dist/index.js",
|