import{existsSync as S,mkdirSync as g,readFileSync as h,readdirSync as x,statSync as N,writeFileSync as w}from"node:fs";import{join as m}from"node:path";function v(t){let e=Number(t);if(!Number.isFinite(e)||e<=0)return null;try{return process.kill(e,0),!0}catch(n){let r=n&&typeof n=="object"?n.code:"";return r==="ESRCH"?!1:r==="EPERM"?!0:null}}function F(t,e={}){if(!t||!S(t))return{patched:0};let n=e.studioNoPidMaxAgeMs!=null&&Number.isFinite(e.studioNoPidMaxAgeMs)?Math.max(0,e.studioNoPidMaxAgeMs):120*1e3,r=Date.now(),u=0,o;try{o=x(t)}catch{return{patched:0}}for(let s of o){let c=m(t,s),a;try{a=N(c)}catch{continue}if(!a.isDirectory())continue;let i=p(c);if(!i||i.status!=="running")continue;let l=Number(i.updatedAt)||0,y=v(i.pid),f=!1,d="";y===!1?(f=!0,d="process-exited"):y===null&&i.runSource==="studio"&&n>0&&l>0&&r-l>n&&(f=!0,d="studio-stale-no-pid"),f&&(D(c,{status:"interrupted",activeNode:null,activeStageIndex:null,exitReason:d}),u+=1)}return{patched:u}}var E="zibby-run-state.json";function M(t){return m(t,E)}function p(t){if(!t||typeof t!="string")return null;let e=M(t);if(!S(e))return null;try{let n=h(e,"utf8"),r=JSON.parse(n);return r&&typeof r=="object"?r:null}catch{return null}}function D(t,e){if(!t||typeof t!="string")return;try{g(t,{recursive:!0})}catch{return}let r={...p(t)||{v:1},...e,v:1,updatedAt:Date.now()};try{w(M(t),`${JSON.stringify(r)}
`,"utf8")}catch(u){console.warn(`[zibby run-state] ${u.message}`)}}function P(t,e={}){if(!t||!S(t))return[];e.reconcile!==!1&&F(t,e.reconcile||{});let n=e.maxStaleMs!=null&&Number.isFinite(e.maxStaleMs)&&e.maxStaleMs>0?e.maxStaleMs:1800*1e3,r=typeof e.now=="number"?e.now:Date.now(),u;try{u=x(t)}catch{return[]}let o=[];for(let s of u){let c=m(t,s),a;try{a=N(c)}catch{continue}if(!a.isDirectory())continue;let i=p(c);if(!i||i.status!=="running")continue;let l=Number(i.updatedAt)||0;n>0&&l>0&&r-l>n||o.push({sessionId:s,sessionPathAbs:c,...i})}return o}export{E as SESSION_RUN_STATE_FILENAME,P as listRunningSessionStatesFromSessionsRoot,D as mergeSessionRunState,v as processPidLooksAlive,p as readSessionRunState,F as reconcileStaleRunningSessionStates,M as sessionRunStateFilePath};
