-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathindex.ts
More file actions
63 lines (47 loc) · 2.83 KB
/
Copy pathindex.ts
File metadata and controls
63 lines (47 loc) · 2.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/**
* @file index.ts
* @description Entry point for the CtrlNode.ai Agent Bridge.
*/
// BUILD_TIME is injected at compile time via --define BUILD_TIME="..."
declare const BUILD_TIME: string;
const _buildTime = typeof BUILD_TIME !== 'undefined' ? BUILD_TIME : 'dev';
// config.ts MUST be the first import — it validates env vars and exits
// with a user-friendly message if required files are missing.
const { PROVIDERS, ensurePairingToken, BRIDGE_VERSION } = await import('./config.js');
console.log(`\nCTRLNODE Bridge ${BRIDGE_VERSION} built ${_buildTime}\n`);
// --setup: run interactive wizard and exit before loading anything else.
// Must be checked before any other imports so config.ts side-effects don't run.
if (process.argv.includes('--setup')) {
const { runSetup } = await import('./setup.js');
await runSetup();
process.exit(0);
}
const { createProviders } = await import('./providers/factory.js');
const { MultiProvider } = await import('./providers/MultiProvider.js');
const { runSyncAgents, connect } = await import('./websocket.js');
const { logger } = await import('./logger.js');
const { loadModelManifest } = await import('./modelManifest.js');
const { checkAndApplyUpdate } = await import('./updater.js');
// ── Keepalive ─────────────────────────────────────────────────────────────────
const keepalive = setInterval(() => {}, 1_000);
if (keepalive.unref) keepalive.unref();
// ── Bootstrap ─────────────────────────────────────────────────────────────────
// Check for Bridge updates — runs before pairing/connect so prompt appears right after banner.
// Failures are handled internally — Bridge always starts even if the check fails.
await checkAndApplyUpdate();
await ensurePairingToken();
// Fetch/refresh model manifest before connecting (Option A).
// Failures are handled internally — Bridge always starts even if the fetch fails.
await loadModelManifest();
const rawProviders = createProviders(PROVIDERS);
const provider = rawProviders.length === 1 ? rawProviders[0] : new MultiProvider(rawProviders);
connect(provider);
runSyncAgents();
// ── Process signals ───────────────────────────────────────────────────────────
process.on('SIGINT', () => {
logger.debug('shutdown', { message: 'Shutting down' });
provider.dispose().finally(() => process.exit(0));
});
process.on('SIGTERM', () => process.emit('SIGINT'));
process.on('uncaughtException', (err: Error) => logger.error('uncaught_exception', { message: err.message }));
export {};