{"version":3,"file":"process-kill.mjs","names":[],"sources":["../src/process-kill.ts"],"sourcesContent":["import { Clock, Effect } from \"effect\";\nimport { isPidAlive } from \"./process-registry\";\n\nexport interface KillEscalationOptions {\n  terminateMs?: number;\n  signal?: NodeJS.Signals;\n}\n\nconst DEFAULT_TERMINATE_MS = 5000;\nconst POLL_INTERVAL_MS = 250;\n\nconst groupKill = (pid: number, signal: NodeJS.Signals): void => {\n  try {\n    process.kill(-pid, signal);\n  } catch {\n    try {\n      process.kill(pid, signal);\n    } catch {\n      // already gone\n    }\n  }\n};\n\nconst waitGone = (pid: number, timeoutMs: number): Effect.Effect<boolean> =>\n  Effect.gen(function* () {\n    const started = yield* Clock.currentTimeMillis;\n    const deadline = started + timeoutMs;\n    while (isPidAlive(pid)) {\n      const now = yield* Clock.currentTimeMillis;\n      if (now >= deadline) return false;\n      yield* Effect.sleep(POLL_INTERVAL_MS);\n    }\n    return true;\n  });\n\n// killProcessGroupEscalating mirrors the dev session's per-child kill: signal\n// the process group (direct-pid fallback), wait for exit, then SIGKILL the\n// group if the graceful signal was ignored.\nexport const killProcessGroupEscalating = (\n  pid: number,\n  options?: KillEscalationOptions,\n): Effect.Effect<void> =>\n  Effect.gen(function* () {\n    const terminateMs = options?.terminateMs ?? DEFAULT_TERMINATE_MS;\n    const signal = options?.signal ?? \"SIGTERM\";\n    if (pid <= 1 || pid === process.pid) return;\n    if (!isPidAlive(pid)) return;\n    groupKill(pid, signal);\n    if (signal === \"SIGKILL\") return;\n    const gone = yield* waitGone(pid, terminateMs);\n    if (!gone) {\n      groupKill(pid, \"SIGKILL\");\n      yield* waitGone(pid, 1000);\n    }\n  });\n\n// reapGroup hard-kills a process group with direct-pid fallback — the\n// post-escalation cleanup for service trees and their watcher grandchildren.\nexport const reapGroup = (pid: number): void => {\n  if (pid <= 1 || pid === process.pid) return;\n  groupKill(pid, \"SIGKILL\");\n};\n"],"mappings":";;;;AAQA,MAAM,uBAAuB;AAC7B,MAAM,mBAAmB;AAEzB,MAAM,aAAa,KAAa,WAAiC;CAC/D,IAAI;EACF,QAAQ,KAAK,CAAC,KAAK,MAAM;CAC3B,QAAQ;EACN,IAAI;GACF,QAAQ,KAAK,KAAK,MAAM;EAC1B,QAAQ,CAER;CACF;AACF;AAEA,MAAM,YAAY,KAAa,cAC7B,OAAO,IAAI,aAAa;CAEtB,MAAM,YAAW,OADM,MAAM,qBACF;CAC3B,OAAO,WAAW,GAAG,GAAG;EAEtB,KAAI,OADe,MAAM,sBACd,UAAU,OAAO;EAC5B,OAAO,OAAO,MAAM,gBAAgB;CACtC;CACA,OAAO;AACT,CAAC;AAKH,MAAa,8BACX,KACA,YAEA,OAAO,IAAI,aAAa;CACtB,MAAM,cAAc,SAAS,eAAe;CAC5C,MAAM,SAAS,SAAS,UAAU;CAClC,IAAI,OAAO,KAAK,QAAQ,QAAQ,KAAK;CACrC,IAAI,CAAC,WAAW,GAAG,GAAG;CACtB,UAAU,KAAK,MAAM;CACrB,IAAI,WAAW,WAAW;CAE1B,IAAI,EAAC,OADe,SAAS,KAAK,WAAW,IAClC;EACT,UAAU,KAAK,SAAS;EACxB,OAAO,SAAS,KAAK,GAAI;CAC3B;AACF,CAAC;AAIH,MAAa,aAAa,QAAsB;CAC9C,IAAI,OAAO,KAAK,QAAQ,QAAQ,KAAK;CACrC,UAAU,KAAK,SAAS;AAC1B"}