1import { writeFileSync, readFileSync, unlinkSync, existsSync } from 'fs' 4const lockFile = `${ptTmpDir}/refactor.lock` 5const staleLockMs = 60_000 7type LockData = { pid: number, ts: number, op: string } 9const readLock = (): LockData | null => { 10 try { return JSON.parse(readFileSync(lockFile, 'utf8')) } 14const isPidAlive = (pid: number): boolean => { 15 try { process.kill(pid, 0); return true } 16 catch { return false } 19export const acquireRefactorLock = (op: string) => { 20 const lock = readLock() 22 const isStale = Date.now() - lock.ts > staleLockMs 23 const isDeadPid = !isPidAlive(lock.pid) 24 if (!isStale && !isDeadPid) { 25 const agoSec = Math.round((Date.now() - lock.ts) / 1000) 26 throw new Error(`Refactor lock held by pid ${lock.pid} (${lock.op}, ${agoSec}s ago). pt_mv must always be run sequentially never concurrently. Wait, then retry. DO NOT manually bypass pt_mv - imports will be missed.`) 30 writeFileSync(lockFile, JSON.stringify({ pid: process.pid, ts: Date.now(), op })) 33export const releaseRefactorLock = () => { 34 const lock = readLock() 35 if (lock?.pid === process.pid) { 36 try { unlinkSync(lockFile) } catch {}