idleTimeout.ts 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. import { logForDebugging } from './debug.js'
  2. import { gracefulShutdownSync } from './gracefulShutdown.js'
  3. /**
  4. * Creates an idle timeout manager for SDK mode.
  5. * Automatically exits the process after the specified idle duration.
  6. *
  7. * @param isIdle Function that returns true if the system is currently idle
  8. * @returns Object with start/stop methods to control the idle timer
  9. */
  10. export function createIdleTimeoutManager(isIdle: () => boolean): {
  11. start: () => void
  12. stop: () => void
  13. } {
  14. // Parse CLAUDE_CODE_EXIT_AFTER_STOP_DELAY environment variable
  15. const exitAfterStopDelay = process.env.CLAUDE_CODE_EXIT_AFTER_STOP_DELAY
  16. const delayMs = exitAfterStopDelay ? parseInt(exitAfterStopDelay, 10) : null
  17. const isValidDelay = delayMs && !isNaN(delayMs) && delayMs > 0
  18. let timer: NodeJS.Timeout | null = null
  19. let lastIdleTime = 0
  20. return {
  21. start() {
  22. // Clear any existing timer
  23. if (timer) {
  24. clearTimeout(timer)
  25. timer = null
  26. }
  27. // Only start timer if delay is configured and valid
  28. if (isValidDelay) {
  29. lastIdleTime = Date.now()
  30. timer = setTimeout(() => {
  31. // Check if we've been continuously idle for the full duration
  32. const idleDuration = Date.now() - lastIdleTime
  33. if (isIdle() && idleDuration >= delayMs) {
  34. logForDebugging(`Exiting after ${delayMs}ms of idle time`)
  35. gracefulShutdownSync()
  36. }
  37. }, delayMs)
  38. }
  39. },
  40. stop() {
  41. if (timer) {
  42. clearTimeout(timer)
  43. timer = null
  44. }
  45. },
  46. }
  47. }