@@ -248,16 +248,42 @@ export async function createRuntimeApp(options: RuntimeAppOptions = {}): Promise
248248
249249 // ── init() — database, migrations, auth, handlers ──────────────
250250 async function init ( ) {
251- if ( ! options . skipDbInit ) {
252- await initPostgres ( ) ;
253- await autoMigrate ( ) ;
254- } else if ( options . dbConnection ) {
255- setConnection ( options . dbConnection ) ;
256- }
251+ const isRunnerMode = ! ! process . env . TEAM_SERVER_URL ;
252+
253+ // In runner mode, skip DB and auth — the server owns those.
254+ // The runner uses RemoteThreadManager to proxy persistence via WebSocket.
255+ if ( ! isRunnerMode ) {
256+ if ( ! options . skipDbInit ) {
257+ await initPostgres ( ) ;
258+ await autoMigrate ( ) ;
259+ } else if ( options . dbConnection ) {
260+ setConnection ( options . dbConnection ) ;
261+ }
262+
263+ void startScheduler ( ) ;
264+
265+ if ( ! options . skipAuthSetup ) {
266+ const { initBetterAuth } = await import ( './lib/auth.js' ) ;
267+ await initBetterAuth ( ) ;
268+ log . info ( 'Auth: Better Auth (local)' , { namespace : 'server' } ) ;
269+ } else {
270+ log . info ( 'Auth: forwarded from server' , { namespace : 'server' } ) ;
271+ }
272+
273+ // Mark stale threads
274+ await markStaleThreadsInterrupted ( ) ;
275+ await markStaleExternalThreadsStopped ( ) ;
276+
277+ // Re-register watchers
278+ void rehydrateWatchers ( ) ;
257279
258- void startScheduler ( ) ;
280+ // Periodic sweep for external threads
281+ startExternalThreadSweep ( ) ;
282+ } else {
283+ log . info ( 'Runner mode — skipping DB, auth, and scheduler' , { namespace : 'server' } ) ;
284+ }
259285
260- // Register handler registry
286+ // Register handler registry (needed in both modes for tunnel:request handling)
261287 const handlerCtx : HandlerServiceContext = {
262288 getThread : tm . getThread ,
263289 updateThread : tm . updateThread ,
@@ -277,26 +303,8 @@ export async function createRuntimeApp(options: RuntimeAppOptions = {}): Promise
277303 } ;
278304 registerAllHandlers ( handlerCtx ) ;
279305
280- if ( ! options . skipAuthSetup ) {
281- // When running without the server (e.g. standalone runtime), init Better Auth locally
282- const { initBetterAuth } = await import ( './lib/auth.js' ) ;
283- await initBetterAuth ( ) ;
284- log . info ( 'Auth: Better Auth (local)' , { namespace : 'server' } ) ;
285- } else {
286- log . info ( 'Auth: forwarded from server' , { namespace : 'server' } ) ;
287- }
288306 await logProviderStatus ( ) ;
289307
290- // Mark stale threads
291- await markStaleThreadsInterrupted ( ) ;
292- await markStaleExternalThreadsStopped ( ) ;
293-
294- // Re-register watchers
295- void rehydrateWatchers ( ) ;
296-
297- // Periodic sweep for external threads
298- startExternalThreadSweep ( ) ;
299-
300308 // Reattach PTY sessions
301309 ptyManager . reattachSessions ( ) ;
302310
0 commit comments