4runr-os 2.9.125 → 2.9.126

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
- // Shutdown queue system first (let jobs complete)
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
- await fastify.close();
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
 
@@ -2141,35 +2141,44 @@ impl App {
2141
2141
  self.state.connection_portal.connecting = false;
2142
2142
 
2143
2143
  if let Some(ref det) = self.state.setup_portal.detection_result {
2144
+ let now = chrono::Local::now().format("%H:%M:%S").to_string();
2144
2145
  match self.state.setup_portal.selected_option {
2145
2146
  LocalBundle if !det.local_bundle.available => {
2146
- self.state.connection_portal.error = Some(
2147
- "Setup did not find a vendored local Gateway. Install 4runr-os globally, run from the repo, or set your Gateway URL manually below."
2148
- .into(),
2147
+ self.state.connection_portal.add_log_entry(
2148
+ now,
2149
+ LogLevel::Warning,
2150
+ "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
2151
  );
2150
2152
  }
2151
2153
  LocalBundle if det.local_bundle.available && !det.local_bundle.running => {
2152
- self.state.connection_portal.error = Some(
2153
- "Local bundle found but nothing responded on :3001 yet. Start the Gateway, then press Enter to connect."
2154
- .into(),
2154
+ self.state.connection_portal.add_log_entry(
2155
+ now,
2156
+ LogLevel::Info,
2157
+ "Local Gateway bundle detected. Start the Gateway (cd apps/gateway && npm start), then press Enter to connect.".to_string()
2155
2158
  );
2156
2159
  }
2157
2160
  CloudServer if !det.cloud_server.available => {
2158
- self.state.connection_portal.error = Some(
2159
- "4Runr Cloud is not available in this build (Coming soon). Use Local Bundle or enter a Custom / self-hosted Gateway URL below."
2160
- .into(),
2161
+ self.state.connection_portal.add_log_entry(
2162
+ now,
2163
+ LogLevel::Warning,
2164
+ "4Runr Cloud is not available in this build (Coming soon). Use Local Bundle or enter a Custom / self-hosted Gateway URL.".to_string()
2161
2165
  );
2162
2166
  }
2163
2167
  CustomUrl if url.is_empty() => {
2164
- self.state.connection_portal.error = Some(
2165
- "Type your Gateway URL below (https://…), then press Enter to connect.".into(),
2168
+ self.state.connection_portal.add_log_entry(
2169
+ now,
2170
+ LogLevel::Info,
2171
+ "Type your Gateway URL (https://…), then press Enter to connect.".to_string()
2166
2172
  );
2167
2173
  }
2168
2174
  _ => {}
2169
2175
  }
2170
2176
  } else if matches!(self.state.setup_portal.selected_option, CustomUrl) && url.is_empty() {
2171
- self.state.connection_portal.error = Some(
2172
- "Type your Gateway URL below, then press Enter to connect.".into(),
2177
+ let now = chrono::Local::now().format("%H:%M:%S").to_string();
2178
+ self.state.connection_portal.add_log_entry(
2179
+ now,
2180
+ LogLevel::Info,
2181
+ "Type your Gateway URL, then press Enter to connect.".to_string()
2173
2182
  );
2174
2183
  }
2175
2184
 
@@ -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.125",
3
+ "version": "2.9.126",
4
4
  "type": "module",
5
- "description": "4Runr AI Agent OS - Secure terminal interface for AI agents. v2.9.125: Fix global auto-update verification (npm list JSON root vs dependencies). Prior: Gateway /health /ready /metrics DDoS exempt; Connection Portal error UI + 429 hint. ⚠️ Pre-MVP / Development Phase",
5
+ "description": "4Runr AI Agent OS - Secure terminal interface for AI agents. v2.9.126: Fix Portal UI showing error on first load + Gateway port cleanup. Prior: auto-update npm list JSON parsing, Gateway /health DDoS exempt, Connection Portal error UI. ⚠️ Pre-MVP / Development Phase",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
8
8
  "4runr": "dist/index.js",